COBOL - Group home

An in-depth look at calling COBOL from Java using the new non-OO COBOL/Java interoperability framework in Enterprise COBOL 6.4

  

In a previous post, I gave a high-level overview of the features of the new, non-OO COBOL/Java interoperability framework for batch and IMS environments that was introduced in Enterprise COBOL 6.4.

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

In this post, I'd like to focus on one aspect of the new support in particular:

  • Calling a COBOL program containing the JAVA-CALLABLE directive from a Java application

The discussion will focus on a simple "Hello, world!" program that can easily be extended to something more sophisticated, while at the same time providing a vehicle for an in-depth discussion of exactly how to build and launch such a program, both from z/OS UNIX and also JCL. For this discussion, we'll assume an AMODE 31 COBOL program and an AMODE 64 Java application, which is likely to be the most common configuration in practice.

Summary of goals

  • Demonstrate the ease of calling an AMODE 31 COBOL program from AMODE 64 Java application that starts on the Java side

  • Show the details of building and running this interoperable application from both z/OS UNIX and JCL. This includes examples of using the new cjbuild utility that builds the DLL that is associated with the COBOL/Java interoperable application

The one directory method

When I explore COBOL/Java interoperability using the new, non-OO interoperability framework, I like to do it from z/OS UNIX using what I call the "one directory" method. (Don't worry, we'll talk about how to run from JCL a little later.)

In the "one directory" method, you create a single directory on your z/OS UNIX file system where you put the COBOL and Java source files that you want to interoperate. Build and run commands are all executed from this directory, and all artifact files produced by the compiler are generated in this directory, as well, including the DLL generated for the application by the new cjbuild utility.

NOTE: The "one directory" method is convenient because all the files you need to work with when exploring are in one location, and you don't need to think about where the application DLL(s), Java .class files, and temporary artifact files generated by the compiler and cjbuild utility should be located. Everything is located conveniently in the current directory, or sub-directories of the current directory, which is sufficient for exploration. For production, more careful consideration needs to be given to where these files will ultimately be located -- more on that later.

For this discussion, we'll assume this special "one directory" that we're going to use has the following path on your z/OS UNIX file system:

/home/userid/jtoc/ccj

If you're following along, it would be a good idea to ensure that this directory exists now on your system.

As mentioned before, we will use a simple "Hello, world!" COBOL program that is modified to allow the passing of some simple parameters in order to demonstrate the building/running of a COBOL/Java interoperable application where Java calls COBOL.

Files involved in a COBOL/Java interoperable application

