Access CICS applications with Spring

JCA support provides the key to connection

Important enterprises currently have in their information systems many heterogeneous applications that must be integrated into newly developed applications. Some of these applications are developed on IBM technologies like Customer Information Control System (CICS) or IMS with the COBOL language. The J2EE Connector Architecture (JCA) specification addresses and unifies the way to communicate with these kinds of systems.

Some tools offer solutions for encapsulating all the JCA plumbing. Since version 1.2.1, Spring provides a lightweight and innovative solution for connectors using the CCI (Common Client Interface) API.

In this article, I show how to use Spring's JCA support with the IBM CICS JCA-compliant connectors to execute operations on a CICS system. First, I briefly describe JCA concepts and the main features supported in Spring. Then, I detail the global architecture to deploy to allow access to CICS with JCA. Finally, I show how to use Spring's JCA support to develop components based on CICS accesses, focusing on facilities described in this article.

J2EE Connector Architecture

JCA specifies how to access an EIS (enterprise information system) with Java. Currently, there are two versions of this specification:

  • Version 1.0: Only addresses outbound messaging with an EIS. It standardizes the interaction between the client and the connector, and the contracts between the connector and the provider, which offers pooling, transaction, and security services.
  • Version 1.5: Based on the previous version, it introduces inbound messaging to an EIS so the system can now call back the connector.

As the IBM CICS connectors used in this article are compliant with JCA 1.0, I do not describe features specific to version 1.5.

JCA 1.0 is divided into two main parts:

  • Interactions between the client and the connector: The connector implementation chooses the client API to use. It can be a dedicated one or the CCI API described in the JCA specification. For example, a JDBC (Java Database Connectivity) DataSource or a Hibernate SessionFactory can be exposed with a JCA connector.
  • Interactions between the connector and the service provider.

The IBM CICS connectors use the CCI API as the client. Its factory abstraction is the ConnectionFactory interface, which resembles the DataSource abstraction for JDBC. It allows the client application to create connections with the EIS. You can get the abstraction in one of two ways:

  • From the JNDI (Java Naming and Directory Interface) of an application server where the connector has been deployed. In this case, the connector can use its services (pooling, transaction, and security) and is used in a managed mode.
  • Directly from a configured instance of the connector's ManagedConnectionFactory interface implementation. In this case, the connector is used in a nonmanaged mode unless a ConnectionManager implementation is specified when creating the ConnectionFactory with the createConnectionFactory() method.

Listing 1 shows a typical execution of a request with the CCI API.

Listing 1. Example of a call with the CCI API

 1  ConnectionFactory connectionFactory=getConnectionFactory();
2  Connection connection=null;
3  Interaction interaction=null;
4  try {
5     connection=connectionFactory.getConnection();
6     interaction=connection.createInteraction();
7     InteractionSpec iSpec=createInteractionSpec();
8     Record inputRecord=createRecord();
9     populateInputRecord(inputRecord);
10    Record outputRecord=createRecord();
11    interaction.execute(iSpec,inputRecord,outputRecord);
12 } catch(ResourceException ex) {
13    // Manage the exceptions
14 } finally {
15    closeInteraction(interaction);
16    closeConnection(connection);
17 }

At Line 1, an instance of the ConnectionFactory interface is retrieved, depending on the strategy chosen. At Line 5, a connection with the EIS is created and then an interaction to execute operations. At Line 7, an instance of InteractionSpec is created to parameterize the operation, and then, at Lines 8 and 9, the input and output records are created to send and receive data from the EIS. At Line 11, the request is actually executed and the output record populated with the received data from the EIS. At Lines 15 and 16, the application must free all created resources whether exceptions occur or not.

There are two different signatures of the execute() method in the Interaction interface. You can either give the input and output records to the method or only pass the input record to the method, which returns the output record to the application. Generally, connectors support only one signature, and the other throws a NotSupportedException exception. In the previous example, I showed the first signature because the IBM CICS connectors support it.

Spring's JCA support

At this time, Spring's JCA support only addresses JCA's client portion and helps you use the CCI API. Nevertheless, a LocalConnectionFactoryBean class is provided to configure a connector in a nonmanaged mode. Moreover, the support can be used to configure a connector in a managed mode outside a J2EE application server by injecting an implementation of the ConnectionManager interface in the LocalConnectionFactoryBean class.

The JCA support resembles Spring's JDBC framework. Its first aim is to abstract the configuration of the factories used and to simplify the use of the CCI API to allow the developer to work only on the features specific to the application.

Figure 1 shows the different components of an application using JCA and their interactions both in managed and nonmanaged modes: the JCA-compliant connectors' resource adapters, the application server's services, the client API of the connector used, and Spring's JCA support.

Figure 1. Overview of Spring's JCA support. Click on thumbnail to view full-sized image.

Spring's JCA support has two features. The first addresses the connector's configuration. In a managed mode, the developer only has to point out the JNDI name that represents the ConnectionFactory and the connector is configured in the application server with Spring's JndiObjectFactoryBean class, as shown in Listing 2.

Listing 2. Configuration of a JCA ConnectionFactory in a managed mode with JNDI

 <bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
   <property name="jndiName"><value>eis/cicseci</value></property>

If you choose to use the connector in a nonmanaged mode, you must completely configure the connector in Spring with the ManagedConnectionFactory interface's connector implementation, as shown in Listing 3.

