Skip to content

COBOL/Java Interoperability

With COBOL-IT, calling COBOL from Java requires an intermediate C program, which in the sample below, we refer to as a JNI glue program. You can use JNI to call COBOL IT DLL's in Windows or shared libraries that contain COBOL code routines in UNIX.

In effect, the way from Java to COBOL-IT is through C, as suggested in this diagram:

Java < > “C” < > COBOL

The following example includes a Java program, a JNI glue program (written in C) and a COBOL program, which receives the data passed from the original Java program, and processes it. This is only a working sample. Please refer to the Java JNI documentation for full detail about calling C code from Java.

Note

Take care to match memory models (32-bit or 64-bit) between your Java and COBOL installations. Mixing 32-bit (Java or Cobol) with 64-bit (Java or Cobol) is not allowed.

Prerequisites

The COBOL/Java interoperability samples require that the Java Development Kit (JDK) be installed on the host system. Visit the Oracle website for information on how to download and install the Java Development Kit.

This sample also requires that a C compiler, and COBOL-IT COBOL compiler be installed on the host system. Linux/Unix systems will typically have a C compiler installed. For Windows systems that do not have a C compiler installed, visit the Microsoft website for information on how to download and install a Visual Studio C++ compiler.

Calling COBOL from Java

Many businesses looking at Application Modernization will naturally look to Java for building graphical front ends, and enabling them to connect internet portals, mobile devices and application servers to their core application technology. With COBOL/Java Interoperability, solution engineers are able to propose solutions that include websites, connecting to application servers such as WebLogic, WebSphere, or JBoss, connecting in turn to legacy COBOL applications, which connect in turn to industry-leading database engines such as Oracle, DB2, Microsoft SQL Server, MySQL, and PostgreSQL.

While it is clear that Java is a powerful enabler in these cases, it is equally clear that it is not designed to serve as a replacement for the legacy COBOL applications. As a result, we see COBOL/Java Interoperability developing as an important topic in the area of Application Modernization.

In a Java/COBOL solution, the COBOL legacy applications continue to run the business- and are deployed as programs that are CALL’ed from Java through a C calling interface known as the JNI.

The Java Program

This is a Java program that will take an argument as input, and pass that information to the JNI glue program, written in C. In our example, the JNI glue program is progjavainterface.so (Linux/Unix), or progjavainterface.dll (Windows).

JavaProg.java

       public class JavaProg
      {
              public native String prog(int i, String s);
              static {
                     System.loadLibrary("progjavainterface");
              }
              public static void main(String[] args) {

                     String s = "From Java";
                     JavaProg cobol= new JavaProg();
                     for (int i=0; i<args.length; i++) {
                            s = cobol.prog(i, args[i]);
                            System.out.println("JAVA: Returned : " + s);
                     }
              }
      }

Verify that Java Development Kit (JDK) is installed on your machine, and that the bin directory of the JDK installation is in your PATH. Then, you can compile the java program as follows:

>javac JavaProg.java

The JNI Glue Program

progjavainterface.c

To be able to call this COBOL program from our Java code we need a JNI glue program written in C.

       #include "jni.h"
       #include "libcob.h"

       void
       cob_string_to_C(COB_RTD, char *s, int size){
              int i;
              for ( i = (int) size - 1; i >= 0; i-- ) {
                     if ( s[i] != CHAR_SP && s[i] != 0 ) {
                            break;
                     }
              }
              s[i + 1] = '\0';
      }

       JNIEXPORT jstring JNICALL Java_JavaProg_prog(JNIEnv *env, jobject
        obj, jint javaint, jstring javaString)
      {
              jstring jstr;

       const int nativeint = javaint;
       const char *nativeString = (*env)->GetStringUTFChars(env, 
       javaString, 0);
       /*Get COBOL-IT runtime data*/
       cit_runtime_t * rtd;
       /*The COBOL program interface */
       int (*cobolprog)(int *, char*, char*);
       /* Buffer to avoid memory protection in cobol this must be the 
       same size +1 as string declared in LINKAGE*/
       char cobolstring[32];
       char resstring[41];
       strncpy (cobolstring, nativeString, 31);
       memset (resstring, ' ' , 40);
       /*call the cobol program*/
       rtd = cob_get_rtd();
       cob_init(rtd, 0, NULL);
       cobolprog = cob_resolve(rtd, "prog");
       if(cobolprog) {
              cobolprog(&nativeint, cobolstring, resstring);
       }
       cob_string_to_C(rtd, resstring, 41);

       jstr = (*env)->NewStringUTF(env, resstring);
       (*env)->ReleaseStringUTFChars(env, javaString, nativeString);
              return jstr;
      }

Compile the JNI glue program written in C and create a shared object:

In Linux/Unix:

cobc -b progjavainterface.c -o libprogjavainterface.so

Be careful to name the output lib<yourname> ; this is required by the Unix loader.

In Windows:

