Example: COBPROD application - building and running

The section describes how to build/run the COBPROD application from z/OS UNIX. A description of how to build and run the application from JCLis provided in the next section, "Sample JCL for building and running the COBPROD application". The COBPROD application is a contrived COBOL/Java™ interoperable application that is used for demonstration purposes throughout this section. A version of the COBPROD application is provided as a set of files available in the demo/cobol_java_interop_sample subdirectory of the COBOL install directory in the z/OS UNIX file system. Versions of the files also exist in the compiler's SIGYSAMP data set (see the members whose names start with the prefix igycjdn).

About this task

The COBPROD application consists of two COBOL programs, COBPROD and "addlist", and a Java class called CobProd. The application starts on the Java side, calls the COBPROD COBOL program to initialize a table of product information in WORKING-STORAGE, then accesses that information directly from Java upon return. The Java side then passes a list of prices to the "addlist" COBOL program which sums the list and returns to Java where the sum is displayed to the terminal.
Note: Passing large arrays of java.math.BigDecimal objects or java.lang.String objects to COBOL from Java can be expensive due to data type conversions and thus may not be appropriate when performance is critical. Passing a small array of java.math.BigDecimal objects is demonstrated here to show the convenience of such an operation when it is used prudently or when performance is less of a factor.
Two interoperability features are demonstrated in the application:
  • Java calling COBOL
  • Java accessing COBOL WORKING-STORAGE directly
The demo contains the following user source files:
cobprod.cbl
COBOL program that initializes WORKING-STORAGE with a table of product information that can be accessed from Java.
addlist.cbl
COBOL program that adds a list of prices together and dumps the resulting value to the terminal by making a call back to Java.
CobProd.java
Defines the Cobprod Java class that is the Java-based demo driver.
The following script files for building and running the COBPROD application are also provided:
build.sh
A shell script for building the COBPROD application. Instructions for building using the script are contained in the script itself.
Invoke build.sh at the z/OS UNIX command line. A mixed AMODE application (AMODE 31 COBOL and AMODE 64 Java) will be built.
makefile
As an alternative to the build.sh script, a makefile is provided to demonstrate how a makefile could be used to build an interoperable application for those that prefer makefiles. For the makefile build, a mixed AMODE application (AMODE 31 COBOL, AMODE 64 Java) is always built.
Initiate a makefile-based build by issuing the following command at the z/OS UNIX command line in a directory that contains the makefile:
make
run.sh
A shell script for running the interoperable application. Works for applications built using either build.sh or makefile. See the script for details about how to run it.
Other miscellaneous files are provided:
README
Contains detailed information about building and running the COBPROD application.
cobprod.cbl

      *********************************************************************
      *                                                                   *
      *  IBM Enterprise COBOL for z/OS                                    *
      *               Version 6 Release 4 Modification 0                  *
      *                                                                   *
      *  LICENSED MATERIALS - PROPERTY OF IBM.                            *
      *                                                                   *
      *  5655-EC6 COPYRIGHT IBM CORP. 2022, 2024                          *
      *                                                                   *
      *  US GOVERNMENT USERS RESTRICTED RIGHTS - USE,                     *
      *  DUPLICATION OR DISCLOSURE RESTRICTED BY GSA                      *
      *  ADP SCHEDULE CONTRACT WITH IBM CORP.                             *
      *                                                                   *
      *********************************************************************
      * cobprod initializes a working-storage item with some
      * product information to be shared with Java
       identification division.
       program-id. cobprod.
       data division.
       working-storage section.
      * Product info table, shared with Java
      * NOTE: This is for demonstration purposes only.
      *       Data should NOT be placed in your COBOL program code.
       01 prod-list-size pic s9(9) comp-5 value 5.
       01 prod-info-data.
         03 filler.
            05 filler pic x(20) value 'chair'.
            05 filler pic s9(9)v9(2) value 29.99.
         03 filler.
            05 filler pic x(20) value 'table'.
            05 filler pic s9(9)v9(2) value 45.98.
         03 filler.
            05 filler pic x(20) value 'bed'.
            05 filler pic s9(9)v9(2) value 149.45.
         03 filler.
            05 filler pic x(20) value 'blanket'.
            05 filler pic s9(9)v9(2) value 19.99.
         03 filler.
            05 filler pic x(20) value 'sofa'.
            05 filler pic s9(9)v9(2) value 239.99.
      * Make this table directly accessible to Java
       >>java-shareable on
       01 prod-info redefines prod-info-data.
          03 prod-list occurs 5 times.
            05 prod-name  pic x(20).
            05 prod-price pic s9(9)v9(2).
       >>java-shareable off
       linkage section.
       01 prod-list-size-out pic s9(9) comp-5.
       >>java-callable
       procedure division returning prod-list-size-out.
       MainProgram.
      * Populate table
           move prod-list-size to prod-list-size-out
           goback.
       end program cobprod.
