Have you ever wanted to reuse some existing Java EE code as part of a CICS application? Or perhaps you need to implement a new application feature, leveraging Java EE APIs from a COBOL program. Now you can, with the latest continuous delivery update to CICS TS V5.3. In this article we’ll look at how you can prepare your Java EE application, running in a Liberty JVM server, to be invoked from any CICS program.

There’s a few things you should bear in mind when deciding if this capability is suitable for your project. Firstly, your Java code must currently be a POJO (Plain Old Java Object), packaged in WAR or an EAR. It only really makes sense to call Java code that implements business logic, rather than web layers such as servlets or JAX-RS resource classes. You can invoke your Java code as the initial program of a transaction, as well as using the EXEC CICS LINK, START and START CHANNEL APIs. If you want to call an EJB, for now you’ll need to a create a POJO wrapper that CICS can call. If you’re porting an application from an OSGi JVM server, you’ll need to modify it a bit. You’ll need to update the signature, and use channels and containers instead of a COMMAREA. You’ll also need to package it as a POJO in WAR, as calling OSGi bundles isn’t currently supported in Liberty.

When it comes to transactions, you’ll be pleased to hear that the Java code will be invoked on the same CICS task and in the same unit-of-work (UOW) as the calling application. This means you can make recoverable updates to CICS resources from both the calling program, and using the JCICS API in the target Java program.

Note with the removal of the DPL subset restriction in APAR PI98229 it is now possible for the linked to Java program to issue SYNCPOINT commands. This has the added benefit that the Java program can be invoked using a DPL with the SYNCONRETURN option and can also use the Java Transaction API (JTA)to start a new UOW and coordinate updates to a JDBC DataSource using type 4 connectivity.

First steps

First of all, you’ll need to get hold of the PTFs for APAR PI63005 and apply them to your CICS TS V5.3 system. Or alternatively, grab the latest version of the CICS TS V5.4 Open Beta. You’ll also need to update CICS Explorer to version 5.3.0.8 or the latest open beta level. If you’re using the CICS build toolkit, that’s also available as part of 5.3.0.8 or beta releases. You can download the CICS Build Toolkit here.

Next you’ll need a Liberty JVM server. See Configuring a Liberty JVM server for details of how to set this up. You’ll also need to add <feature>cicsts:link-1.0</feature> to the featureManager tag in server.xml. Then you can ENABLE the JVMSERVER resource.

Preparing your Java code

We’ve tried to make it as simple as possible to get your Java code ready for another CICS program to call. We’d suggest creating a wrapper class for your business logic, so you can keep the CICS-specific code separate. Then all you need to do is add the @CICSProgram annotation to the method you would like CICS to call. We hope annotations will be a familiar construct to most Java developers already, and they’re especially prevalent in Java EE. Using the annotation means CICS can easily spot which methods you expose at build time, and generate some artifacts that will help us make the call at runtime. CICS will even create a PROGRAM resource for you dynamically, using the name you supply as a parameter to the annotation.

If you want to use the example projects discussed in the article, you can download the finished projects as a zip file and import them into CICS Explorer by using File -> Import -> General -> Existing projects into workspace and clicking the ‘Select archive file’ option. They’ll soon been available directly in CICS Explorer as well. Otherwise you’ll need to put your code in a Dynamic Web Project.

So here’s our Java code:

 

public class HelloLiberty 
{
    @CICSProgram("HELLOWLP")
    public void printMessage() 
    {
        StringBuilder sb = new StringBuilder();
        sb.append("Hello ");
        try 
        {
            Channel currentChannel = Task.getTask().getCurrentChannel();
            if (currentChannel != null && currentChannel.getContainer("NAME") != null) 
            {
                Container nameContainer = currentChannel.getContainer("NAME");
                sb.append(nameContainer.getString());
            } 
             else 
            {
                sb.append(Task.getTask().getUSERID().trim());
            }
            sb.append(" from Liberty server ");
            sb.append(System.getProperty("com.ibm.cics.jvmserver.wlp.server.name"));
            System.out.println(sb.toString());
        } catch (InvalidRequestException | ContainerErrorException
				| ChannelErrorException | CCSIDErrorException
				| CodePageErrorException e) 
        {
            e.printStackTrace();
            Task.getTask().abend("OHNO");
        }
    }
}

You’ll notice the @CICSProgram annotation on the printMessage() method. This names the CICS PROGRAM resource that can be used to invoke the method, HELLOWLP in this case. You can annotate as many methods as you like, as long as they all have distinct program names. If you haven’t used any annotations in this particular project before, you’ll need to enable annotation processing. You can do this by hovering over the warning on the annotation and using the provided quick fix.

Hover over a warning on the @CICSProgram annotation to display the quick fix
Enabling annotation processing on your web project by using the quick fix

Looking at the code in the printMessage() method, you’ll see the first thing we do is get hold of the current channel. We then get a container from the channel, which contains our input data. Using channels and containers is the primary method for passing data between your Java code and the calling CICS program. In this example, all we’re passing is a simple string. However, if the calling program passes a piece of structured data consisting of several fields, you’ll need to convert this into Java-friendly data types and objects. Refer to the following articles for details of how to generate this data conversion code using two alternative tools: IBM Record Generator for Java and Rational J2C tools

