When an application starts with native code and requires to call Java features via JNI APIs, it first needs to load a JVM using the JNI API, unless it is using OO COBOL. With OO COBOL invoking Java, COBOL will start the JVM for you.

When an application starts with Java, it calls the native language via native methods.

The native methods called from Java are declared in the Java code and implemented in the native language. The name of the native method follows the JNI naming rules. In the simple case, the method would be in the format of Java_classname_methodname. See the JNI Specification for more detailed information regarding native method names and arguments.

As part of the JNI calling convention, the native method has two hidden arguments that are not seen on the Java declaration. Those arguments are predefined by the JNI:JNIEnv interface pointer and jobject. In COBOL, the JNIEnv interface pointer is the JNIEnvPtr and it is used to dereference the JNI service. The jobject is a pointer to the class in case the class is static, or to the instance of the class if it is not static.

You can use the javah tool to generate .h header files that can be inspected for the signature of the native method generated. These header files are used by C and C++ compilers, not by the COBOL compiler, but you might find them useful for checking the naming of native methods. Although generating the .h files is optional, it has great value in providing the expected signature.

Once the native code is compiled and linked, the native methods are accessed via an executable DLL module that is loaded on the Java side. There are two ways for Java to load the executable DLL module:

  • Using System.loadLibrary(“Name”)

    In this case the DLL name needs to be in the format of libName.so.

  • Using System.load("<absolutePath>/Name")

    In this case there is no restriction on the name of the library.

For proper loading and binding, the executable DLL needs to reside on the z/OS UNIX side, have the right attributes (executable) and follow naming rules.

Example 1: “Hello world” from COBOL

This Java sample code demonstrates how to invoke a native COBOL method that prints “Hello from COBOL”. The example has no parameters passed to nor no return data from the native method.

  1. Declare the native method in the Java code.
  2. Compile the Java code using javac to generate a .class file.
  3. Generate the native code.

    There are two main parts that need special attention: the program-id and the procedure division’s parameters and return value. The program-id should follow the JNI rules and match the native method name as declared on the Java side. In this case, following the Java_classname_methodname convention, the program-id is Java_HelloTest_printHello. The native method declared has no arguments but the COBOL procedure division declares the two ‘hidden’ arguments required for JNI, even though they are not used in the procedure (as we do not facilitate the JNI services). Note that there is no use of JNI services. Therefore the JNI copybook is not included.

  4. Compile the COBOL code with the required options given in the example. These compilation options are described in the “Compiling and linking for COBOL” section.
  5. Link-edit step to generate the executable DLL module (following naming rules to allow proper loading). The required options are described in the “Compiling and linking for COBOL” section.
  6. Run the Java program.

    If the System.loadLibrary(“Name”) method is used, the Java will search a file of the type libName.so in the library path provided via the -Djava.library.path option. If you use the System.load(...) method, the path points to the library file.

The following is a simple COBOL program that prints “Hello from COBOL “.

helloTest.cbl


helloTest.cbl
Process pgmname(longmixed),lib,dll,thread
       IDENTIFICATION DIVISION.
       PROGRAM-ID.    "Java_HelloTest_printHello" is recursive.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       LINKAGE SECTION.
       01 ENV-PTR   USAGE POINTER.
       01 OBJECT-REF  PIC S9(9) BINARY.
       PROCEDURE DIVISION USING BY VALUE ENV-PTR
                                     OBJECT-REF.
              Display " >> Hello from COBOL ".
              GOBACK.


This COBOL program is compiled and linked as follows, where a typical installation path for COBOL is /usr/lpp/cobol and a typical installation path for Java is /usr/lpp/java. Replace with your own paths for your environment.


/usr/lpp/cobol/bin/cob2 -c -qdll,thread helloTest.cbl
/usr/lpp/cobol/bin/cob2 -bdll -o libHello.so helloTest.o /usr/lpp/java/IBM/J7.1/bin/j9vm/libjvm.x /usr/lpp/cobol/lib/igzcjava.x helloTest.cbl

The following HelloTest.java program is compiled and run using the following USS commands:


/usr/lpp/java/IBM/J7.1/bin/javac HelloTest.java
/usr/lpp/java/IBM/J7.1/bin/java -Djava.library.path=. HelloTest

HelloTest.java

public class HelloTest
{
   public native void printHello();
   public static void main(String argv[]) throws Exception
  {
    System.loadLibrary("Hello");
    HelloTest newHelloTest = new HelloTest();
    newHelloTest.printHello();
      return;
   }
}

Join The Discussion

Your email address will not be published. Required fields are marked *