%THIS Built-in Function Example

90 views Asked by At

I am a new RPG-Dev for around a year now and also know Java to some extend. I am struggeling with this BIF for a few days now and I am not finding anything useful anywhere. Here is the IBM DOC example, which does not work for me:

%THIS IBM

I was able to call the java class constructor and a class method.

     D* Java String 
     DstringClass      C                   'java.lang.String'
     DJAVA_STRING      S               O   CLASS(*JAVA:stringClass)
     DnewString        PR              O   EXTPROC(*JAVA:stringClass
     D                                            :*CONSTRUCTOR)
     Dvalue                       65535A   VARYING CONST
     DJAVA_toString    PR                  LIKE(Java_STRING)
     D                                     EXTPROC(*JAVA:stringClass
     D                                             :*CONstrucTOR)
     D value                      65535A   VARYING CONST
     DgetBytes         PR                  LIKE(NAME)
     D                                     EXTPROC(*JAVA:stringClass
     D                                             :'getBytes')
     Dvalue                       65535A   VARYING CONST
     D* Java Employee 
     DnewEmp           PR              O   EXTPROC(*JAVA:'Employee':
     D                                             *CONSTRUCTOR)
     D id                            10I 0 VALUE
     D name                            O   CLASS(*JAVA:stringClass)
     D VCUS                          10I 0 VALUE
     D VCU                           10I 0 VALUE
     D
     Demployee         S               O   CLASS(*JAVA:'Employee')
     D
     DvacationDays     PR            10I 0 EXTPROC(*JAVA:'Employee'
     D                                                  :'vacationDays')
     DgetId            PR            10I 0 EXTPROC(*JAVA:'Employee'
     D                                                  :'getId')
     DRTNNR            S             10I 0
     DNAME             S             10A
     D
     C                   EVAL      JAVA_STRING = JAVA_toString('John')
     C                   EVAL      employee = newEmp(123:JAVA_STRING:15:10)
     C                   EVAL      RTNNR = vacationDays(employee)
     C                   SETON                                        LR
     C
     PvacationDays     B                   EXPORT
     DvacationDays     PI            10I 0
     DidNummer         S             10I 0
     C
     C                   EVAL        idNummer = getId(%THIS)
     C                   RETURN      idNummer
     PvacationDays     E           

The Java Class:

public class Employee{  
    private int id;
    private String name;
    private int vacationUnspent;
    private int vacationUsed;
    
// Constructor
  
// Getter + Setter

// Methods
    public int vacationDays(Employee employee){
        final int vacation;
        vacation = this.vacationUnspent - this.vacationUsed;    
        return vacation;
    }
}    

I am able to compile both and run it until to the Point of RTNNR = vacationDays(employee) where i get the Error Message: RNX0301 "java.lang.NoSuchMethodError: Employee.vacationDays()I"

so I did "javap -s Employee" in the Qshell: public int vacationDays(Employee);
descriptor: (LEmployee;)I

So i clearly dont want to go into the Java class but instead use the Method in my RPG program to use the %THIS BIF. And i can not compile the RPG program when vacationDays() is empty. It wants an Object in it. It is kinda annoying that the IBM example doesnt show the call of vacationDays so I have to assume a lot.

Thank you in advance.

I tried to recreate the IBM example and also some more normal examples on how to call Java Methods in RPG. The later worked. I was able to get into the Java class and its methods and get results back, which I expected. I was unable to find any other Examples of %THIS on the web and the other developers of my company never have used it.

2

There are 2 answers

1
Barbara Morris On BEST ANSWER

In your Java class, you have to define the method as a native method.

public native int vacationDays(Employee employee);

https://www.ibm.com/docs/en/i/7.2?topic=java-rpg-native-methods

The RPG procedure has to be in a service program, and your Java class has to load the service program so your native method can be called by Java.

1
Valerij Dobler On

If you can modify the Java source code

You can simplify your vacationDays to the following

public int vacationDays(){
    return this.vacationUnspent - this.vacationUsed;
}

Especially the part where it does not need to accept an employee, because it can just access the data from the instance it belongs to.

Where you can't modify the Java source code

Just pass null to it, because as mentioned above it is unused so it does not matter what the argument is set to.

Tangent

How about vacationAvailable instead of using vacationUnspent? It gets rid of the negation.