The JCA local ECI feature provides an optimized JCA adapter supporting the CICS Transaction Gateway JCA ECI interfaces. This allows you to port existing JCA applications that use the JCA ECI interfaces from other JEE applications servers into the a CICS Liberty JVM server, and to developed new JEE applications that can link to existing CICS COBOL programs without being tied to the proprietary JCICS Java API.

Introduction

In the March CICS TS 5.3 Open Beta we announced support for JCA 1.6 in CICS Liberty JVM servers, this allowed applications using the CICS TG ECI resource adapter to be run inside CICS. However, these applications still had to go outside of CICS via CICS TG to call a CICS program, which is not an optimal solution.

Calling a CICS program using the ECI resource adapter
The architecture using the CICS TG ECI resource adapter

Since then we’ve been working with CICS TG on creating a resource adapter which keeps the same API as the ECI resource adapter, but which uses CICS APIs instead of CICS TG to perform a locally optimised call to a CICS program: the JCA Local ECI resource adapter.

image

The architecture using the CICS Local ECI feature

The JCA Local ECI resource adapter provides benefits to new applications as well as existing ones: it doesn't require JCICS, so applications can be made to be portable between CICS and distributed system and it provides optimisations for creating multiple containers in a channel on a program call.

Installation

The JCA Local ECI feature comes installed on all CICS TS 5.3 Liberty JVM servers. To enable the feature, edit the Liberty JVM servers server.xml to include the following feature cicsts:jcaLocalEci-1.0 in the feature manager element as shown in figure 1.

Figure 1: server.xml snippet to include the JCA Local ECI feature

<server>
    <featureManager>
        <!-- Other features -->
        <feature>cicsts:jcaLocalEci-1.0</feature>
    </featureManager>

    <!-- Other content of the server.xml -->
</server>

Consolidating an existing application

Consolidating an existing Java EE application into a CICS Liberty JVM server is a 6 step process, which can be easily performed using CICS Explorer

  1. If possible, update the JNDI name of the ConnectionFactory to eis/defaultCICSConnectionFactory. If this is not possible, define a new ConnectionFactory with the required JNDI name in server.xml, see figure 2 for details.
  2. Create a new CICS bundle.
  3. Add the existing application to the CICS bundle, target the Liberty JVM server you want to deploy the application too.
  4. Export the CICS bundle to z/FS.
  5. Create a new CICS bundle definition on the CICS region, targeting the location the of the exported bundle on z/FS.
  6. Install the bundle.

To ensure the application is correctly installed, view the Liberty JVM servers messages.log file. A message should appear the the application has been enabled and the URL path to the root of that application.

There are some differences that owners of existing applications should be aware of in an environment which is local to CICS:

  1. If the CICS program that is linked to issues a SYNCPOINT command then this will commit the CICS UOW, which is only possible if CICS is the transaction coordinator. If the Java web application has initiated a Java transaction using the UserTransation class then the CICS UOW will be subordinate to the Java transaction which is controlled by the Liberty transaction manager. In this case the CICS task will not be permitted to issue a CICS SYNCPOINT, either using an EXEC CICS SYNCPOINT command in a called program or a Task.commit() method using the JCICS API. Instead the Java transaction must user the UserTranaction.commit() or rollback() methods to control the transactional scope. However, if there is no Java transaction created by the web application then the LINKed to program will be able to issue a SYNCPOINT, and further if the linked to program is defined as remote it will be invoked using the SYNCONRETURN option allowing the programs linked to via a DPL to also issue a SYNCPOINT as they will run in a separate UOW to that of the calling program.
  2. Setting the transaction ID using the EciInteractionSpec.setTPNNanme() method to set the name of the mirror transaction only functions on a call to a remote program, and will set the name of the mirror transaction alias that will be used. If you need to modify the transaction name under which a Liberty web application runs then this requires usage of a URIMAP resource definition with the USAGE attribute set to JVMSERVER.

Figure 2: server.xml snippet to create another ConnectionFactory with a different JNDI name

<server>
    <!-- Other contents of the server.xml -->
    <connectionFactory id="jcaLocalEciConnectionFactory" jndiName="eis/ECI">
        <properties.com.ibm.cics.wlp.jca.local.eci/>
    </connectionFactory>
</server>

Creating a new application using the JCA Local ECI feature

Creating a new application which uses the JCA Local ECI feature is easily done using CICS Explorer and WebSphere Development Tools. This post will show how to create a basic web application (WAR), but the JCA Local ECI feature can be used in Enterprise Bundle applications (EBA).

  1. Create a new Dynamic Web Project
  2. Create a new Web Servlet
  3. In the one of the inherited do methods, use JNDI to look up the ConnectionFactory object
@Resource("eis/defaultCICSConnectionFactory")
ConnectionFactory factory;
  1. Create a Connection object from the ConnectionFactory.
Connection conn = factory.getConnection();
  1. Create an Interaction object from the Connection.
Interaction interaction = conn.createInteraction();
  1. Create a new ECIInteractionSpec object and configure properties on this object.
ECIInteractionSpec spec = new ECIInteractionSpec();
spec.setFunctionName("SAMPLPROG");
  1. Create Record objects for the input and output of the program call.
RecordImpl input = new RecordImpl(); RecordImpl output = new RecordImpl();
  1. Call the execute method on the Interaction object, passing in the ECIInteractionSpec and Record objects created.
interaction.execute(spec, input, output);
  1. Read the output from the output Record.

ABENDs in CICS will be wrapped in a Java ResourceException and the resource adapter will provide sensible error messages. More detailed information can be found in the JVM server's messages log file and STDERR.

An simple servlet example that uses the CICS ECI resource is available in this CICSDev GitHub repository

Using the optimised channel and container support

The Local ECI resource adapter provides a simple mechanism of creating CICS channels and containers to pass to the CICS program. A special class EciChannelRecord can be created to represent a channel; this class extends the MappedRecord class (and through inheritance the standard Java Map class). Each record in this class represents a container, where the key of the record is the name of the container and the value is the contents of that container.

The data type of the value changes the mode of the container. For a container in BIT mode, a type of byte[] must be provided and for a container in CHAR mode, a type of String must be provided.

byte[] bitModeData = new byte[]{ 0x42, 0x11, 0x00 };
String charModeData = "Hello CICS";
EciChannelRecord channel = new EciChannelRecord("CHANNEL");
channel.put("BITCONTAINER", bitModeData);
channel.put("CHARCONTAINER", charModeData);

Using this method of calling CICS programs with channels and containers has another advantage: rather than creating individual containers in the channel as they are populated, the Local ECI resource adapter uses the object representation of a channel to create the containers in a single batch just before control is passed to the CICS program, keeping the Java code in the JVM for as long as possible.

Final thoughts

This blog post has described how to consolidate an existing Java EE application which used the CICS TG ECI resource adapter to communicate with CICS into a CICS Liberty JVM server and how to create a new application which uses the JCA Local ECI feature. It has also explained how the JCA Local ECI feature can be used to call CICS programs with a channel using simple Java objects, rather than relying on JCICS classes, allowing applications to be portable between CICS Liberty JVM servers and distributed application servers.

References and useful links

Join The Discussion

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