addlist.cbl

        cbl pgmname(longmixed)
      *********************************************************************
      *                                                                   *
      *  IBM Enterprise COBOL for z/OS                                    *
      *               Version 6 Release 4 Modification 0                  *
      *                                                                   *
      *  LICENSED MATERIALS - PROPERTY OF IBM.                            *
      *                                                                   *
      *  5655-EC6 COPYRIGHT IBM CORP. 2022, 2024                          *
      *                                                                   *
      *  US GOVERNMENT USERS RESTRICTED RIGHTS - USE,                     *
      *  DUPLICATION OR DISCLOSURE RESTRICTED BY GSA                      *
      *  ADP SCHEDULE CONTRACT WITH IBM CORP.                             *
      *                                                                   *
      *********************************************************************
      * Receives a list of decimal items and calculates
      * and returns the sum.  Maxium list size 3
       identification division.
       program-id. 'addlist'.
       data division.
       working-storage section.
       local-storage section.
       01 idx pic s9(9) comp-5.
       linkage section.
       01 pricelist.
         03 price pic s9(9)v9(2) comp-3 occurs 3 times.
       01 listsize pic s9(9) comp-5.
       01 result pic s9(9)v9(2) comp-3.
       >>java-callable
       procedure division using by reference pricelist
                                by value listsize
                          returning result.
       MainProgram.
      * Compute sum of list
           display '<<COBOL: addlist: entered>>'

           compute result = 0

           perform varying idx from 1 by 1
                   until idx > 3
             compute result = result + price(idx)
           end-perform

           display '<<COBOL: addlist: exited>>'
           goback.
       end program 'addlist'.
CobProd.java

//*******************************************************************
//                                                                  *
// IBM Enterprise COBOL for z/OS                                    *
//              Version 6 Release 4 Modification 0                  *
//                                                                  *
// LICENSED MATERIALS - PROPERTY OF IBM.                            *
//                                                                  *
// 5655-EC6 COPYRIGHT IBM CORP. 2022, 2024                          *
//                                                                  *
// US GOVERNMENT USERS RESTRICTED RIGHTS - USE,                     *
// DUPLICATION OR DISCLOSURE RESTRICTED BY GSA                      *
// ADP SCHEDULE CONTRACT WITH IBM CORP.                             *
//                                                                  *
//*******************************************************************
import enterprise.COBOL.*;
import java.math.*;

public class CobProd
{
  public static void main(String[] args)
  {
    System.out.println("<<Java: CobProd.main: entered>>");

    System.out.println();
    System.out.println("Java: Access COBOL product info from COBPROD");

    // Call out to COBOL to initialize the product table in COBPROD
    int tableSize = enterprise.COBOL.progs.COBPROD();
    System.out.println("Java: prod table size = " + tableSize);

    // Display the product names and prices in the table
    for (int i = 0; i < tableSize; i++)
    {
      System.out.print("Java: Product name = " +
        enterprise.COBOL.strg.COBPROD.PROD_INFO.PROD_LIST[i].PROD_NAME.get());
      System.out.print(" Price = $");
      System.out.println(enterprise.COBOL.strg.COBPROD.PROD_INFO.PROD_LIST[i].PROD_PRICE.get());
    }
    System.out.println();

    // Calculate the sum of the first 3 prices in the table
    BigDecimal[] prices = new BigDecimal[3];
    assert(tableSize >= 3);
    assert(prices.length >= 3);
    prices[0] = enterprise.COBOL.strg.COBPROD.PROD_INFO.PROD_LIST[0].PROD_PRICE.get();
    prices[1] = enterprise.COBOL.strg.COBPROD.PROD_INFO.PROD_LIST[1].PROD_PRICE.get();
    prices[2] = enterprise.COBOL.strg.COBPROD.PROD_INFO.PROD_LIST[2].PROD_PRICE.get();

    // Call out to COBOL routine addlist to do the actual calculation
    System.out.println("Java: call COBOL addlist to add prices");

    BigDecimal result = enterprise.COBOL.progs.addlist(prices, prices.length);

    System.out.println();
    System.out.println("Java: Price of chair+table+sofa is: $" + result);

    System.out.println();
    System.out.println("<<Java: CobProd.main: exited>>");
  }
}
build.sh