Once we’ve obtained data from the calling program, we’re ready to perform whatever business logic function our Java code will implement. This will likely involve invoking methods on other Java objects, and interacting with CICS resources using the JCICS API. We can then reverse the data transformation process, and put any output parameters in containers on the channel. If an Exception is thrown, we have several choices. We can choose to allow the Exception to percolate up the stack, which will cause the task to terminate with an AJ05 abend. Alternatively, we can catch the Exception and handle it ourselves, perhaps by returning an error code to the calling program, or by abending the task as we’ve done in the example code.

Deploying the application

You’re now ready to deploy the application. You can use any supported method to deploy the application into the Liberty JVM server, such as a CICS bundle, coding an application element in server.xml, or using the dropins folder in a development scenario. In this case we’ll describe using a CICS bundle. You’ll need to either create a new CICS bundle project or update an existing one.

You can add then a “Dynamic Web Project Include”, referring to our web project, and naming the JVM server we’ll be deploying to. If you’re using the example projects, a CICS bundle project with the include is provided, so you’ll just need to change the JVM server name (in the com.ibm.cics.server.examples.wlp.link.warbundle file) to match yours. You can then deploy the bundle project by selecting “Export Bundle Project to z/OS Unix File System” from the context menu. Next you’ll need to create a BUNDLE resource in CICS, and point to the zFS location where you deployed the bundle project. You can then install the BUNDLE.

Use the New Dynaimc Web Project Include wizard to select the web project and specify the JVMSERVER name
Creating an include for a Dynamic Web Project

When the CICS bundle is ENABLED, the web application gets installed in to Liberty. This triggers CICS to examine the WAR and spot the artifacts generated by the annotation processor as a result of the @CICSProgram annotation. CICS dynamically creates a PROGRAM resource for each annotated method. You can find these using the PROGRAMs view in the CICS Explorer, filtering on the name of the JVM server.

Using the Programs view in CICS Explorer to show dynamically created PROGRAMs
Using the Programs view in CICS Explorer to show dynamically created PROGRAMs

While we hope you will find the dynamically created PROGRAMs convenient, it is also possible to define and install them yourself if need be. If a PROGRAM with the same name is already installed at the point when the Liberty application is enabled, CICS won’t try to create one. Instead it will validate that the attributes of the PROGRAM are suitable and emit a warning to MSGUSR if not.

Trying out the sample

If you’ve deployed the sample. you’ll now be able to try it out. You can use CECI to invoke the PROGRAM:

CECI LINK PROG(HELLOWLP)

and then look in the JVM server’s STDOUT for the message:

Hello WILSON from Liberty server defaultServer

(where WILSON is my CICS user ID).

If you put a container called NAME on the channel and link with that channel like this:

CECI PUT CONTAINER(NAME) CHAR FROM(MATTHEW) CHANNEL(CHAN)

CECI LINK PROG(HELLOWLP) CHANNEL(CHAN)

you should see the contents of the NAME container in the output message

Hello MATTHEW from Liberty server defaultServer

Hopefully you’ve now learned enough to give it a try for yourself. If you need further information, see Invoking a Java EE application from a CICS program.


Change history

04/Sept/18 – Updated to reflect removal of DPL subset restrictions

6 comments on"Link to Liberty now available in CICS TS V5.3"

  1. Hi Matthew
    Is there a way I can run it in my CICS TS 5.2.

    • Matthew Wilson November 18, 2016

      Hi Prabhat,
      No, unfortunately CICS TS V5.3 is required. There are no plans to make this capability available on V5.2, as a lot of the underpinning technology is only in V5.3.

  2. Andy Armstrong November 22, 2016

    Brilliant article @Matthew — brilliant feature.

  3. Anubhuti Kaushik December 28, 2016

    Excellent feature. You have explained it really well.

  4. I tried this for a dropins application but it didn’t work. So I checked with Hursley team and get a guide.
    —–
    You need to locate the annotation processing jar that CICS provides in it’s USS home directory (/lib),
    then turn on annotation processing in Eclipse for that particular project
    Once it’s turned on, the CICS hooks should trigger and the PROGRAM definition should get generated.
    – add com.ibm.cics.server.invocation.annotations.jar to their project’s build path (this provides the actual @CICSProgram annotation)
    – set com.ibm.cics.server.invocation.binding.jar as an annotation processor (in project properties -> Java compiler -> Annotation processing -> Factory Path -> Add external JAR)
    —–
    Then, it worked!!! Thank you Michael and team!!

    Two more tips : (1) If you turn on the program autoinstall, don’t try this before the annotation processing. Your link request can also create a program definition without JVM and class path values. (2) Commare doesn’t work for this annotated program.

    • Matthew Wilson May 11, 2017

      Thanks SS. Just to note that if you’re using CICS Explorer, you don’t need to manually the annotation processor to the project. In this case I understand you were using plain Eclipse, so this was the solution.

Join The Discussion

Your email address will not be published. Required fields are marked *