cobc -I "C:\Program Files\Java\jdk1.6.0_22\include" -I "C:\Program Files\Java\jdk1.6.0_22\include\win32" -b progjavainterface.c

The COBOL-IT program

In our sample, the JNI glue program, written in C, has been hard-coded to call the COBOL program prog, which will load the shared object prog.so (Linux/Unix) or prog.dll (Windows).

prog.cbl

       IDENTIFICATION       DIVISION.
       PROGRAM-ID.          prog.
       ENVIRONMENT          DIVISION.
       DATA                 DIVISION.
       LINKAGE SECTION.
       01 VALINT     USAGE UNSIGNED-INT.
       01 VALSTR PIC X(30) USAGE DISPLAY.
       01 RETS.
              03 RETSTR1 PIC 9(9) USAGE DISPLAY.
              03 RETSTR2 PIC X(30) USAGE DISPLAY.
              03 FILLER PIC X(1) VALUE ZERO.
      *
       PROCEDURE DIVISION USING VALINT VALSTR RETS.
              DISPLAY "COBOL: " VALINT " IS '" VALSTR "'".
              MOVE VALINT to RETSTR1.
              MOVE VALSTR to RETSTR2.
              GOBACK.

Compile prog.cbl

cobc -m -fthread-safe prog.c bl

Take care to use the -fthread-safe compiler flag with all of your COBOL programs, even those not directly called by Java.

Note that we use USAGE UNSIGNED-INT for the numeric input value in the LINKAGE section. This type matches with the native C int type.

Please refer to the COBOL-IT Reference manual for more detail about USAGE memory mapping.

Run the java program

In Linux/Unix:

       run.sh
       export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
       java JavaProg "12345" "Calling COBOL from Java" "c"

In Windows:
java -classpath . JavaProg "12345" "Calling COBOL from Java" "c"

In summary

You can combine the compile and run commands above into scripts (Linux/Unix) or batch files (Windows) as follows:

Linux/Unix:

buildnrun.sh

       javac JavaProg.java
       cobc -b progjavainterface.c -o libprogjavainterface.so
       cobc -m -fthread-safe prog.cbl
       export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
       java JavaProg "12345" "Calling COBOL from Java" "c"

Windows 32:

build.bat

       set JAVA_HOME=c:\program files\java\jdk1.6.0_22\bin
       set PATH=%JAVA_HOME%;%PATH%
       javac JavaProg.java
       cobc -I "C:\Program Files (x86)\Java\jdk1.6.0_20\include" -I 
       "C:\Program Files (x86)\Java\jdk1.6.0_20\include\win32" -b 
       progjavainterface.c
       cobc -m -fthread-safe prog.cob
       java -classpath . JavaProg "12345" "Calling COBOL from Java" "c"

Windows 64:

buildx64.bat

       set JAVA_HOME=c:\program files\java\jdk1.6.0_22\bin
       set PATH=%JAVA_HOME%;%PATH%
       javac JavaProg.java
       cobc -I "C:\Program Files\Java\jdk1.6.0_22\include" -I 
       "C:\Program Files\Java\jdk1.6.0_22\include\win32" -b 
       progjavainterface.c
       cobc -m -fthread-safe prog.cob
       java -classpath . JavaProg "12345" "Calling COBOL from Java" "c"

Running JavaProg returns the following output:

       COBOL: 0000000000    IS '12345                          '
       JAVA: Returned : 00000000012345
       COBOL: 0000000001 IS 'Calling COBOL from Java           '
       JAVA: Returned : 000000001Calling COBOL from Java
       COBOL: 0000000002 IS 'c                                 '
       JAVA: Returned : 000000002c

Calling Java from COBOL

With COBOL-IT, calling Java from COBOL requires an intermediate C program, which in the sample below, we refer to as a JNI glue program. In effect, the way from COBOL-IT to Java is through C, as suggested in this diagram:

COBOL-IT < > “C” < > Java

The following example includes a COBOL-IT program, a JNI glue program (written in C) and a Java program, which receives the data passed from the original Java program, and processes it. This is only a working sample. Please refer to the COBOL IT documentation for full detail about Calling C from COBOL IT.

Note

Take care to match memory models (32-bit or 64-bit) between your Java and COBOL installations. Mixing 32-bit (Java or Cobol) with 64-bit (Java or Cobol) is not allowed.

The COBOL-IT Program

prog.cbl

       IDENTIFICATION DIVISION.
       PROGRAM-ID. prog.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 STRDATA.
              02 STR PIC X(20) VALUE "COBOL STRING".
              02 FILLER PIC X VALUE LOW-VALUE.

       PROCEDURE     DIVISION.
              CALL "CALLJAVA" using STRDATA.
              STOP RUN.

Compile prog.cbl

cobc -x prog.cbl

The JNI Glue Program