#!/bin/sh
###############################################################################
#
#  IBM Enterprise COBOL for z/OS                    
#               Version 6 Release 4 Modification 0
#
#  LICENSED MATERIALS - PROPERTY OF IBM.
#
#  5655-EC6 COPYRIGHT IBM CORP. 2022, 2024
#
#  US GOVERNMENT USERS RESTRICTED RIGHTS - USE,
#  DUPLICATION OR DISCLOSURE RESTRICTED BY GSA
#  ADP SCHEDULE CONTRACT WITH IBM CORP.
#
###############################################################################
##############################################################################
# Build script for the COBOL/Java interoperability demo COBPROD
##############################################################################
#
# Invocation:
# -----------
#
# build.sh         - build mixed amode interoperable application
#
# NOTE:
# -----
#
# 1) Make sure cjbuild and cob2 are in your PATH before running this script
#
# 2) Make sure JAVA_HOME is set appropriately
#
# 3) Make sure your STEPLIB includes an Enterprise COBOL V6.4 or later
#    compiler and a runtime that is sufficient to run COBOL programs
#    compiled with the Enterprise COBOL V6.4 or later compiler
#
# 4) You must have an existing data set to receive COBOL program objects
#    and DLLs and it must be called <USER>.COBOL.LOAD, where <USER> is 
#    your high-level qualifier
#
##############################################################################

if [ -z $STEPLIB ]; then
  echo "STEPLIB environment variable must be set"
  exit 1
fi

if [ -z $JAVA_HOME ]; then
  echo "JAVA_HOME environment variable must be set"
  exit 1;
fi

OUT_DIR=./out
CLASSOUT_DIR=./class

# Set the AMODE variables
JAVAMODE="JAVA64"
CJMODE="MIX_31_64"

# Make the output directory
rm -fr ${OUT_DIR} ${CLASSOUT_DIR}
mkdir ${OUT_DIR} ${CLASSOUT_DIR}

# STEP 1: Compile user COBOL programs, specifying JAVAIOP option
cob2 -c cobprod.cbl "-qjavaiop(OUTPATH('${OUT_DIR}'),${JAVAMODE})"
cob2 -c addlist.cbl "-qjavaiop(OUTPATH('${OUT_DIR}'),${JAVAMODE})"

# STEP 2: Build application DLL and .jar file using cjbuild
cjbuild -v \
  --jar libapp1.jar \
  --javaclassdir ${CLASSOUT_DIR} \
  --mode ${CJMODE} \
  --pkgname enterprise.COBOL \
  --coboldir ${OUT_DIR} \
  --dlloutdir "//COBOL.LOAD" \
  app1

# STEP 3: Link user programs
cob2 cobprod.o -o "//COBOL.LOAD(cobprod)" libapp1.x
cob2 addlist.o -o "//COBOL.LOAD(addlist)" libapp1.x

# STEP 4: Build Java parts of the application
export CLASSPATH=${CLASSOUT_DIR}:$CLASSPATH

${JAVA_HOME}/bin/javac -d ${CLASSOUT_DIR} CobProd.java
makefile
###############################################################################
# Makefile for the COBOL/Java interoperability demo COBPROD (Mixed 31/64 mode)
###############################################################################
#
# NOTE:
# -----
#
# 1) Make sure cjbuild and cob2 are in your PATH before using this makefile
#
# 2) Make sure your STEPLIB is set to include an Enterprise V6.4 or later
#    compiler and runtime
#
# 3) Make sure JAVA_HOME points to your 64-bit Java JDK
#
#    e.g., JAVA_HOME=/usr/lpp/java/IBM/J8.0_64  or
#          JAVA_HOME=/usr/lpp/java/IBM/J11.0_64
#
# 4) You must have an existing data set to receive COBOL program objects
#    and DLLs and it must be called <USER>.COBOL.LOAD, where <USER> is 
#    your high-level qualifier
#
##############################################################################

