Obtaining the JNI environment pointer

If you need to call any JNI functions, use the /COPY file JNI from QSYSINC/QRPGLESRC. Most of the JNI functions are called through a procedure pointer. The procedure pointers are part of a data structure that it itself based on a pointer called the "JNI environment pointer". This pointer is called JNIEnv_P in the JNI /COPY file. To obtain this pointer, call the JNI wrapper procedure getJniEnv.

EVAL   JNIEnv_P = getJniEnv();

Figure 92 contains sample source code for getJniEnv.

Figure 92. Source Code for getJniEnv

 *----------------------------------------------------------------
 * getJniEnv - get the JNI environment pointer                    
 * Note: This procedure will cause the JVM to be created if       
 *       it was not already created.                              
 *----------------------------------------------------------------
P getJniEnv       b                   export                      
D getJniEnv       pi              *                               
                                                                  
D attachArgs      ds                  likeds(JavaVMAttachArgs)    
D env             s               *   inz(*null)                  
D jvm             s                   like(JavaVM_p) dim(1)       
D nVms            s                   like(jsize)                 
D rc              s             10i 0                             
D obj             s               o   class(*java                 
D                                         : 'java.lang.Integer')  
D newInteger      pr              o   extproc(*java               
D                                           : 'java.lang.Integer' 
D                                           : *constructor)       
D   value                       10i 0 value                       
 /free                                                            
    monitor;                                                      
       // Get the current JVM
       rc = JNI_GetCreatedJavaVMs(jvm : 1 : nVms);                
       if (rc <> 0);                                              
          // Some error occurred                                  
          return *null;                                           
       endif;  if (nVms = 0);                                             
          // The JVM is not created yet.  Call a Java             
          // method to get the RPG runtime to start the JVM       
          obj = newInteger(5);                                    
                                                                  
          // Try again to get the current JVM          
          rc = JNI_GetCreatedJavaVMs(jvm : 1 : nVms);  
          if (rc <> 0                                  
          or  nVms = 0);                               
             // Some error occurred                    
             return *null;                             
          endif;                                       
       endif;                                          
       // Attach to the JVM                            
       JavaVM_P = jvm(1);                              
       attachArgs = *allx'00';                         
       attachArgs.version = JNI_VERSION_1_2;           
       rc = AttachCurrentThread (jvm(1) : env          
                               : %addr(attachArgs));   
       if (rc <> 0);                                   
          return *null;                         
       endif;                                          
                                                       
       // Free the object if we created it above while 
       // getting the RPG runtime to start the JVM     
       if obj <> *null;                                
          freeLocalRef (env : obj);                    
       endif; 
    on-error;                                          
       return *null;                                   
    endmon;                                            
    return env;                                        
 /end-free                                             
P getJniEnv       e
Figure 93. Copy-file JAVAUTIL
 *----------------------------------------------------------------
 * Copy file JAVAUTIL
 *----------------------------------------------------------------
 /if defined(JAVAUTIL_COPIED)
 /eof
 /endif
 /define JAVAUTIL_COPIED
D JNI_GROUP_ADDED...     
D                 c                   0     
D JNI_GROUP_NOT_ADDED...     
D                 c                   -1     
D JNI_GROUP_ENDED...     
D                 c                   0       
D beginObjGroup   pr            10i 0 extproc('beginObjGroup')
D   env                           *   const     
D   capacityParm                10i 0 value options(*nopass)     
D endObjGroup     pr            10i 0 extproc('endObjGroup')
D   env                           *   const     
D   refObjectP                    o   class(*java:'java.lang.Object')     
D                                     const     
D                                     options(*nopass)     
D freeLocalRef...
D                 pr                  extproc('freeLocalRef')
D   env                           *   value
D   localRef                      o   CLASS(*JAVA
D                                         : 'java.lang.Object')
D                                     value
D getNewGlobalRef...
D                 pr              o   class(*JAVA
D                                         : 'java.lang.Object')
D                                     extproc('getnewGlobalRef')
D   env                           *   value
D   localRef                      o   class(*JAVA
D                                         : 'java.lang.Object')
D                                     value
D freeGlobalRef...
D                 pr                  extproc('freeGlobalRef')
D   env                           *   value
D   globalRef                     O   class(*JAVA
D                                         : 'java.lang.Object')
D                                     value
D getJniEnv       pr              *   extproc('getJniEnv')
Figure 94. Using the wrappers for the JNI functions
Java class