CALLJAVA.c

       #include <stdio.h>
       #include <jni.h>
       #include <string.h>
       #include "libcob.h"
       #define PATH_SEPARATOR ':' /* define it to be ';' on windows */
       #define USER_CLASSPATH "." /* where Prog.class is */

       JNIEnv* create_vm(JavaVM ** jvm) {

              JNIEnv *env;
              JavaVMInitArgs vm_args;
              JavaVMOption options;
              int ret;

              options.optionString = "-Djava.class.path=."; //Path to 
              the java source code
              vm_args.version = JNI_VERSION_1_6; //JDK version. 
              This indicates version 1.6
              vm_args.nOptions = 1;
              vm_args.options = &options;
              vm_args.ignoreUnrecognized = 0;

              ret = JNI_CreateJavaVM(jvm, (void**)&env, &vm_args);
              if (ret < 0)
                     printf("\nUnable to Launch JVM\n");
              return env;
      }

       COB_CALL_TARGET int CALLJAVA(char* str)
      {
              JNIEnv *env;
              JavaVM * jvm;
              jclass clsH=NULL;
              jmethodID midCalling = NULL;
              jstring StringArg;

              /* create Jave VM ... This should be done only once */
              env = create_vm(&jvm);
              if (env == NULL)
                     return 1;
              // Find the Java Class
              clsH = (*env)->FindClass(env, "jmodule");

              //Obtaining Method IDs
              if (clsH != NULL) {
                     midCalling    = (*env)->GetStaticMethodID(env, 
                     clsH,"TestCall","(Ljava/lang/String;)V");
              } else {
                     printf("\nUnable to find the requested class\n");
              }

              if (midCalling!=NULL) {
                     StringArg = (*env)->NewStringUTF(env, str);

                     //Calling another static method and passing string 
                     type parameter
                     (*env)->CallStaticVoidMethod(env, 
                     clsH,midCalling,StringArg);
              }

              /* close Java VM*/
              (*jvm)->DestroyJavaVM(jvm);
      }

Compile the JNI glue program written in C and create a shared object

In Linux/Unix:

       cobc -m -I $JAVA_HOME/include -I $JAVA_HOME/include/linux 
       CALLJAVA.c -R $JAVA_HOME/jre/lib/amd64/server -L 
       $JAVA_HOME/jre/lib/amd64/server -ljvm

In Windows:

       SET JAVA_HOME=C:\Program Files (x86)\Java\jdk1.6.0_20
       PATH=%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin\server;%PATH%
       SET LIB=%LIB%;%JAVA_HOME%\lib
       SET
       INCLUDE=%INCLUDE%;%JAVA_HOME%\include;%JAVA_HOME%\include\win32
       cobc -m CALLJAVA.c   -l jvm.lib

The Java Program

       jmodule.java

       public class jmodule
      {
              public static void main(String args[])
              {
                     System.out.println("Hello World!");
                     System.out.println("This is the main function in 
                     jmodule class");
              }
              public static void TestCall(String szArg)
              {
                     System.out.println("Print from Java");
                            System.out.println(szArg);
              }
      }

Verify that Java Development Kit (JDK) is installed on your machine, and that the bin directory of the JDK installation is in your PATH.

Compile the java program

>javac jmodule.java

Run the COBOL Program

In Linux/Unix:

./prog

In Windows:

       SET JAVA_HOME=C:\Program Files\Java\jdk1.6.0_22
       SET LIB=%LIB%;%JAVA_HOME%\lib
       ./prog

In summary

You can combine the compile and run commands above into scripts (Linux/Unix) or batch files (Windows) as follows:

Linux/Unix:

       cobc -x prog.cob
       cobc -m -I $JAVA_HOME/include -I $JAVA_HOME/include/linux 
       CALLJAVA.c -R $JAVA_HOME/jre/lib/amd64/server -L 
       $JAVA_HOME/jre/lib/amd64/server -ljvm
       javac jmodule.java
       ./prog

Windows 32:

       SET JAVA_HOME=C:\Program Files (x86)\Java\jdk1.6.0_22
       SET PATH=%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin\server;%PATH%
       SET LIB=%LIB%;%JAVA_HOME%\lib
       SET
       INCLUDE=%INCLUDE%;%JAVA_HOME%\include;%JAVA_HOME%\include\win32
       cobc -x prog.cob
       cobc -m CALLJAVA.c -l jvm.lib
       javac jmodule.java
       prog

Windows 64:

       SET JAVA_HOME=C:\Program Files\Java\jdk1.6.0_22
       SET PATH=%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin\server;%PATH%
       SET LIB=%LIB%;%JAVA_HOME%\lib
       SET
       INCLUDE=%INCLUDE%;%JAVA_HOME%\include;%JAVA_HOME%\include\win32
       cobc -x prog.cob
       cobc -m CALLJAVA.c -l jvm.lib
       javac jmodule.java
       prog

Running Prog returns the following output:

       Print from Java
       COBOL STRING
Back to top