MYSTEPLIB=$(USER).COBOL.LOAD:$(STEPLIB)
OUT_DIR=./out
CLASSOUT_DIR=./class
MYCLASSPATH=$(CLASSOUT_DIR):$(CLASSPATH)

all: setup libapp1 cobprod addlist CobProd.class

setup:
	@rm -fr out class
	@mkdir -m 0755 out class

libapp1: cobprod.o addlist.o methods
	STEPLIB=$(MYSTEPLIB) cjbuild -v  -j $(CLASSOUT_DIR) -p enterprise.COBOL -m MIX_31_64 -c $(OUT_DIR) -d "//COBOL.LOAD" methods app1

cobprod: cobprod.o
	STEPLIB=$(MYSTEPLIB) cob2 cobprod.o -o "//COBOL.LOAD(cobprod)" libapp1.x 

addlist: addlist.o libapp1
	STEPLIB=$(MYSTEPLIB) cob2 addlist.o -o "//COBOL.LOAD(addlist)" libapp1.x

cobprod.o: cobprod.cbl
	STEPLIB=$(MYSTEPLIB) cob2 -c cobprod.cbl "-qjavaiop(OUTPATH('$(OUT_DIR)'),JAVA64)"
  
addlist.o: addlist.cbl
	STEPLIB=$(MYSTEPLIB) cob2 -c addlist.cbl "-qjavaiop(OUTPATH('$(OUT_DIR)'),JAVA64)"

CobProd.class: CobProd.java
	CLASSPATH=$(MYCLASSPATH) $(JAVA_HOME)/bin/javac -d $(CLASSOUT_DIR) CobProd.java

clean:
	rm -fr *_java_native* *WS.java *WS_base.java *.o *.class *.sig CEEDUMP.* Java.* *.x *.so Snap.* javacore.* jitdump.* *.lst
	rm -fr cobol.java progs.java strg.java
	rm -fr LIBAPP1* libapp1*
	rm -fr out
	rm -fr class
run.sh

#!/bin/sh
###############################################################################
#
#  IBM Enterprise COBOL for z/OS                    
#               Version 6 Release 4 Modification 0
#
#  LICENSED MATERIALS - PROPERTY OF IBM.
#
#  5655-EC6 COPYRIGHT IBM CORP. 2022, 2024
#
#  US GOVERNMENT USERS RESTRICTED RIGHTS - USE,
#  DUPLICATION OR DISCLOSURE RESTRICTED BY GSA
#  ADP SCHEDULE CONTRACT WITH IBM CORP.
#
###############################################################################
###############################################################################
# Run script for the COBOL/Java interoperability demo COBPROD
###############################################################################
#
# NOTE:
# -----
#
# 1) Make sure your STEPLIB includes an Enterprise COBOL runtime
#    that is sufficient to run programs compiled with the Enterprise
#    COBOL V6.4 or later compiler.
#
#    The dataset <USER>.COBOL.LOAD that received the program objects
#    and DLL for your interoperable application during the build
#    step must also be included in your STEPLIB.  We have added this
#    in automatically for you below.
#
# 2) Set JAVA_HOME to an appropriate 64-bit Java SDK:
#
#    e.g., JAVA_HOME=/usr/lpp/java/IBM/J8.0_64  or
#          JAVA_HOME=/usr/lpp/java/IBM/J11.0_64
#
# 3) If you modify this example so that cjbuild stores the DLL it
#    produces to a z/OS UNIX directory, then you need to modify
#    the last line of this script to the following:
#
#    ${JAVA_HOME}/bin/java -Djava.library.path=<dll_out_dir> CobProd
#
###############################################################################

if [ -z $STEPLIB ]; then
  echo "STEPLIB environment variable must be set"
  exit 1
fi

if [ -z $JAVA_HOME ]; then
  echo "JAVA_HOME environment variable must be set"
  exit 1
fi

export STEPLIB=${USER}.COBOL.LOAD:${STEPLIB}
export CLASSPATH=.:./libapp1.jar:./class:${CLASSPATH}
export IBM_JAVA_OPTIONS="-XX:+Enable3164Interoperability"
export _CEE_RUNOPTS="POSIX(ON)"
export LIBPATH=.:${JAVA_HOME}/lib/s390x/j9vm:${JAVA_HOME}/lib/s390x/:${JAVA_HOME}/bin/j9vm:${JAVA_HOME}/lib/j9vm:${LIBPATH}

${JAVA_HOME}/bin/java CobProd