Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus...

38
Creating Applications Using Java and Micro Focus COBOL Part 1

Transcript of Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus...

Page 1: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

Creating Applications Using Java and Micro Focus

COBOL Part 1

Page 2: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

Abstract

The use of Java as both a programming language and an application

development platform is continuing to grow. More and more

companies are using Java for new development, yet have a large

existing base of COBOL code that is running their businesses today.

Rather than rewrite the COBOL code in Java, companies are looking

for ways to reuse their existing investment in COBOL in their new Java

development. This is the first in a series of papers that examines how

this can be done today using Micro Focus tools and look forward to

new innovations from Micro Focus that will make this even easier in

the future.

Page 3: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 3 -

Contents

Why use Java and COBOL? ......................................................................................4 So why is mixing Java with other languages difficult?............................................................................................. 5 Example of using the Java Native Interface from COBOL......................................................................................... 5 Example Code.................................................................................................... 11

Creating a Mixed Java/COBOL Application...........................................................13 Building the COBOL Code................................................................................. 13 A Wrapper Class ................................................................................................ 18

Use the mfcobol Package........................................................................... 22 Loading the COBOL Program .................................................................... 23 Calling the COBOL Program ...................................................................... 23

Handling Complex Types .................................................................................. 27 The DataType Interface.............................................................................. 29 Example ...................................................................................................... 30 Other Examples .......................................................................................... 34

Putting it all Together....................................................................................... 37

Conclusion..............................................................................................................38

Page 4: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 4 -

Why use Java and COBOL?

According to Gartner1, the number of programmers developing applications in Java has grown enormously over the last few years and that growth is expected to continue, with a projected number of 2.5 million programmers using Java by 2005. One of the primary reasons for this is that Java is not just a programming language, but an entire architecture. Java 2 Enterprise Edition (J2EE) is becoming the mainstream enterprise application architecture. All of the leading J2EE Application Server vendors, including IBM with WebSphere, BEA with WebLogic and Oracle with Oracle9i Application Server are delivering solutions that can meeting the largest customer’s speed and scalability requirements2.

At the same time, there is a huge amount of COBOL code in existence today that is deployed throughout the enterprise, performing critical day-to-day operations. Rewriting all of this code is rarely an option, so the logical choice is to integrate the existing COBOL code into the new applications being created in Java.

This paper is the first in a series of papers that examines how Java and COBOL can work together. This paper looks at the problems inherent in Java interfacing with other languages and the solutions offered by Micro Focus in Net Express and Server Express. Future papers will focus on the issues involved in creating web-based applications using Java technologies and COBOL, as well as new features planned for future versions of Net Express and Server Express.

When reading this paper, you will find it helpful if you have some familiarity with the Java programming language.

1 “Strategic Analysis Report”, Feiman and Berg, Gartner Research, 19th December 2001

2 “Worldwide Third-Generation Language Forecast and Analysis, 2002-2006”, Kirzner, IDC

Page 5: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 5 -

So why is mixing Java with other languages difficult?

