Enterprise COBOL provides Java-oriented capabilities in addition to the basic OO capabilities available directly in the COBOL language. For example, it allows creation of Java and COBOL classes and invocation of methods on Java and COBOL objects using the INVOKE statement. For basic Java-object capabilities, using the OO capabilities is sufficient for the Java-COBOL interoperability. For additional Java-object capabilities you need the JNI services.
There are several ways to structure the OO application. You can either have COBOL invoking Java or Java invoking COBOL. When starting with COBOL, use the INVOKE statement to invoke a Java method. It is possible to start with COBOL program from both the z/OS UNIX side and the MVS. See the “Communicating with Java methods” topic in the Enterprise COBOL for z/OS programming guide.
The main method
To start with Java, there needs to be a ‘main’ method written. It can be written in Java or as a compiled COBOL class definition that contains a factory method called ‘main’ with the appropriate arguments.
Typically, when using OO COBOL, the easiest way for Java to invoke COBOL is via an OO COBOL ‘wrapper’ class, which calls the procedural COBOL logic and thus “wraps” it.
Since Java resides on the z/OS UNIX side, if you start with Java, all the application components (classes and executable DLL modules) must reside on the HFS. To launch Java, you can use the shell command prompt (running the java command) or with the BPXBATCH utility from JCL or TSO/E.
Working with ‘wrapper’ OO COBOL classes
A COBOL source file that contains a class definition is often the gateway between Java and COBOL
Once this COBOL source file is compiled, a Java file is generated on the USS side. This Java file contains the native method declaration based on the JNI rules. If, for example, the class had a method
foo, then the generated Java code will have a declaration of a native method named
Java_classname_foo. The generated Java code (
.java file) needs to be compiled on the USS side by using the
javac compiler to produce the
When using OO COBOL with class definition, there are these naming rules:
- The name of the resulting DLL module needs to match the expected class name. If
ClassNameis the external class name, then the name of the DLL module must be
libClassName.so, as this is the name expected in the generated Java file (as it uses
System.loadLibrarymethod to load the DLL).
- If the class is part of a package and thus there are periods in the external class name, the periods should be changed to underscores in the DLL module name (based on JNI naming rules).
Accessing JNI services
In COBOL, the JNI API is defined in the JNI copybook called
JNI.cpy. The JNI copybook contains the definition of JNINativeInterface, the COBOL group structure that maps the JNI environment structure, which contains an array of function pointers for the JNI callable services. To facilitate access to JNI services, the
JNI.cpy file needs be defined in the COBOL program under the LINKAGE SECTION. For example, if the file is named JNI:
Before you reference the contents of the JNI environment structure, you must code the following statements to establish its addressability:
Set address of JNIEnv to JNIEnvPtr
Set address of JNINativeInterface to JNIEnv
The code sets the address of JNIEnv, a pointer data item that JNI.cpy provides, and JNIEnvPtr, the COBOL special register that contains the environment pointer. The JNIEnvPtr is implicitly defined as USAGE POINTER and should not be used as a receiving data item. Use this special register JNIEnvPtr to reference the JNI environment pointer to obtain the address for the JNI environment structure.
After the pointers are set, the JNI callable services can be accessed with CALL statements that reference the function pointers. The JNIEnvPtr special register is the first argument to the services that require the environment pointer, as shown in the following example:
01 InputArrayObj usage object reference jlongArray.
01 ArrayLen pic S9(9) comp-5.
. . .
Call GetArrayLength using by value JNIEnvPtr InputArrayObj