An interoperable application consists of several pieces:

  • COBOL user source file(s)

  • Java user source file(s)

  • the artifact files generated by the COBOL compiler, which include COBOL "stub" files and possibly Java class files, which would happen if, for instance, any of the user COBOL programs contain the JAVA-SHAREABLE directive

  • the "methods" file, which is a file that contains 2 types of information: i) the name of all COBOL programs involved in the interopable application that contain either a JAVA-CALLABLE or JAVA-SHAREABLE directory; ii) the name of every static Java method called from a COBOL program in the interoperable application. The method name must be in the same form as the name used in the COBOL program (e.g., Java.<fully-qualified-class-name>.<static-method-name>.

  • the DLL for your interoperable application generated by the cjbuild utility.

NOTE: Associated with every COBOL/Java interoperable application is a DLL for that application that is needed at run time. This DLL consists of the glue code (or "stub" files) that are needed to connect COBOL and Java.

Note also that depending on how you structure your application, it's possible that you may decide to view your existing COBOL assets as consisting of multiple different "services" that can be leveraged from Java, with each service consisting of one or more COBOL files that is callable from Java, for example. In this case, cjbuild could be used to group the stub files associated with each independent service into its own DLL that can be used by many different interoperable applications. Each application would depend on more than one DLL in this case (i.e., there would be one DLL per service used by the application).

In the end, there is flexibility in how you build your application, but for our examples, we will build all stub files needed for a single interoperable application into a single DLL. This method is simple and should work fine, even in production. If using this method results in a single stub file being included in the DLLs of multiple different interoperable applications (because the associated COBOL program was used in each of those different interoperable applications), that is perfectly fine because stub files are only small pieces of code anyway.

At run time, the the location of the DLLs for your application must be included in your LIBPATH environment variable, if located on the z/OS UNIX file system, or must be included in your STEPLIB if located in a PDS/E data set.

COBOL program file prog1.cbl

       identification division.
       program-id. prog1.
       data division.
       working-storage section.
       01 idx pic s9(9) comp-5 value 0.
       linkage section.
       01 intlist.
         03 int-data pic s9(9) comp-5 occurs 3 times.
       >>java-callable
       procedure division using intlist.
       MainProgram.
           display 'Hello, from prog1!'
           perform varying idx from 1 by 1
                   until idx > 3
             display 'COBOL PROG1: incoming array value '
                     idx ' = ' int-data(idx)
           end-perform
           goback.
       end program prog1.

Important things to note about the COBOL program:

  • The program contains the JAVA-CALLABLE directive, which tells the COBOL compiler that this program should be made callable from Java. This will result in the COBOL compiler generating a stub file that provides the glue code to connect Java to COBOL and perform any necessary data conversions for the call

  • The JAVA-CALLABLE directive can be placed anywhere before the PROCEDURE DIVISION header

  • The program has one parameter, which is a fixed-length table of 3 binary integer elements. This type of COBOL parameter can receive an argument from Java of type int[3]

  • Besides adding the JAVA-CALLABLE directive to your program and running cjbuild (see below) to build stub files associated with your program into a DLL, there are no other changes necessary to your existing COBOL program to make it callable from Java. That is it!

Java program TestApp.java

The following program makes a call to a COBOL native method called PROG1.

import enterprise.COBOL.*;

public class TestApp
{
  public static void main(String[] args)
  {
    int[] intlist = {7, 8, 9};

    System.out.println("Java: TestApp.main calling COBOL prog1");
    enterprise.COBOL.progs.PROG1(intlist);
  }
}

Building and running on z/OS UNIX

In this section, we'll provide z/OS UNIX shell scripts that can be used to build/run the application from z/OS UNIX.

It should be noted that, in general, the way a non-OO COBOL/Java interoperable application is built is as follows:

  • user COBOL programs are compiled specifying the JAVAIOP option, but are not linked

  • the cjuild utility is run to build the DLL for the interoperable application

    • currently, this step requires an input file that lists all the COBOL programs that contain either the JAVA-SHAREABLE or JAVA-CALLABLE directive as well as the name of any static Java methods called from COBOL programs in the application -- this is the so-called "methods" file

    • this step produces a "side deck" of exported DLL symbols that must be used in subsequent steps when linking the user COBOL programs

  • user COBOL programs are linked as normal with the exception that programs are now linked against the side deck generated in the previous step

"methods" file to use for cjbuild

The following is the contents of a file called methods that exists in the current directory in this example and is specified as input to the cjbuild utility (see the build.sh file below).

_NOTE: the purpose of the "methods" file is to allow users to maintain a single directory (not talking about the "one directory" method here) that contains all the COBOL "stub" files for all COBOL programs in your shop that are involverd in COBOL/Java interoperability, and then define different interoperable applications from subsets of stub files, maintaining a different "methods" file for each interoperable application.

Note also that this is not necessarily the only way to approach managing the files/artifacts involved in interoperable applications. It's merely one approach that may work for you. _

Here is the contents of the methods file (called "methods") for this example:

PROG1

build script build.sh

#!/bin/sh

export JAVA_HOME=/usr/lpp/java/J11.0_64
# ATTN: ensure the STEPLIB environment variable is set appropriately

# STEP 1: Compile user COBOL programs, specifying JAVAIOP option
cob2 -c prog1.cbl "-qjavaiop(java64)"

# STEP 2: Build stub file DLL using cjbuild
cjbuild -v --mode MIX_31_64 -d . methods app1

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

# STEP 4: Build Java parts of the application
${JAVA_HOME}/bin/javac TestApp.java

Things to note about this build script:

  • Since we're using the "one directory" approach to explore COBOL/Java interoperability, the OUTPATH suboption of the JAVAIOP compiler option is not specified when compiling prog1 (it defaults to the current directory, as desired)

  • the JAVA64 suboption of the JAVAIOP option is specified in order to let the compiler know that this interoperable application is targeting AMODE 64 Java.

    • Note: the JAVA64 suboption is only supported when the LP(32) option is in effect. When LP(64) is in effect, it is assumed that AMODE 64 Java is the target.

  • the cjbuild command specifies the -m MIX_31_64 option as the build mode to let cjbuild know that we're creating an application that is a mix of AMODE 31 COBOL and AMODE 64 Java.

  • the location of the DLL produced by cjbuild (see -d option) is the current z/OS UNIX directory (that's just for convenience for this exploration). In reality, the location of the DLL can be any general z/OS UNIX path (and that path must be included in your LIBPATH environment variable at run time) or any PDS or PDSE data set (in this case the name of the data set must be specified to cjbuild in a format similar to the following //'USERID.COBOL.LOAD', and at run time that data set must be in your STEPLIB).

  • wherever cjbuild is run, a "side deck" of exported symbols for the DLL produced will be available in that directory with the file extension .x. This file is required during linking of the user COBOL program in a subsequent step (see STEP 3 in the above script).

    • NOTE: If alternatively the DLL is targeted for a data set named USER.COBOL.LOAD and the DLL is called LIBAPP1, then a side deck will also be created as a member named LIBAPP1 in a data set called USER.COBOL.EXP. That data set will be created if it does not already exist. This is useful when invoking the linker from JCL.

What to expect when running the build script

Before running the build script, ensure that the STEPLIB environment variable in your shell is set appropriately to point to your COBOL compiler and runtime, and ensure that your COBOL zFS install directory is included in your PATH environment variable. For example, your COBOL zFS install directory may be something such as /usr/lpp/cobol/igyv6r4.

Run the build.sh from the current directory by issuing the following command:

./build.sh

The following output should be produced:

 PP 5655-EC6 IBM Enterprise COBOL for z/OS  6.4.0 in progress ...
 End of compilation 1,  program PROG1,  no statements flagged.

Running cjbuild COBOL/Java build tool
=====================================

 NATIVE_METHODS_FILE = methods
 DLL_BASE_NAME       = app1
 COBOL_DIR           = .
 DLL_OUT_DIR         = .
 JAVA_CLASS_DIR      = .
 JAVA_SRC_DIR        = .
 PACKAGE_NAME        = enterprise.COBOL
 INTEROP_MODE        = MIX_31_64

JAVA_HOME: /usr/lpp/java/J11.0_64
COBOL_INSTALL_DIR: /home/userid/cobol/igyv6r4

User env STEPLIB: TSC390.COBOL.IGY.V6R4M0.GOOD.SIGYCOMP:TSCTEST.COBRTE.NIGHTLY.SCEERUN2:TSCTEST.COBRTE.NIGHTLY.SCEERUN:TSCTEST.CEEZ310.SCEERUN:TSCTEST.CEEZ310.SCEERUN2

Including file in app DLL: PROG1_java_native_app1

# Compiling native method call stub PROG1_java_native_app1
/home/userid/cobol/igyv6r4/bin/cob2 -qlist -qopt(1),nsymbol(national),dbcs -c /home/userid/jtoc/test/simple/jcc/PROG1_java_native_app1.cbl -I /home/userid/cobol/igyv6r4/include
# Command return code 0

# Compiling WS access object invalidate routine
/home/userid/cobol/igyv6r4/bin/cob2 -qlist -qopt(1),nsymbol(national),dbcs -c igycjimc.cbl -I /home/userid/cobol/igyv6r4/include
# Command return code 0

# Compiling Call to JAVA exception check routine
/home/userid/cobol/igyv6r4/bin/cob2 -qlist -qopt(1),nsymbol(national),dbcs -c igycjest.cbl -I /home/userid/cobol/igyv6r4/include
# Command return code 0

# Linking native method DLL
/home/userid/cobol/igyv6r4/bin/cob2 -bdll -o ./libapp1.so PROG1_java_native_app1.o igycjimc.o igycjest.o /usr/lpp/java/J11.0_64/lib/j9vm/libjvm31.x /home/userid/cobol/igyv6r4/lib/igzxjni2.x
# Command return code 0

# Building java application files
/usr/lpp/java/J11.0_64/bin/javac -d . -cp . ./cobol.java ./progs.java ./strg.java
# Command return code 0


cjbuild completed successfully.
===============================

At this point, at a minimum, the following files should be in your directory:

PROG1_java_native.sig
PROG1_java_native.cbl
PROG1_java_native_app1.cbl
PROG1_java_native_app1.lst
PROG1_java_native_app1.o
TestApp.class
TestApp.java
build.sh
cobol.java
enterprise/
enterprise/COBOL
enterprise/COBOL/cobol.class
enterprise/COBOL/progs.class
enterprise/COBOL/strg.class
igycjest.cbl
igycjest.lst
igycjest.o
igycjimc.cbl
igycjimc.lst
igycjimc.o
libapp1.x
methods
prog1.cbl
prog1.lst
prog1.o
progs.java
run.sh
strg.java

The user should not concern themselves with most files in this directory, which is largely a work directory for the compiler. The only files that the user needs to be aware of at the end is libapp1.so, which is the DLL for the application created by cjbuild, prog1, which is the COBOL executable, and TestApp.class, which is the .class file for the user Java program TestApp.java. The remaining files are stub files (e.g., PROG1_java_native.cbl), build artifact files (e.g., prog1.o, prog1.lst, etc.) and generated code files that were needed temporarily so they could be included in the DLL. In short, of the output files produced, only the DLL and .class files and prog1 are needed after the build operation. The rest of the generated files may be cleaned up. This is a task left for the user.

run script run.sh

#!/bin/sh

export JAVA_HOME=/usr/lpp/java/J11.0_64
# ATTN: ensure the STEPLIB environment variable is set appropriately
export STEPLIB=${USER}.COBOL.LOAD:$STEPLIB
export CLASSPATH=.:./class:${CLASSPATH}
export IBM_JAVA_OPTIONS="-XX:+Enable3164Interoperability"
export _CEE_RUNOPTS="XPLINK(ON),POSIX(ON)"
export LIBPATH=.:${JAVA_HOME}/lib:${JAVA_HOME}/lib/j9vm:${LIBPATH}

${JAVA_HOME}/bin/java TestApp

Things to note about this run script:

  • We assume that we're targeting Java 11 here.

What to expect when running the application

To run the application, first ensure that your STEPLIB environment variable is set appropriately, then issue the following command:

./run.sh

The following output should be produced:

Java: TestApp.main calling COBOL prog1
Hello, from prog1!
COBOL PROG1: incoming array value 0000000001 = 0000000007
COBOL PROG1: incoming array value 0000000002 = 0000000008
COBOL PROG1: incoming array value 0000000003 = 0000000009

Making it work in production with JCL

Once you're done exploring and have written the final version of your interoperable application and tested it thoroughly, you'll eventually want to move it into production.

NOTE: For this discussion, we'll assume that, ultimately, you will want to build and launch your application from JCL.

It turns out that building your interoperable application for production is relatively easy. You just need to think about the locations of all the different types of files involved. These locations can be a mix of data sets and z/OS UNIX directories. The locations you are already using for most of those files in your system can continue to be used, typically. However, there are a few new locations to think about, as well, with the two most important ones being:

  1. The location of stub files output from the COBOL compiler which will be consumed by the cjbuild utility and built into a DLL.

  • Specify this path explicitly in a production build using the OUTPATH suboption of the JAVAIOP option

  1. The location of the DLL for your application built by cjbuild

  • we recommend it be a data set for production.

  • this data set just needs to be in your STEPLIB at run time

  • in the JCL below, see Step 2 for how a data set is specified as the output location for the DLL and see Step 5 for how that data set is included in the STEPLIB at run time

  1. The location of any .class files generated by cjbuild. This location should be a z/OS UNIX directory that is included in your Java CLASSPATH at run time. Note that the Java package name you choose for the generated Java code also plays a part in determining the location of the files. NOTE: the default package name used for generated Java files is enterprise.COBOL. It is fine to accept that (and most defaults) when using the "one directory" method for exploration, but for production we strongly suggest you customize the package name (e.g, com.acme.interopapp1).

Let's go through all the different file locations relevant to your application and discuss in more detail:

  • COBOL user source files

    • in general, COBOL user source files can continue to reside where they always reside in your environment, which we assume in our JCL is in a data set

  • Java user source files

    • in general, Java user source files can continue to reside where they always reside in your environment, which we assume in our JCL is on the z/OS UNIX file system

  • the z/OS UNIX directory that will receive all the "stub" files and other artifact files generated by the Enterprise COBOL compiler when compiling programs that use non-OO COBOL/Java interoperability constructs.

    • this location is specifed using the OUTPATH suboption of the JAVAIOP compiler option, e.g., JAVAIOP(OUTPATH('output-path'),JAVA64)

    • this same path should be specified using -c or --coboldir option when running cjbuild

  • the z/OS work directory for building the application (NOTE: cjbuild requires a z/OS UNIX work directory even when run from JCL)

    • this is the directory from which cjbuild is run. Many of the work files it generates (files that are generally not relevant for users) will be generated here

    • it is strongly recommended that in production, your work directory is different from the location of the stub files and the location where class files are output (unlike the "one directory method")

  • output location for COBOL program objects corresponding to user COBOL programs

    • in general, COBOL program objects can be stored in the same locations they are always stored, which is assumed to be data sets in the JCL below

    • NOTE: For Java-calls-COBOL scenarios, this location must be a data set because that scenario depends on the COBOL dynamic calling mechanism.

  • the output location that will receive the DLL for your interoperable application as mentioned previously, we recommend the location for the DLL be a data set the location of the data set is specified using the -d or --dlloutdir option of the cjbuild utility, e.g,. -d "//'USERID.COBOL.LOAD'"

  • the output location that will receive .class files generated by cjbuild this location can be specified to cjbuild using the -j or --javaclassdir option of the cjbuild utility also be sure to specify the -p or --pkgname option of cjbuild to indicate the Java package with which the generated Java code will be associated.

Setting these locations in the JCL sample code

The JCL sample is written to allow users to specify all the relevant locations (and a few more not discussed above) using JCL variables defined at the top of the JCL.

The JCL contains detailed descriptions of every variable you should set, but the most relevant ones are:

  • JAVAHOME - the location on z/OS UNIX of your Java SDK (this should be whatever you set the JAVA_HOME environment variable to

  • ZFSCBDIR - the location of your COBOL zFS install directory

  • OUTDIR - the location of stub files and other artificat files produced by the Enterprise COBOL compiler (should correspond to the OUTPATH subopion of the JAVAIOP compiler option used to build your COBOL files)

  • WORKDIR - the z/OS UNIX directory from which cjbuild will be run

  • CLASSOUT - the z/OS UNIX directory where your .class files will be placed by cjbuild

  • PKGNAME - the Java package with which to associated all generated Java files

  • DLLNAME - the suffix of the DLL file created by the cjbuild - when the DLL is targeted to a data set, the name specified must be 5 characters or less, as the prefix 'LIB' will be pre-pended to the provided name, and there is a maximum of 8 characters in a data set member name.

See the JCL for more defails about how to set these variables, and replace any instances of TREMAIN or tremain in the paths or data set names with your own userid.

Related links

  1. 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)
  2. COBOL/Java interoperability outside the object-oriented COBOL framework

  3. Calling static Java methods from COBOL

  4. Mapping between COBOL and Java data types in the non-OO COBOL/Java interoperability framework

JCL for build and run

//TREMAIN2 JOB 'JAVA/COBOL interop',
// MSGLEVEL=(1,1),MSGCLASS=S,CLASS=C,NOTIFY=&SYSUID,
// REGION=0M
//********************************************************************/
//*                IBM Enterprise COBOL for z/OS                     */
//********************************************************************/
//********************************************************************/
//*                                                                   *
//*      LICENSED MATERIALS -- PROPERTY OF IBM.                       *
//*                                                                   *
//*      5655-EC6                                                     *
//*      COPYRIGHT IBM CORP. 2024                                     *
//*                                                                   *
//*      US GOVERNMENT USERS RESTRICTED RIGHTS - USE, DUPLICATION OR  *
//*      DISCLOSURE RESTRICTED BY GSA ADP SCHEDULE CONTRACT WITH IBM  *
//*      CORP.                                                        *
//*                                                                   *
//********************************************************************/
//*********************************************************************
//*
//*  Sample JCL for building and running a non-OO COBOL/Java
//*  interoperable application starting on the Java side with
//*  Java calling COBOL.
//*
//*********************************************************************
//*
//*  Prerequisites:
//*
//*  1) User COBOL source files must be copied to data set:
//*     USER.COBOL.COBOL.
//*
//*  2) A PDSE data set named USER.COBOL.OBJECT must exist
//*     to receive object program files generated by the COBOL
//*     compiler.
//*
//*  3) A PDSE data set USER.COBOL.LOAD must exist to receive
//*     program object files. These program objects come from
//*     linking object files from user programs and also from
//*     linking the object files associated with stub programs
//*     into a DLL.
//*
//*     A PDS data set (FB 80) called USER.COBOL.EXP must also
//*     exist prior to running this JCL.  This data set will
//*     receive the side deck for the DLL produced by cjbuild
//*     and is used during subsequent link steps.
//*
//*  4) You must ensure the following JCL variables are set below,
//*     which control various build parameters. This includes the
//*     z/OS UNIX directory into which stub files will be generated
//*     by the compiler and the z/OS UNIX work directory to be
//*     used by the cjbuild utility. The cjbuild utility uses this
//*     directory to build the DLL needed for the interoperable
//*     application.
//*
//*     For this sample, we assume the z/OS UNIX directory
//*     structure to be used for building the application is as
//*     follows:
//*
//*     /home/tremain/jtoc/test/simple/jcc/work
//*       - main work directory
//*     /home/tremain/jtoc/test/simple/jcc/out
//*       - stub file output directory (compiler places stub
//*         files here)
//*     /home/tremain/jtoc/test/simple/jcc/class
//*       - directory where cjbuild places any generated .class
//*         files
//*
//*     The following variables must be set:
//*
//*     JAVAHOME
//*     ZFSCBDIR
//*     OUTDIR
//*     INTMODE
//*     WORKDIR
//*     CLASSOUT
//*     JVSRCOUT
//*     PKGNAME
//*     DLLNAME
//* 
//*     See below for detailed descriptions of how to set these
//*     variables. Example values are provided.
//*
//*     NOTE: z/OS UNIX directories for stub files and the work
//*           directory for cjbuild do not have to exist.  The
//*           JCL below create the directories if they do not
//*           exist prior to running this job (see STEP 0).
//*
//*  5) The contents of the "methods" file, used as input to the
//*     cjbuild utility, is specified in the instream data
//*     set STDPARM in STEP 2 that contains the UNIX commands
//*     that are required to run the cjbuild utility.  To change
//*     the list of methods whose associated stub files should
//*     be included in the DLL, change the "echo" commands that
//*     are used to append each method name to the methods file.
//*
//*********************************************************************
// EXPORT SYMLIST=*
//*********************************************************************
//* Set compiler and run time library levels below
//*******************************************************************
//         SET LIBPRFX='TSCTEST.CEEZ240'
//         SET LNGPRFX='TSC390.COBOL.IGY.V6R4M0.GOOD'
//*******************************************************************
//* JAVAHOME: Set this to your Java home directory. This will be used
//*           to set the JAVA_HOME environment variable needed by
//*           Java operations
//*******************************************************************
//         SET JAVAHOME='/usr/lpp/java/J11.0_64'
//*******************************************************************
//* ZFSCBDIR: This should point to the location of your COBOL zFS
//*          install directory (e.g., /usr/lpp/cobol/igyv6r4)
//*
//*          The bin directory of this directory is where the cob2
//*          and cjbuild utilities reside.  They will be needed
//*          when building the interoperable application
//*******************************************************************
//         SET ZFSCBDIR='/home/tremain/cobol/igyv6r4'
//*******************************************************************
//* OUTDIR: Set this to the z/OS UNIX directory that will receive
//*         the stub files and other artifact files generated by
//*         the COBOL compiler compiling programs that contain
//*         the JAVA-CALLABLE and JAVA-SHAREABLE directives or
//*         programs that make calls to Java using a CALL statement
//*         of the form:
//*
//*             CALL 'Java.class-name.static-method-name' ...
//*
//*         The cjbuild uility (see STEP 2) will get the files from
//*         this directory (see --coboldir option) so the directory
//*         specified for OUTDIR should be used both in the OUTPATH
//*         suboption of JAVAIOP when compiling the user COBOL
//*         program as well as the --coboldir option of cjbuild.
//*******************************************************************
//         SET OUTDIR='/home/tremain/jtoc/test/simple/jcc/out'
//*******************************************************************
//* INTMODE: Set this to the interoperability mode to be used
//*          by your application (needed by the cjbuild utility)
//*
//*          PURE31 - AMODE 31 COBOL, AMODE 31 Java
//*          PURE64 - AMODE 64 COBOL, AMODE 64 Java
//*          MIX_31_64 - AMODE 31 COBOL, AMODE 64 Java
//*
//*          NOTE: if you specify MIX_31_64, you must add the
//*                JAVA64 suboption to the JAVAIOP option of
//*                all related user COBOL programs.
//*******************************************************************
//         SET INTMODE='MIX_31_64'
//*******************************************************************
//* WORKDIR: Set this to the z/OS UNIX directory to be used as a work
//*          directory for building the interoperable application.
//*          cjbuild will be run from this directory and basic
//*          artifact files it generates (object files, listing,
//*          etc.) go to this directory automatically.
//*
//*          This is where the "methods" file will be located for
//*          this sample.
//*******************************************************************
//         SET WORKDIR='/home/tremain/jtoc/test/simple/jcc/work'
//*******************************************************************
//* CLASSOUT: Set this to the directory you want any .class files
//*           generated by cjbuild to go.  These are the .class
//*           files for Java accessor classes for JAVA-SHAREABLE
//*           items, and also .class files for any Java files
//*           generated by cjbuild, such as cobol.java, progs.java,
//*           and strg.java.
//*******************************************************************
//         SET CLASSOUT='/home/tremain/jtoc/test/simple/jcc/class'
//*******************************************************************
//* JVSRCOUT: Set this to the directory you want any .java files
//*           generated by cjbuild to go (cobol.java, progs.java,
//*           strg.java).
//*******************************************************************
//         SET JVSRCOUT='/home/tremain/jtoc/test/simple/jcc/work'
//*******************************************************************
//* PKGNAME:  Set this to the name of the Java package that you
//*           want the 'progs' and 'strg' class to be a part of.
//*           The default is enterprise.COBOL.  This affects how
//*           COBOL programs are invoked from Java.  e.g., if the
//*           package name is enterprise.COBOL., then you would
//*           invoke a COBOL program called PROG1 as follows:
//*
//*           enterprise.COBOL.progs.PROG1();
//*******************************************************************
//         SET PKGNAME='enterprise.COBOL'
//*******************************************************************
//* DLLNAME: The name of the DLL that cjbuild creates and which
//*          is needed at runtime when interoperable activities
//*          occur in the application.
//*
//*          If the DLL is targeted for a data set (which is
//*          the usual way, see --dlloutdir option of cjbuild)
//*          then the DLL will be stored as a member of the
//*          specified data set, and is called LIB<DLLNAME>.
//*
//*          If the DLL is targeted to the z/OS UNIX file system,
//*          it will be called lib<dllname>.so.
//*******************************************************************
//         SET DLLNAME=APP1
//*******************************************************************
//PROCLIB JCLLIB ORDER=(&LNGPRFX..SIGYPROC)
//*******************************************************************
//*******************************************************************
//* STEP 0: Ensure required z/OS UNIX directories exist
//*******************************************************************
//*******************************************************************
//CRDIRS   EXEC PGM=BPXBATCH
//STDPARM  DD *,SYMBOLS=EXECSYS
SH mkdir -p &OUTDIR;
mkdir -p &WORKDIR;
mkdir -p &CLASSOUT;
mkdir -p &JVSRCOUT
/*
//STDOUT   DD SYSOUT=*
//STDERR   DD SYSOUT=*
//STDENV   DD *
NO_CUSTOM_SHELL=1
/*
//*******************************************************************
//*******************************************************************
//* STEP 1: Compile user COBOL programs, specifying JAVAIOP option
//*******************************************************************
//*******************************************************************
// SET INFILE='PROG1'
//*******************************************************************
// IF (CRDIRS.RUN AND (CRDIRS.RC EQ 0)) THEN
//COBOL1   EXEC IGYWC,
//  LNGPRFX=&LNGPRFX,
//  LIBPRFX=&LIBPRFX,
//  PARM.COBOL='OPTFILE'
//SYSLIB   DD DSN=&SYSUID..COBOL.COBOL,DISP=SHR
//SYSIN    DD DSN=&SYSUID..COBOL.COBOL(&INFILE),DISP=SHR
//SYSLIN   DD DSN=&SYSUID..COBOL.OBJECT(&INFILE),DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSOPTF  DD *,SYMBOLS=EXECSYS
 JAVAIOP(OUTPATH('&OUTDIR'),JAVA64)
/*
//SYSOUT   DD SYSOUT=*
// ENDIF
//*******************************************************************
//* STEP 2: Build stub file DLL using cjbuild
//*******************************************************************
// IF (COBOL1.COBOL.RUN AND (COBOL1.COBOL.RC EQ 0)) THEN
//CJBUILD EXEC PGM=BPXBATCH
//STDPARM  DD *,SYMBOLS=EXECSYS
SH export JAVA_HOME=&JAVAHOME;
PATH=.:/bin:/usr/bin:/usr/local/bin:&ZFSCBDIR/bin;
cd &WORKDIR;

echo PROG1 > methods;

&ZFSCBDIR/bin/cjbuild
 -v
 --coboldir &OUTDIR
 --dlloutdir "//'&SYSUID..COBOL.LOAD'"
 --pkgname &PKGNAME
 --javaclassdir &CLASSOUT
 --javasrcdir &JVSRCOUT
 --mode &INTMODE
 methods &DLLNAME
/*
//STEPLIB DD  DSN=&LNGPRFX..SIGYCOMP,DISP=SHR
//        DD  DSN=&LIBPRFX..SCEERUN,DISP=SHR
//        DD  DSN=&LIBPRFX..SCEERUN2,DISP=SHR
//STDOUT  DD SYSOUT=*
//STDERR  DD SYSOUT=*
//STDENV  DD *,SYMBOLS=EXECSYS
NO_CUSTOM_SHELL=1
_C89_LSYSLIB=&LIBPRFX..SCEELKED
/*
// ENDIF
//*******************************************************************
//*******************************************************************
//* STEP 3: Link user programs.  User programs may call out to
//*         programs in the DLL produced by cjbuild in STEP 2
//*         thus should be linked with the side deck produced in
//*         that step
//*******************************************************************
//*******************************************************************
// SET INFILE='PROG1'
//*******************************************************************
// IF (CJBUILD.RUN AND (CJBUILD.RC EQ 0)) THEN
//LKED1 EXEC PGM=IEWL,
// PARM='RENT,LIST,LET,DYNAM(DLL),CASE(MIXED)'
//SYSLIB DD DSN=&LIBPRFX..SCEELKED,DISP=SHR
//       DD DSN=&LIBPRFX..SCEELKEX,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSTERM DD SYSOUT=*
//SYSLMOD DD DSN=&SYSUID..COBOL.LOAD(&INFILE),DISP=SHR
//SYSDEFSD DD DUMMY
//OBJMOD DD DSN=&SYSUID..COBOL.OBJECT(&INFILE),DISP=SHR
//SIDEDK DD DSN=&SYSUID..COBOL.EXP(LIB&DLLNAME),DISP=SHR
//SYSLIN DD *
 INCLUDE OBJMOD
 INCLUDE SIDEDK
/*
// ENDIF
//*******************************************************************
//*******************************************************************
//* STEP 4: Builds Java application
//*******************************************************************
//*******************************************************************
// IF (LKED1.RUN AND (LKED1.RC EQ 0)) THEN
//BLDJAVA EXEC PGM=BPXBATSL
//STDPARM DD *,SYMBOLS=EXECSYS
PGM &JAVAHOME/bin/javac
 -d &CLASSOUT
 &WORKDIR/TestApp.java
/*
//STDOUT  DD SYSOUT=*
//STDERR  DD SYSOUT=*
//STDENV  DD *,SYMBOLS=EXECSYS
JAVA_HOME=&JAVAHOME
CLASSPATH=.:&CLASSOUT
PATH=.:/bin:/usr/bin:/usr/local/bin:&ZFSCBDIR/bin
/*
// ENDIF
//*******************************************************************
//*******************************************************************
//* STEP 5: Run COBOL/Java interoperable application
//*******************************************************************
//*******************************************************************
// IF (BLDJAVA.RUN AND (BLDJAVA.RC EQ 0)) THEN
//GO      EXEC PGM=BPXBATSL
//STDPARM DD *,SYMBOLS=EXECSYS
PGM &JAVAHOME/bin/java TestApp
/*
//STEPLIB DD DSN=&SYSUID..COBOL.LOAD,DISP=SHR
//        DD DSN=&LNGPRFX..SIGYCOMP,DISP=SHR
//        DD DSN=TSCTEST.COBRTE.NIGHTLY.SCEERUN,DISP=SHR
//        DD DSN=TSCTEST.COBRTE.NIGHTLY.SCEERUN2,DISP=SHR
//        DD DSN=TSCTEST.CEEZ240.SCEERUN.LE3164,DISP=SHR
//        DD DSN=TSCTEST.CEEZ240.SCEERUN2.LE3164,DISP=SHR
//        DD DSN=&LIBPRFX..SCEERUN,DISP=SHR
//        DD DSN=&LIBPRFX..SCEERUN2,DISP=SHR
//STDOUT  DD SYSOUT=*
//STDERR  DD SYSOUT=*
//STDENV  DD *,SYMBOLS=EXECSYS
JAVA_HOME=&JAVAHOME
PATH=.:/bin:/usr/bin:/usr/local/bin:&ZFSCBDIR/bin
_C89_LSYSLIB=&LIBPRFX..SCEELKED
CLASSPATH=.:&CLASSOUT
_CEE_RUNOPTS=XPLINK(ON),POSIX(ON)
IBM_JAVA_OPTIONS="-XX:+Enable3164Interoperability"
/*
// ENDIF