Listing 3. JCA ConnectionFactory configuration in a nonmanaged mode


<bean id="managedConnectionFactory" class=""> ... </bean>

<bean id="connectionFactory" class=""> <property name="managedConnectionFactory"> <ref local="managedConnectionFactory"/> </property> </bean>

The second feature of Spring's JCA support addresses the use of the CCI API, which hides the repetitive and error-prone code from the developer, who can now concentrate on these application-specific tasks:

  • Configure the EIS request with the InteractionSpec interface's connector implementation
  • Determine how to construct the input record from one or several parameters
  • Determine how to extract data from the output record and populate the returned object

Note that Spring still lets you work with CCI records explicitly if you need to.

To complete the above tasks, Spring's JCA support offers two approaches:

  • The template-based approach: The application must use the CciTemplate class to execute requests on the EIS and can configure each call with creator and extractor callback interfaces, which are passed to its methods.
  • The object-based approach: The application must construct the operation as an object by inheriting the MappingRecordOperation abstract class. Spring's JCA support also offers the MappingCommAreaOperation subclass for operations based on a commarea, like CICS.

Listing 4 shows the same code from Listing 1 using the template-based approach:

Listing 4. Use of the template-based approach

 1  ECIInteractionSpec interactionSpec=new ECIInteractionSpec();
2  interactionSpec.setFunctionName("LOGIPROG");
3  interactionSpec.setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);
5  getCciTemplate().execute(interactionSpec,new RecordCreator() {
6     public Record createRecord(RecordFactory recordFactory)
7                      throws ResourceException, DataAccessException {
8        // Create the record with the parameters
9     }
10 },new RecordExtractor() {
11    public Object extractData(Record record) throws ResourceException,
12                                     SQLException, DataAccessException {
13       // Extract the data from the record
14    }
15 });

Listing 5 shows the object-based approach.

Listing 5. Operation using the object-based approach

 1  public abstract class ECIMappingOperation extends MappingRecordOperation {
2     public ECIMappingQuery(ConnectionFactory connectionFactory,String programName) {
3        setConnectionFactory(connectionFactory);
4        ECIInteractionSpec interactionSpec=new ECIInteractionSpec();
5        //Initialize the interaction spec
6        setInteractionSpec(interactionSpec);
7        setOutputRecordCreator(new ECIOutputRecordCreator());
8     }
10    private class ECIOutputRecordCreator implements RecordCreator {
11       public Record createRecord(RecordFactory recordFactory)
12                                  throws ResourceException, DataAccessException {
13          // Returns a Record that will be used for output
14       }
15    }
16 }

Listing 6 shows the use of the operation object created in Listing 5.

Listing 6. Use of the operation object

 1  ECIMappingOperation query=new ECIMappingQuery(getConnectionFactory(),"LOGIPROG") {
2     protected Record createInputRecord(RecordFactory recordFactory,
3               Object inputObject) throws ResourceException, DataAccessException {
4        // Create the record with the parameters
5     }
7     protected Object extractOutputData(Record outputRecord)
8                      throws ResourceException, SQLException, DataAccessException {
9        // Extract the data from the record
10    }
11 });
12 return query.execute(input);

I now describe a concrete example of how to use Spring's JCA support with CICS connectors.

CICS architecture and configuration

The architecture and required applications for accessing a CICS are shown in Figure 2.

Figure 2. Overview of the global architecture (CICS and J2EE). Click on thumbnail to view full-sized image.

Figure 2 shows that CICS allows access to different resources:

  • Transaction: Represents 3270 screens and is based on a presentation program that knows how to interact with these screens. This kind of program can call some business logic program to display the data. With CICS, the interface to access transactions is EPI (external presentation interface).
  • Program: Carries out treatments. Note that programs implementing transactions cannot be called directly. Only commarea-based programs can. With CICS, the interface to access transactions is ECI (external call interface).

Figure 2 also emphasizes that a TCP62 listener must be configured on CICS to allow the remote clients to communicate with it using this protocol. In addition, the IBM CICS connectors are based on CICS Transaction Gateway, which can be used in a gateway mode or directly as a CICS client. These connectors are wrappers upon the CTG API that support both ECI and EPI calls. The CTG offers a level of indirection between the J2EE application and the CICS. As a matter of fact, it defines logical names for every CICS, which are used by clients instead of real CICS names. Finally, in Figure 2, we can see that the client part of the IBM CICS connectors is CCI-based; thus, Spring's JCA support can be used for this kind of connector.

As the messages exchanged with CICS programs are based on a commarea (a byte array that represents both the request data sent to the program and the response data received from it), the JCA record must too be based on a byte array representing this commarea. Spring's JCA support provides a dedicated record implementation (the CommAreaRecord class).

In the following section, I show the connector's configuration and how to call a CICS program with Spring's JCA.

Access a CICS program

To begin, configure the IBM CICS ECI connector either in an application server or in Spring, depending on the mode chosen. Note that the use of XA transactions are not allowed in a nonmanaged mode, but, in our case, that is not a problem because the connector used only supports local transactions.

In this article, we configure in a nonmanaged mode. For the managed mode, please refer to your application server's documentation to see how to import and configure a JCA-compliant connector.

As described previously, the configuration is completed using the connector's ManagedConnectionFactory interface implementation. For the IBM CICS ECI connector, the parameters are:

1 2 Page 1
Page 1 of 2