COBOL - Group home

Towards a new COBOL/Java interoperability for batch and IMS environments

  

About the Author

David Tremaine is a Senior Software Developer at IBM. He has spent the past decade working on the Enterprise COBOL compiler development team, where he has helped lead IBM's COBOL modernization mission, contributing to such new features as conditional compilation, native UTF-8 support, AMODE 64 support, and enhanced COBOL/Java interoperability, among others. He has worked on IBM's z platform since 2008 and before that worked on IBM's Db2 LUW product.

                                                                                                  

Enterprise COBOL is the trusted workhorse that has given your business a competitive edge for decades by executing your business logic with world-class security, performance, and reliability.

But COBOL won't be the only language in your shop forever. In a modern environment, new types of processing will be added, and new languages introduced. One of those languages will almost certainly be Java, which excels at utilizing the latest z hardware advancements, and can increase the cost-effectiveness of your workloads by running Java applications on IBM z Integrated Information Processors (zIIPs).

But what happens when you have a Java application that needs to access business logic that is already implemented in one of your long-standing, reliable COBOL programs?

Converting that COBOL program to Java for this scenario can be a lot of work with little benefit, especially if the task was better suited to COBOL's strengths in the first place. So how do you bring the COBOL and Java worlds together?

COBOL/Java interoperability in the past

You might have explored COBOL/Java interoperability in the past, or heard about someone who has, and come away thinking that it is not for you. After all, in the past there were a number of restrictions and limitations. For example:

-      You either needed to convert your COBOL program to Object-Oriented (OO) COBOL, or handle most of the interoperability yourself using low-level, Java Native Interface (JNI) calls.

-      You needed to compile your COBOL program as a DLL, something unfamiliar in many COBOL environments.

-      Even when using OO COBOL for interoperability, you still might have needed to employ JNI if you wanted to pass something as simple as a Java String object or BigDecimal object to your COBOL program or pass a PIC X string in COBOL to Java.

An OO COBOL program cannot interoperate with an AMODE 64 Java program.

With all these restrictions and complications, who could blame you for looking at alternatives?

Improved COBOL/Java interoperability using the Enterprise COBOL 6.4 non-OO interoperability framework

There is good news for users interested in COBOL/Java interoperability in the form of Enterprise COBOL 6.4, released in 2022. An entirely new COBOL/Java interoperability model is provided that seeks to address many of the limitations of the past while offering an even simpler interface for the future.

In particular, the new interoperability framework has the following benefits:

-      It is not dependent on any aspect of OO COBOL.

-      It requires almost no changes to an existing COBOL program if you want to make that program callable from Java, or you want to have that program call a static Java method.

o   In particular, the program does not need to be refactored as an OO program nor compiled as a DLL.