class TestClass{
   String name = "name not set";

   TestClass (byte name[]) {
      this.name = new String(name);
   }

   void setName (byte name[]) {
      this.name = new String(name);
   }

   String getName () {
      return this.name;
   }
}


RPG program


H THREAD(*SERIALIZE)
H BNDDIR('JAVAUTIL')
 // (JAVAUTIL is assumed to the binding directory that lists
 // the service program containing the procedures described
 // below)

 /copy JAVAUTIL
 // (JAVAUTIL is assumed to be the source member containing the
 // prototypes for the procedures described below)


D TestClass       C                   'TestClass'
D StringClass     C                   'java.lang.String'
D newTest         PR              O   EXTPROC(*JAVA : TestClass
D                                           : *CONSTRUCTOR)
D   name                        25A   VARYING CONST

D getName         PR              O   CLASS(*JAVA : StringClass)

D                                     extproc(*JAVA : TestClass
D                                           : 'getName')

D setName         PR                  extproc(*JAVA : TestClass
D                                           : 'setName')
D   newName                     25A   VARYING CONST

D newString       PR              O   EXTPROC(*JAVA : StringClass
D                                           : *CONSTRUCTOR)
D   value                    65535A   VARYING CONST

D nameValue       PR            25A   VARYING
D                                     extproc(*JAVA : StringClass
D                                           : 'getBytes')

D myTestObj       S                   LIKE(newTest)
D myString        S                   LIKE(newString)
D env             S                   LIKE(getJniEnv)
 /free
    
    // Get the JNI environment pointer so that JNI functions
    // can be called.  

    env = getJniEnv();
   

    // Set the beginning marker for an "object group"
    // so that any objects created between now and the
    // "end object group" can be freed all at once.

    beginObjGroup (env);

    // Create a Test object to work with
    // We do not want this object to be freed with the
    // other objects in the object group, so we make it
    // a permanent object

    myTestObj = newTest ('RPG Dept');
    myTestObj = getNewGlobalRef (env : myTestObj);

    // Get the current "name" from the Test object
    // This creates a local reference to the Name object

    myString = getName (myTestObj);
    dsply (nameValue(myString));

    // Change the name

    setName (myTestObj : 'RPG Department');

    // Get the current "name" again.  This will cause
    // access to the previous local reference to the old name
    // to be lost, making it impossible for this RPG
    // program to explicitly free the object.  If the object
    // is never freed by this RPG program, Java could never
    // do garbage-collection on it, even though the old String
    // object is not needed any more.  However, endObjGroup
    // will free the old reference, allowing garbage collection

    myString = getName (myTestObj);
    dsply (nameValue(myString));

    // End the object group.  This will free all local
    // references created since the previous beginObjGroup call.
    // This includes the two references created by the calls
    // to getName.

    endObjGroup (env);

    // Since the original Test object was made global, it can
    // still be used.

    setName (myTestObj : 'RPG Compiler Dept');

    // The original Test object must be freed explicitly
    // Note: An alternative way to handle this situation
    //       would be to use nested object groups, removing
    //       the need to create a global reference
    //         beginObjGroup ------------.
    //         create myTestObj          |
    //         beginObjGroup  ---------. |
    //         ...                     | |
    //         endObjGroup    ---------' |
    //         use myTestObj again       |
    //         endObjGroup   ------------'

    freeGlobalRef (env : myTestObj);

    return;

 /end-free


[ Top of Page | Previous Page | Next Page | Contents | Index ]