Java is not just a programming language. It is an entire platform for developing and executing applications. Java applications are written in the Java programming language and compiled to a machine-independent, binary code called byte code. In order to execute the byte code, you need a Java Virtual Machine (JVM). In many ways, this is similar to the original architecture used for Micro Focus COBOL. COBOL programs were (and can still be) compiled to intermediate code which could then be executed on any machine where a Micro Focus COBOL run-time system was installed (if you are not familiar with intermediate code, you can find more information on the various Micro Focus executable formats in the paper “Building Applications with Micro Focus COBOL” at http://www.microfocus.com/whitepapers/).

Most programming languages used on the PC and UNIX are compiled to a machine-specific object code and linked with various system libraries to form an executable application. The Java specifications refer to this as native code since the applications are compiled to the native machine instructions for a particular machine. It is quite common for programmers to mix object code modules, developed using different programming languages, together to form an application.

To enable a Java application to call native code modules and for native code to call Java, the Java designers provided an interface called the Java Native Interface (JNI). The JNI is a very powerful interface that provides for a lot of flexibility. Unfortunately for COBOL programmers, the interface was clearly designed by programmers who were mostly familiar with languages such as C or C++ and makes extensive use of features that are not standard in the COBOL language, such as pointers to procedural code.

Example of using the Java Native Interface from COBOL

Although using the JNI is possible using Micro Focus COBOL because of the extensions Micro Focus has added to the language over the years, it is not a straightforward task. For example, the following program is a COBOL program that is called by a Java class. It takes a string and some numeric values as parameters, displays the contents and then returns a string to the Java class:

Page 6: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 6 -

$set case reentrant(1) align"8" * COBOL module called by a Java class. This * shows how simple types and strings can be * passed from Java to COBOL. identification division. * The name specified in program ID is significant. * It MUST be "Java_" followed by the class name * (Sample1), followed by another "_" and the * name of the native method. Note that the case * used is very significant. program-id. "Java_Sample1_demo". special-names. * The call convention used for JNI calls needs * to be defined here. For Win32 systems, it is * 74 (which corresponds to the stdcall calling * convention). $if UNIX defined call-convention 0 is javaapi. $else call-convention 74 is javaapi. $end local-storage section. * The copy file javatypes.cpy is provided * with Net Express. It includes various * definitions needed to use the JNI copy "javatypes.cpy". 01 StringPointer pointer. 01 ReturnedStringPointer pointer. 01 JavaStringLength jint. 01 COBOLString pic x(255). 01 DisplayFloat pic z(6)9.99. linkage section. 01 JEnv pointer. 01 jobjectPtr pointer. 01 JavaInteger jint. 01 JavaChar jchar. 01 JavaShort jshort. 01 JavaFloat jfloat. 01 JavaString pointer. 01 WorkString pic x.

Page 7: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 7 -

01 JNINativeInterfacePtr usage JNINativeInterface.

Page 8: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 8 -

* The entry point must use the JNI calling convention. * * The first parameter (JEnv) is a pointer to the JNI * function table. It must be passed (by reference) as * the first parameter on all JNI function calls. * * The second parameter (jobjectPtr) differs depending on * whether the native method is a static or instance * method. If it is an instance method, jobjectPtr is a * reference to the object on which the method was * invoked. If it is a static method, jobjectPtr is a * reference to the class in which the method is * defined. This parameter is not used in this * sample. * The subsequent parameters (JavaInteger, etc) are * the parameters passed to the method from Java. procedure division javaapi using by reference JEnv by value jobjectPtr by value JavaInteger by value JavaChar by value JavaShort by value JavaFloat by value JavaString. * Map the pointer passed in JEnv to the * JNINativeInterface structure so that we * can call JNI functions. set address of JNINativeInterfacePtr to JEnv * Strings in Java are implemented by a class and * cannot be accessed directly. We have to use * JNI functions to retrieve the value of the string and * to create new ones. Note that you CANNOT modify * the contents of a Java string - you can only * retrieve string values or create new ones. * * First, use the JNI function GetStringUTFChars * to get a pointer to an ASCII string that * contains the contents of the Java string call javaapi GetStringUTFChars using by reference JEnv by value JavaString by value 0 size 2 returning StringPointer

Page 9: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 9 -

* Check for any "Out of memory" exception that * may have been raised by GetStringUTFChars. We * need to exit so that the exception can be handled * by the Java virtual machine. if StringPointer = NULL exit program returning 0 end-if * Map a work area in linkage section on to the * returned string so that we can access it * directly set address of WorkString to StringPointer * Get the length of the string call javaapi GetStringUTFLength

using by reference JEnv by value JavaString returning JavaStringLength * Now move the string in to working storage. We do this * as we will be releasing the storage allocated * to the temporary string move WorkString(1:JavaStringLength) to COBOLString * Release the temporary string created by * GetStringUTFChars. This is very important to * avoid memory leaks. call javaapi ReleaseStringUTFChars using by reference JEnv by value JavaString by value StringPointer * Display the values passed from Java. Basic * types can be accessed directly. We move the * float and double variables into numeric-edited * display variables so that they display in a * more user-friendly manner display "Integer = " JavaInteger display "Char = " JavaChar display "Short = " JavaShort move JavaFloat to DisplayFloat display "Float = " DisplayFloat display "Jstring = " COBOLString(1:JavaStringLength) * Now setup the string to be returned back to Java move "Returned string from COBOL!" to COBOLString * Make sure the string is NULL-terminated. move x"00" to COBOLString(28:1) * NewStringUTF creates a new Java string and returns a * pointer to it call javaapi NewStringUTF using by reference JEnv by reference COBOLString

Page 10: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 1 0 -

returning ReturnedStringPointer * Pass the returned pointer back to the caller exit program returning ReturnedStringPointer .

The Java class that calls this program is:

public class Sample1 { // Declaration of the native method call // (which is implemented in the COBOL program) native public String demo(int anint, char achar, short ashort, float afloat, String astring); // Initializer loads the COBOL module static { System.loadLibrary("cobolmodule"); } // Main method public static void main(String args[]) { int inta = 100; char charb = 65; short shortc = 102; float floatd = 103; String stringf = "Hello from JAVA!"; String returnedstring; // Create an instance of Sample1 Sample1 theDemo = new Sample1(); // Call the native COBOL method returnedstring = theDemo.demo(inta ,charb , shortc ,floatd, stringf); // and display the returned string System.out.println("Returned string from COBOL = " + returnedstring); } }

Page 11: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 1 1 -

As you can see, there is a lot of COBOL code needed to perform a relatively simple task. In addition, the code involved is not straightforward and would require significant modification to any existing COBOL code.

With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java and COBOL much easier. The release of Net Express 3.1 Service Pack 1 and updates to Server Express have added additional enhancements to this support, allowing procedural COBOL programs to be called without requiring any changes. Micro Focus introduced support for both procedural and object-oriented COBOL. The use of Java calling object-oriented COBOL was covered in an earlier paper3 and will not be discussed further here.

Example Code An example application has been developed to accompany this paper and the following sections will make references to this example. The example is a very simple classified advertisement system for a newspaper called The Corgi Times that allows the user to view advertisements in the system and place new advertisements. The user interface for this application is written entirely in Java and can be seen in Figure 1. The back-end processing code that retrieves and places advertisements is written in COBOL and is in the form of simple called COBOL program with a number of entry points. All data is stored in COBOL indexed-sequential files.

The example application is packaged as an installable executable that will verify that the required pre-requisites are on your system and then install both the executable code and the source code for the application. The requirements for running this application are as follows:

1. A computer running Microsoft Windows 98, ME, NT 4.0, 2000 or XP. Although the source code has been designed to be portable and can be ported to other systems with suitable versions of Micro Focus Server Express, the compiled executables are designed to run only on 32-bit Windows platforms.

2. Micro Focus Net Express 3.1 with Service Pack 1.

3 “Beans and COBOL: Do they Mix”, http://www.cobolportal.com/resources/technical.asp

Page 12: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

3. Sun Java Development Kit (JDK) version 1.3 or later. Other Java Virtual Machines should work, but the application is configured for the Sun Java Virtual Machine.

Figure 1 – The user interface for the Corgi Times example application

- 1 2 -

Page 13: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 1 3 -

Creating a Mixed Java/COBOL Application

The key to calling Micro Focus COBOL programs from Java is a Java class called mfcobol.runtime. This class is provided with Micro Focus Net Express 3.1 and Server Express in a Java package called mfcobol. The class mfcobol.runtime provides methods that can be invoked by a Java class to load COBOL programs and call entry points in those programs. These methods handle all of the complexity of the Java Native Interface, allowing COBOL programs to be used unchanged.

The package mfcobol also includes other classes and interface definitions that provide the underlying mechanisms that allow complex data types such as records, arrays, etc to be handled. These will be examined later in this paper.

For additional information on the techniques described in this paper, refer to the section ”Calling Procedural COBOL from Java” in the Net Express manual “Distributed Computing”.

Before anything can be done with the application, the COBOL code needs to be built correctly.

Building the COBOL Code As long as your COBOL code has been written as a callable module, using a linkage section to pass parameters, you should not need to change your source code in order to call it from Java. However, you do need to remember some key points about how the COBOL program should be compiled and linked.

First, the COBOL program should be compiled and linked as a dynamic link library (DLL) on Windows or a shared object (SO) on UNIX. It must also be linked with the multi-threaded COBOL run-time system. This is because Java Virtual Machines are inherently multi-threaded. If you are using Net Express to build your DLL, this can easily be done from the Link tab on the Build Settings dialog for your DLL (see Figure 2).

Secondly, because Java is multi-threaded, you need to be sure that data in your program is not corrupted if two threads call your program, both changing the data. For most programs, the best way to do this is to use the compiler directive REENTRANT(2). This instructs the COBOL run-time system to allocate separate areas of memory for the working storage and FD file areas in your program for each thread that calls the program. For more information on the REENTRANT(2) directive and other options available to you, refer to the section “2.2.1 Multi-Threading Considerations” in the Net Express manual “Distributed Computing”.

Page 14: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

Figure 2 – Choosing the Multi-threaded Run Time System

This is all you need to do to the COBOL program. So, let’s take a look at the COBOL program supplied with the example. The program is provided in the source file Classifieds.cbl. It contains the following entry points:

GetCategories Returns an array containing the different categories of advertisement

GetFirstAd Returns the first advertisement for a particular category

GetNextAd Returns the next advertisement in a particular category

GetDaysRemaining Returns the number of days remaining for the last advertisement retrieved

PlaceAd Place a new advertisement

- 1 4 -

Page 15: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 1 5 -

The following shows the main structure of the application, with the logic inside most of the entry points removed (the full source code is provided with the example accompanying this paper).

$set reentrant(2) program-id. Classifieds. Environment Division. Input-Output Section. File-Control. select AdFile assign to external AdFile organization is indexed access mode is dynamic record key is AR-Key file status is AR-File-Status. select AdCategories assign to external AdCategories organization is indexed access mode is dynamic record key is CR-Category file status is CR-File-Status. Data Division. File Section. FD AdFile. 01 Ad-Record. 03 AR-Key. 05 AR-Category pic x(20). 05 AR-Index pic 9(4). 03 AR-Text pic x(200). 03 AR-Start-Date pic 9(8). 03 AR-Number-Of-Days pic 99. 03 AR-Customer-Phone pic x(20). FD AdCategories. 01 Category-Record. 03 CR-Category pic x(20). 03 CR-Count pic 9(4).

Page 16: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 1 6 -

working-storage section. 01 CR-File-Status. 03 CR-File-Status-1 pic x. 03 CR-File-Status-2 pic x. 03 CR-Binary-Status redefines CR-File-Status-2 pic 99 comp-x. 01 Category-Index pic 9(2) comp. 01 EOF-Reached pic 9(2) comp. … rest of working storage variables linkage section. 01 Category-Array. 03 Category-Rec occurs 20. 05 Category-Name pic x(20). 05 Category-Ad-Count pic 9(4). 01 Category-Count pic 9(2). 01 Category pic x(20). 01 Returned-Status pic 9(8) comp-5. 88 Status-OK value 0. 88 Status-Category-Exists value 1. 88 Status-Error-Writing value 2. 88 Status-No-Categories value 3. 88 Status-Error-Reading value 4. 88 Status-End-Of-Categories value 5. 88 Status-No-Ads value 6. 88 Status-End-Of-Ads value 7. 01 Ad. 03 Ad-Category pic x(20). 03 Ad-Index pic 9(4). 03 Ad-Text pic x(200). 03 Ad-Start-Date. 05 Ad-Start-Year pic 9(4). 05 Ad-Start-Month pic 99. 05 Ad-Start-Day pic 99. 03 Ad-Number-Of-Days pic 99. 03 Ad-Customer-Phone pic x(20). 01 Days-Remaining pic 99.

Page 17: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 1 7 -

procedure division. * This is just used to load the library. The real

* work is done by the various entry points exit program. GetCategories section. entry "GetCategories" using Returned-Status Category-Array Category-Count. set Status-Ok to true open input AdCategories if CR-File-Status-1 not = "0" set Status-No-Categories to true move 0 to Category-Count else move 0 to EOF-Reached move 1 to Category-Index perform until EOF-Reached = 1 read AdCategories next at end move 1 to EOF-Reached not at end move Category-Record to Category-Rec(CategoryIndex) end-read if EOF-Reached = 0 add 1 to Category-Index end-if end-perform move Category-Index to Category-Count subtract 1 from Category-Count end-if close AdCategories exit program. GetFirstAd section. entry "GetFirstAd" using Returned-Status Category Ad. * Logic to get the first category exit program. GetNextAd section. entry "GetNextAd" using Returned-Status Ad. * Logic to get the next ad exit program. GetDaysRemaining section.

Page 18: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 1 8 -

entry "GetDaysRemaining" using Days-Remaining. * Logic to retrieve the number of days remaining * for the last ad retrieved exit program. PlaceAd section. entry "PlaceAd" using Returned-Status Ad. * Logic to place a new ad exit program.

If you have written code before that is designed to be called from other programming languages, you might be surprised to see that this is all standard COBOL code. Techniques such as using null-terminated strings are not needed. The reason for this will become clear later when we look at how data types are handled.

Now, we can turn out attention to the Java code that will call this program.

A Wrapper Class To call the COBOL program, Classifieds, a corresponding Java class called Classifieds has been created. This is a wrapper class for the COBOL program. This means that all interaction with the COBOL program is done from this Java class. The rest of the Java application only communicates with the wrapper class.

The complete wrapper class for the Classifieds COBOL program can be seen below. The following sections will examine this in detail.

package com.microfocus.demo.classifieds; import mfcobol.*; import com.microfocus.demo.coboltypes.*; public class Classifieds { private int CategoryCount = 0; private CategoryRecord[] Categories; static { // Load the COBOL program runtime.cobload("classifieds", null); }

Page 20: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 2 0 -

public Classifieds() throws Exception { Categories = new CategoryRecord[20]; for (int i = 0; i < 20; i++) Categories[i] = new CategoryRecord(); } // Get the categories of ads that are stored. Returns // the number of categories public int getCategories() throws Exception { Integer returnStatus = new Integer(0); COBOLArray COBOLCategories = new COBOLArray(Categories); pic9 COBOLCategoryCount = new pic9(2); Object params[] = {returnStatus, COBOLCategories, COBOLCategoryCount}; try { runtime.cobcall("GetCategories", params); if (returnStatus.intValue() != 0) return 0; else { CategoryCount = COBOLCategoryCount.intValue(); return CategoryCount; } } catch (Exception e) { return 0; } } public CategoryRecord getCategory(int CategoryIndex) { if (CategoryIndex > CategoryCount) return null; else return Categories[CategoryIndex]; }

Page 21: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 2 1 -

// Get the first ad for a particular category public AdRecord getFirstAd(String requiredCategory) { Integer returnStatus = new Integer(0); picX category = new picX(20, requiredCategory); AdRecord adRecord = new AdRecord(); Object params[] = {returnStatus, category, adRecord}; try { runtime.cobcall("GetFirstAd", params); if (returnStatus.intValue() != 0) return null; else return adRecord; } catch (Exception e) { return null; } } // Retrieves the next ad for a particular category. // getFirstAd must be called first to setup the category // to be retrieved public AdRecord getNextAd() { Integer returnStatus = new Integer(0); AdRecord adRecord = new AdRecord(); Object params[] = {returnStatus, adRecord}; try { runtime.cobcall("GetNextAd", params); if (returnStatus.intValue() != 0) return null; else return adRecord; } catch (Exception e) { return null; } }

Page 22: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 2 2 -

// Gets the number of days remaining for the ad last // retrieved public int getDaysRemaining() { pic9 daysRemaining = new pic9(2); Object params[] = {daysRemaining}; try { runtime.cobcall("GetDaysRemaining", params); return daysRemaining.intValue(); } catch (Exception e) { return 0; } } public int placeAd(AdRecord ad) { Integer returnStatus = new Integer(0); Object params[] = {returnStatus, ad}; try { runtime.cobcall("PlaceAd", params); return returnStatus.intValue(); } catch (Exception e) { return -1; } } }

Note. The full source code contained in the example program contains additional exception handling code to handle additional error conditions.. This has been removed here for clarity.

Use the mfcobol Package

The first point to notice in this class is the line:

import mfcobol.*;

This makes all of the classes provided by Micro Focus for Java/COBOL interoperability available to your Java code, including mfcobol.runtime.

Page 23: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 2 3 -

This package is supplied in the file mfcobol.jar, which is provided with Net Express 3.1 and Server Express 2.0. When you compile this class using the Java compiler, you need to make this class available to the compiler by specifying it on the classpath for the compiler. For more information on setting up the environment correctly, refer to the section “6.2.1 Setting Up the COBOL and Java Environments” in the Net Express manual “Distributed Computing”.

Loading the COBOL Program

The next major point is the instruction to the COBOL run-time system to load the COBOL program and make it accessible to the Java code. This is done using the line:

runtime.cobload("classifieds", null);

This loads all programs inside classifieds.dll (on Windows) or classifieds.so (on UNIX). It should only be done once in your application, so the best place to put this statement is in the static constructor for the wrapper class. This can be seen in this example.

Note. The Net Express documentation contains a section on removing COBOL programs from memory (section “2.2.6 Cancelling a COBOL Program” in the “Distributed Computing” manual). This should be ignored, since with later versions of the Java virtual machine, there is no guarantee that a finalize method for a class will be called. So the COBOL run-time system always ensures that the COBOL program is removed from memory when the particular COBOL run unit is finished.

Calling the COBOL Program

Now the COBOL program has been loaded, methods provided in the runtime class can be used to call the different entry points in the COBOL program. There are a number of different functions available. Which one you use depends on if your COBOL program returns a value using the EXIT PROGRAM RETURNING … statement. If your program does use this statement, then the function you use to make the call will vary depending on the data type of the value being returned.

Most COBOL programs, particularly existing ones, do not use the EXIT PROGRAM RETURNING statement. Instead, any return values from the program are passed back in the parameters provided to the program. So, in most cases, you are likely to use the function runtime.cobcall(). This is the function used in the example program. For information on the other functions available, refer to the Net Express Class Library Reference Manual.

Page 24: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 2 4 -

Regardless of which function you use, you always need to perform the following steps:

1. Create an object array containing the parameters that will be passed to the COBOL program.

2. If your COBOL program is expecting any parameter to be passed BY VALUE or BY CONTENT, create an integer array defining the usage type for each parameter. The default usage type for parameters is BY REFERENCE, so if all of your parameters are passed BY REFERENCE (which is usually the case), you can ignore this step.

3. Use the appropriate function to call the COBOL program, specifying the name of the entry point you are calling, the object array containing the parameters and, if needed, the integer array containing the usage types.

4. Handle any exception that occurs while attempting to call the COBOL program.

The next sections examine these steps in detail.

The Array of Parameters

All parameters that are passed to a COBOL program must be Java objects. So, if you want to pass one of the Java primitive types such as int, you need to new instance of the corresponding wrapper class to use as the parameter. So, for a parameter of type int, you would create a new instance of the class Integer. Figure 3 shows the Java primitive types, the corresponding class to use and the definition you would use in the COBOL Linkage Section of the program you are calling.

An example of using an int parameter can be seen in the example program. Many of the entry points return a status value. In COBOL, this is defined as pic s9(9) comp-5. In many of the methods, the parameter is created using the statement:

Integer returnStatus = new Integer(0);

This creates an integer parameter with an initial value of 0. Then, on return from the COBOL program, the return value is tested using the statement:

if (returnStatus.intValue() != 0) // an error occurred

Page 25: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 2 5 -

Primitive Type Class COBOL Definition

boolean Boolean s9(2) comp-5.

short Short s9(4) comp-5.

int Integer s9(9) comp-5.

long Long s9(18) comp-5.

char Character 9(4) comp-5.

byte Byte x comp-5.

float Float comp-1.

double Double comp-2.

Figure 3 – The primitive Java types and their COBOL equivalents

To pass the parameters to the COBOL program, an array of objects is required. The position of the object in the array corresponds to the position of the parameter in the USING clause in the COBOL program. For example, for a COBOL Linkage Section and USING clause defined as follows:

Linkage Section. 01 A pic s9(4) comp-5. 01 B pic s9(9) comp-5. Procedure division using A B.

you might use the following Java code to set up the parameters:

short a = 1; int b = 2; Short paramA = new Short(a); Integer paramB = new Integer(b); Object params[] = {paramA, paramB};

Page 26: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 2 6 -

Unfortunately, the table shown in Figure 3 does not give much of a choice of data types to use. In addition, most of the COBOL definitions do not correspond to definitions usually used in COBOL programs. For example, there is not a primitive type for string in Java – strings are handled using the class String. In fact, if you look at the Micro Focus documentation for information on how to handle Java strings passed to COBOL programs, it appears to be quite complicated. Fortunately, in Service Pack 1 for Net Express 3.1 and later updates to Server Express 2.0, Micro Focus introduced an easier way of handling strings or any other complex data type. This will be described in detail in the section “Handling Complex Types” later.

The Array of Usage Types

In most COBOL programs, all parameters are passed BY REFERENCE. Clauses such as BY VALUE or BY CONTENT are not used. So, for most programs, you do not need to worry about specifying usage types. However, if your COBOL program does use BY VALUE or BY CONTENT parameters, you need to tell the runtime.cobcall() method how to handle each parameter. This is done using an array of integers which is provided as an optional third parameter to the method. The values for the array are specified in the runtime class as constants that you can use in your program.

For example, for a COBOL Linkage Section and USING clause defined as follows:

Linkage Section. 01 A pic s9(4) comp-5. 01 B pic s9(9) comp-5. Procedure division using by value A

by reference B.

the usage type array would be created as follows:

int usages[] = {runtime.BY_VALUE, runtime.BY_REFERENCE};

This notifies the COBOL run-time system that the first parameter is to be handled BY VALUE and the second parameter is to be handled BY_REFERENCE.

Making the Call

All that needs to be done now is to make the call to the COBOL program, This is done using the method runtime.cobcall(). For example, the following code is used in the example program to call the COBOL entry point GetCategories:

Page 27: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 2 7 -

try { runtime.cobcall("GetCategories", params); } catch (Exception e) { // Handle any exception that occurred }

The name of the program or entry point being called is specified in the first parameter to runtime.cobcall(), in this case “GetCategories”. The second parameter is the object array containing the list of parameters for the COBOL program. In this case, all of the parameters are being passed BY REFERENCE, so an array of usage types does not need to be provided. If the parameters were not all defined as BY REFERENCE, then the array of usage types would be included as a third parameter. For example,

runtime.cobcall("program name", params, usages);

Handling Complex Types For most COBOL programs, the primitive data types listed earlier will not suffice. COBOL programs routinely require more complex parameters. This includes fixed length strings (defined as pic x(n)), the different numeric types supported by COBOL such as usage display, packed decimal, etc, as well as records and arrays.

Net Express 3.1 Service Pack 1 and updates to Server Express 2.0 introduced a basic, low-level mechanism that allows these complex data types to be handled. This is the definition of the Java interface DataType. Although this is a relatively simple interface, it provides the foundation for creating Java classes that can handle the automatic conversion of Java types to COBOL types and back to Java. Figure 4 shows the set of Java classes provided with the classified advertisements example program that accompanies this paper. Note that even abstract data types such as dates can be handled by a class that implements the interface DataType.

You are free to use these classes as provided or use them to form the basis of classes for your own application. However, these classes are provided as demonstrations only and are not supported by Micro Focus.

In Net Express 3.1 Service Pack 1, Micro Focus only provides the low-level mechanisms to enable you to implement classes that handle complex data types yourself. In future releases of Net Express, it is reasonable to assume that Micro Focus will include classes that provide this functionality. However, applications

Page 28: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 2 8 -

written using the current functionality will continue to work with future versions of Net Express.

Page 29: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 2 9 -

picX Handles parameters defined as pic X(n)

pic9 Handles parameters defined as pic 9(n)

picS9 Handles parameters defined as pic s9(n)

pic9v9 Handles parameters defined as pic 9(n)v9(m)

picS9v9 Handles parameters defined as pic s9(n)v9(m)

COBOLDate_YYYYMMDD Handles the automatic conversion of dates declared in Java using the class java.util.Date into an eight digit COBOL item in the form YYYYMMDD.

COBOLRecord Handles COBOL record parameters

COBOLArray Handles parameters that include an OCCURS clause

Figure 4 - The type conversion classes provided with the example program

The DataType Interface

The definition of the DataType interface is as follows:

package mfcobol.lang; public interface DataType { public abstract void synchronizeData() throws Exception; public abstract byte[] getBytes() throws Exception; }

Page 30: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 3 0 -

What this means is that any class that implements this interface must provide two functions - getBytes() and synchronizeData().

getBytes() is called by the COBOL run-time system whenever a class that implements the interface DataType is passed as a parameter to a COBOL program from a Java application. getBytes() is called by the COBOL run-time system just before the COBOL program is called to convert the data into a form that is suitable for COBOL and is defined to return an array of bytes. It is this array of bytes that is passed to the COBOL program.

On return from the COBOL program, the COBOL run-time system calls the synchronizeData() method to perform any conversion needed on the array of bytes to provide data back to the Java code.

Example

To show how the DataType interface can be used in practise, the following is the Java code that implements the picX class in the Classifieds Advertisements example program.

package com.microfocus.demo.coboltypes; import mfcobol.lang.*; public class picX implements DataType { private String picXContents; private int picXLength; private byte[] bytes; // Create an empty string with a COBOL picture of pic // x(length). public picX(int length) { picXContents = ""; picXLength = length; }

Page 31: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 3 1 -

// Create a string with a COBOL picture of pic // x(length) and initializes it to initialValue. If the // initial value provided is longer than the specified // length, the initial value is truncated. public picX(int length, String initialValue) { picXLength = length; if (initialValue.length() > picXLength) // Supplied value is longer than the string length, // so crop to the required size picXContents = initialValue.substring(0, picXLength); else picXContents = initialValue; } // Get the Java String representation of the string held // in the picX field. public String toString() { return (picXContents); } // Called by the COBOL run time system on entry to a // COBOL entry point to obtain the data to be moved into // the COBOL pic x(n) parameter. public byte[] getBytes() { StringBuffer stringContents = new StringBuffer(picXLength); int i = picXContents.length(); // Copy the current value if (i > 0) stringContents.replace(0, i, picXContents); // Space pad to the required length while (i < picXLength) { stringContents.append(' '); i++; } bytes = stringContents.toString().getBytes(); return bytes; }

Page 32: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 3 2 -

// Called by the COBOL run-time system prior to return // to Java. The contents of the pic x(n) field are // converted back to a Java string. Any trailing spaces // are removed. public void synchronizeData() { picXContents = new String(bytes, 0, picXLength); // Strip any trailing spaces if (picXContents.charAt(0) != ' ') picXContents = picXContents.trim(); else { // trim() cannot be used here since the COBOL // program returned a string with leading spaces. // trim() would also remove these spaces which // we do not want. while (picXContents.length() > 0 && picXContents.charAt(picXContents.length() – 1) == ' ') { picXContents = picXContents.substring(0, picXContents.length() – 1); } } } }

This class implements the interface DataType and, therefore, provides the two methods getBytes() and synchronizeData().

To see how this would be used, consider the following COBOL code in a program called prog.cbl:

linkage section. 01 A pic x(10). procedure division using A. display A move “xyz” to A exit program.

Page 33: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

This could be called from a Java program using:

String a = “abcdef”; picX picxA = new picX(10, a); Object params[] = {picxA}; runtime.cobcall(“prog”, params);

Figure 5 shows the sequence of events when the Java code calls the COBOL code.

Figure 5 – Java calls COBOL

When the Java program makes the call to runtime.cobcall(), the getBytes() method in the picxA instance of class picX is automatically called by the COBOL run-time system. This converts the value in the Java String class into an array of bytes that is padded with spaces to ensure it is ten bytes long since all COBOL strings are space terminated.

When the COBOL program returns to the Java program, the synchronizeData() method in the picxA instance of class picX is automatically called by the COBOL run-time system. It converts the modified byte array that now contains the characters x, y, z and seven spaces back into a Java string of length 3 that contains “xyz” (see Figure 6).

- 3 3 -

Page 34: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

Figure 6 – Return from the COBOL program

Other Examples

By examining the source code for the other classes provided in the Classified Advertisement example, you will see how these simple techniques can be extended to handle more complex types. For example, a COBOLRecord class is provided that allows record structures consisting of any number of fields to be passed to a COBOL program. In the classifieds advertisements example, the AdRecord and CategoryRecord classes are simply classes that inherit from the COBOLRecord class. The same techniques are used to handle the mapping of Java data types on to COBOL data where there is not a simple corresponding COBOL type. For example, the following class converts instances of the Java class java.util.Date into a COBOL record in the form:

01 COBOLDate. 03 Date-Year pic 9(4). 03 Date-Month pic 9(2). 03 Date-Day pic 9(2).

- 3 4 -

Page 35: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 3 5 -

package com.microfocus.demo.coboltypes; import mfcobol.lang.*; import java.util.*; import java.text.*; public class COBOLDate_YYYYMMDD implements DataType { private Date date; private byte[] bytes; // Create a representation of a date in COBOL YYYYMMDD // format. The field is initialized to today's date. public COBOLDate_YYYYMMDD() { // Use today's date date = new Date(); } // Create a representation of a date in COBOL YYYYMMDD // format, initializing to the specified date.. public COBOLDate_YYYYMMDD(Date newDate) { date = newDate; } // Retrieve the date public Date value() { return date; } // Called by the COBOL run-time system on entry to a // COBOL entry point to obtain the data to be moved into // the COBOL fields. public byte[] getBytes() { // First, create items to handle 4 and 2 byte numbers. // We will need these when converting the date fields DecimalFormat pic9_4 = new DecimalFormat("0000"); DecimalFormat pic9_2 = new DecimalFormat("00");

Page 36: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 3 6 -

// Create string buffers to hold the year, month and // day parts // // Note that type Date returns Year, Month and Date // values as follows: // // Year = Actual Year - 1900 // Month = Range 0 - 11 where January = 0 // Date = 1 - 31 // // So, we have to adjust the Year and Month // accordingly before passing them to COBOL StringBuffer tmpYear = pic9_4.format(date.getYear() + 1900, new StringBuffer(""), new FieldPosition(0)); StringBuffer tmpMonth = pic9_2.format(date.getMonth() + 1, new StringBuffer(""), new FieldPosition(0)); StringBuffer tmpDay = pic9_2.format(date.getDate(), new StringBuffer(""), new FieldPosition(0)); // Now return the complete string String tmpDate = tmpYear.toString() + tmpMonth.toString() + tmpDay.toString(); bytes = tmpDate.getBytes(); return bytes; } // Called by the COBOL run-time system prior to return // to Java. The contents of the COBOL fields are // converted back to a Java Date. public void synchronizeData() { // Note that we have to adjust the Year and Month // before passing back to Java (see comment in //getBytes() above). date = new Date( Integer.parseInt(new String(bytes, 0, 4)) - 1900, Integer.parseInt(new String(bytes, 4, 2)) - 1, Integer.parseInt(new String(bytes, 6, 2))); } }

Page 37: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 3 7 -

Putting it all Together The previous sections describe all you need to do to successfully call COBOL code from Java applications. The key points to remember are:

• Ensure that the COBOL program uses the multi-threaded run-time system and that it is thread-safe, most likely by using the REENTRANT(2) compiler directive.

• Create a Java wrapper class for the COBOL program, importing the package mfcobol.

• Use the runtime.cobload() method to load the COBOL program into memory

• For each parameter, create a new instance of an object, either using one of the wrapper classes for one of the Java primitive types or a class that implements the DataType interface.

• Create an object array containing the objects that represent each Parameter.

• If any of the parameters is passed BY VALUE or BY CONTENT, create an array of integers that specify the usage types for the parameters.

• Use the runtime.cobcall() method to call the COBOL program.

Page 38: Creating Application Using Java and Micro Focus COBOL … · With the introduction of Micro Focus Net Express 3.1 and Server Express 2.0, Micro Focus made the interfacing of Java

- 3 8 -

Conclusion

The ability for new applications being written in Java to be able to reuse existing COBOL code is becoming increasingly important. This paper shows the first steps Micro Focus has taken towards making this easier to do. The next paper in this series will show the problems introduced by moving to a web-based application using Java Server Pages and other Java 2 Enterprise Edition technologies. It will then demonstrate how the techniques introduced in this paper can be extended to overcome these problems and enable COBOL programs to be used in such applications.

About the author: Wayne Rippin is a self-employed consultant. Previously, he worked for Micro Focus for 16 years, first as a systems programmer and later as a product manager. His most recent role there was director of product management, leading a team of product managers responsible for Net Express, Mainframe Express and Unix compiler products.