-      The new framework has been designed to reduce and in many cases eliminate the need for COBOL programmers to use JNI to write COBOL programs that interoperate with Java (though you're free to enhance your program with JNI).

-      It supports AMODE 31 COBOL programs interoperating with AMODE 64 Java programs.

-      It supports a wide range of conversions between COBOL and Java data formats.

o   BigDecimal objects in Java can be passed directly to zoned/packed decimals parameters in COBOL, and vice versa.

o   Java String objects can be passed directly to COBOL PIC X/N/U character data items in COBOL, and vice versa.

o   All Java primitive types have a corresponding COBOL equivalent, and single-dimension arrays of all these types are supported as well.

-      It provides a new utility (cjbuild) that is responsible for automatically building the DLL of "stub" programs that act as the glue code between your COBOL program and Java.

The new non-OO COBOL/Java interoperability framework

The new non-OO COBOL/Java interoperability framework consists of three new features:

  JAVA-CALLABLE directive that makes your COBOL program callable from Java.

  JAVA-SHAREABLE directive allows you to share COBOL working-storage items with Java for read/write access.

    The CALL statement can be used to call static methods in Java.

A high-level overview of each feature is given below.

JAVA-CALLABLE -- making your existing COBOL program callable from Java

To make your COBOL program callable from Java, simply add the JAVA-CALLABLE directive to your program before the procedure division header.

For example:

identification division.
program-id. prog1.
data division.
working-storage section.
linkage section.
01 x pic s9(9) comp-5.
01 y pic x(20).
01 z pic s9(9)v9(2) packed-decimal.
>>java-callable
procedure division using by reference x y z.
:

When this program is compiled, special artifact files called "stub" files are produced (the location is indicated by the new JAVAIOP option). These files will be consumed by the new cjbuild utility to automatically build a DLL that will be loaded into the Java application at runtime. This program will then be considered a COBOL native method that is part of a Java package with default name enterprise.COBOL. This program can be invoked from Java as a native method as demonstrated in the following Java program:

import enterprise.COBOL.*;
import java.math.BigDecimal;

public class TestApp
{
  public static void main(String[] args)
  {
    int x = 12;
    String y = "Hello, world!";

    BigDecimal bd = new BigDecimal(12.34);

    // Call COBOL native method PROG1
    enterprise.COBOL.progs.PROG1(x, y, z);
    :
  }
}


For more details, see the following:

New blog article: An in-depth look at calling COBOL from Java using the new non-OO COBOL/Java interoperability framework (includes JCL)
Making an existing COBOL program callable from Java
Compiling, linking and running non-OO COBOL applications that interoperate with Java
Example JCL for building/running a non-OO COBOL program that interoperates with Java


JAVA-SHAREABLE

If you have a COBOL program that loads important data into WORKING-STORAGE memory that needs to be accessed from other COBOL programs in your application, that memory can now also be accessed (for read or write) directly from Java without having to continually call back and forth between Java and COBOL, which can be expensive.

Consider the following COBOL program:

identification division.
program-id. prog1.
data division.
working-storage section.
>>java-shareable on
01 g1.
   02 s1 pic x(10).
02  g2.
03 g2-z1 pic s9(9).
03 g2-bin pic 9(18) binary.
   02 s2 pic x(10).
>>java-shareable off
>>java-callable
procedure division.
        :

Similar to JAVA-CALLABLE, when this program is compiled, artifact files will be produced that will be consumed by the cjbuild utility to build a DLL for the application that is loaded into the Java application at runtime.

The data items in g1 can be accessed from Java as demonstrated in the following example:

import enterprise.COBOL.*;
import java.math.BigDecimal;

public class TestApp
{
  public static void main(String[] args)
  {
    :
    // Call PROG1 to make sure the working-storage is initialized
    enterprise.COBOL.progs.PROG1();

    // Now access PROG1 working-storage items for read/write access
    String s1 = enterprise.COBOL.strg.PROG1.G1.S1.get();

    BigDecimal g2_z1 = enterprise.COBOL.strg.PROG1.G1.G2.G2_Z1.get();
    enterprise.COBOL.strg.PROG1.G1.G2.G2_BIN.put(42);
    enterprise.COBOL.strg.PROG1.G1.S2.put(“Hello”);
    :
  }
}

For more details, see the following:

Accessing COBOL WORKING-STORAGE data items from Java
Compiling, linking and running non-OO COBOL applications that interoperate with Java
Example JCL for building/running a non-OO COBOL program that interoperates with Java

Using the CALL statement to make calls to static Java methods

Calling a static Java method from a COBOL program can now be done using the standard COBOL CALL statement. All that is needed is to make the call target a literal of the form

'Java.<fully-qualified-class-name>.<static-method-name>'

where the fully-qualified class name is the class name qualified by the package in which the class exists (if any).  In this scenario, outgoing CALL arguments are converted from COBOL data formats to the appropriate Java format, like how incoming Java arguments are converted to COBOL data formats for Java-callable programs.

The following program demonstrates the use of the CALL statement to call a static Java method "doWork" that is in class TestApp. Note that the fully-qualified name of the class must be used in the call literal. In this case, the fully-qualified name is com.acme.TestApp.

cbl pgmname(longmixed)
identification division.
program-id. 'prog1'.
data division.
working-storage section.
01 x pic s9(9) comp-5.
01 y pic x(20).
01 z pic s9(9)v9(2) packed-decimal.
procedure division.
MainProgram.
    call 'Java.com.acme.TestApp.doWork' using x y z
    goback.
end program 'prog1'.


The static Java method might be defined as follows:

package com.acme;

import enterprise.COBOL.*;
import java.math.BigDecimal;

public class TestApp
{
  public static void doWork(int x, String y, BigDecimal z)
  {
    // method code
  }
}

After compiling, this program produces artifact files that are consumed by the cjbuild utility to build a DLL for the application.

For more details, see the following:

New blog article: An in-depth look at calling static Java methods from COBOL using the new non-OO COBOL/Java interoperability framework (includes JCL)
Calling static Java methods from COBOL
Compiling, linking and running non-OO COBOL applications that interoperate with Java
Example JCL for building/running a non-OO COBOL program that interoperates with Java

Support for interoperability between AMODE 31 COBOL programs and AMODE 64 Java applications

Support for compiling and running AMODE 64 COBOL programs was introduced recently in Enterprise COBOL 6.3, which means the majority of today’s COBOL programs are running in AMODE 31.  The new, non-OO COBOL/Java interoperability framework acknowledges this reality and supports interoperability between AMODE 31 COBOL programs and AMODE 64 Java applications.  There are only two things you need to do to make this work:

  1. Compile the COBOL programs that are interoperating with Java with the JAVAIOP(…,JAVA64,…) option.
  2. Specify the –mode MIX_31_64 option when running the cjbuild utility.

Looking ahead

The new non-OO COBOL/Java interoperability feature is a new technology that we're constantly improving. If you want to use this feature, make sure that you pick up the latest fixes and enhancements by applying the latest Enterprise COBOL 6.4 PTFs to your development and runtime environments.

Make sure that you also keep an eye out for future blog posts, digging deeper into the three aspects of the new framework.

Further information

Further information about how to develop and build applications using the non-OO COBOL/Java interoperability feature are listed below: