Running CICS-Java application - (5) Using JCICSX

This article is translated from the Japanese article below.
https://qiita.com/tomotagwork/items/cac290f6435453c19b7b
([google translate](https://translate.google.com/) was used.)

# Introduction
CICS Transaction Server provides a class library called JCICS for using CICS functions from Java. This is the Java version of EXEC CICS API, which allows you to call other CICS programs with LINK and access CICS management resources such as TSQ/TDQ. By using this, you can write a CICS application in Java.
Shipped on 06/12/2020, CICS TS V5.6 now offers a new CICS API for Java called JCICSX, which is an extension of JCICS. Here, I will describe a series of flow when I tried to move the JCICSX.

## Related articles
[Running CICS-Java application - (1) Simple application](https://qiita.com/tomotagwork/items/b3c48da38925e7acd98c)
[Running CICS-Java application - (2) Build management with Maven](https://qiita.com/tomotagwork/items/16cbf233152cf64b42f4)
[Running CICS-Java application - (3) Build management with Gradle](https://qiita.com/tomotagwork/items/347283447a575c44c242)
[Running CICS-Java application - (4) Spring Boot Application](https://qiita.com/tomotagwork/items/bace965b77567146b7dc)
[Running CICS-Java application - (5) Using JCICSX](https://qiita.com/tomotagwork/items/7f93a23c7cca38287a11)

# Environment
**Development Environment**
Windows10

**Runtime Environment**
z/OS V2.4
CICS Transaction Server for z/OS V5.6

# Overview of JCICSX
The position of "class library for using CICS functions from Java", that is "Java version of EXEC CICS API" is the same for both JCICS and JCICSX.
What's different is that JCICSX is an API that has been extended to make it easier to test on your local PC (in the development environment).
In addition, JCICS supports a wide range of functions equivalent to EXEC CICS, but JCICSX is still limited and provides only Channel & Container and Link-related functions.
Reference:
[JCICS Javadoc](https://www.ibm.com/docs/en/cics-ts/5.6?topic=development-jcics-javadoc)
[JCICSX Javadoc](https://www.ibm.com/docs/en/cics-ts/5.6?topic=development-jcicsx-javadoc)

"Easy to test on a local PC (development environment)" has the following two points.

(1) Unit testing is possible using the testing framework
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/423a73f7-0bb1-5d6e-7b28-4b4f9d752491.png)

Of course, there is no CICS runtime on the local PC, so the CICS-dependent code (JCICSX part) cannot be executed as it is. When unit testing a module containing environment-dependent code such as DB access, there is a framework (Mockito etc.) that handles the external resource access part as a Mock, but it is said that it will also be applied to the CICS access part. (I think this is mainly due to the features provided by frameworks such as Mockito.)

(2) Unit test can be performe on the Liberty server on the PC
This is the main extension function of CICS, but we provide a mechanism to check the operation of JCICSX with Liberty on the local PC (in the development environment). The image is as follows.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/f2bd38d4-b901-9d7e-8bbe-f01bc3ecef16.png)

This mechanism is called "remote development". Prepare Liberty on the PC and CICS-Liberty for the development environment, and configure the features for JCICSX remote development respectively. With this configuration, Liberty on the local PC behaves as if it were running on CICS. Therefore, it is not necessary to deploy the application on the host side and check the operation every time when trying & error or testing, and you can run a detailed cycle of operation check and correction on the local PC.
Once the code is finally solidified, it can be deployed and run in the real CICS-Liberty environment for test / production.

In other words, it is convenient to use JCICSX when creating a Liberty application that passes data with Channel & Container and calls an existing application with Link (LINK passed with COMMAREA is not possible).

The following describes the configuration procedure for testing JCICSX on the Liberty server on your PC.

# CICS-Liberty Remote Development Configuration
Reference:  [Configuring the environment for JCICSX](https://www.ibm.com/docs/en/cics-ts/5.6?topic=applications-java-development-using-jcicsx#jcicsx-api__configure)

## CICS-Liberty side (server-side) configuration

### JVM Profile
Prepare the JVM profile on USS. (Properties for the JVMServer are effectively specified in a file on this USS. The JVMSERVER resource definition points to the filename of this JVM profile.)
A sample is provided, so copy it and use it.

Create a directory `/var/cicsts/cicsts56/CT56B4A1/JVMProfiles` and copy `/usr/lpp/cicsts/cicsts56/JVMProfiles/DFHWLP.jvmprofile`(sample definition for Liberty located under the CICS installation directory) to it. Customize as appropriate for your environment.

```xxx:DFHWLPX.jvmprofile
JAVA_HOME=/usr/lpp/java/J8.0_64/
WORK_DIR=/var/cicsts/cicsts56/CT56B4A1/work
WLP_INSTALL_DIR=/usr/lpp/cicsts/cicsts56/wlp
-Dcom.ibm.cics.jvmserver.wlp.autoconfigure=true
-Dcom.ibm.cics.jvmserver.wlp.server.host=*
-Dcom.ibm.cics.jvmserver.wlp.server.http.port=56461
-Dcom.ibm.cics.jvmserver.wlp.server.https.port=56471
-Xms128M
-Xmx256M
-Xmso1M
-Xgcpolicy:gencon
-Xscmx256M
-Xshareclasses:name=cicsts%g,groupAccess,nonfatal
-Xtune:virtualized
-Dcom.ibm.tools.attach.enable=no
-Dfile.encoding=ISO-8859-1
_BPXK_DISABLE_SHLIB=YES
```

### SIT
Specify the directory where the above properties file is located in the SIT parameter "JVMPROFILEDIR".

```
JVMPROFILEDIR=/var/cicsts/cicsts56/CT56B4A1/JVMProfiles 
```

Restart the region for the changes to be enabled.

### JVMServer definition

Prepare the JVMSERVER resource definition.
Copy the JVMSERVER definition "DFHWLP" in the product-provided DFH$WLP group to an appropriate group with the name "DFHWLPX" and customize it.

```
OBJECT CHARACTERISTICS                                    CICS RELEASE = 0730 
 CEDA  View JVmserver( DFHWLPX  )                                             
  JVmserver      : DFHWLPX                                                    
  Group          : TAGGRP                                                     
  DEScription    : CICS JVM server to run WLP samples                         
  Status         : Enabled            Enabled | Disabled                      
  Jvmprofile     : DFHWLPX                                        (Mixed Case)
  Lerunopts      : DFHAXRO                                                    
  Threadlimit    : 015                1-256                                   
 DEFINITION SIGNATURE                                                         
  DEFinetime     : 08/07/20 17:01:19                                          
  CHANGETime     : 08/07/20 17:01:36                                          
  CHANGEUsrid    : CICSUSER                                                   
  CHANGEAGEnt    : CSDApi             CSDApi | CSDBatch                       
  CHANGEAGRel    : 0730                                                                                                                    
```

*Jvmprofile: DFHWLPX, which means that the file DFHWLPX.jvmprofile under the directory specified in JVMPROFILEDIR of SIT is used as the JVM property file.
Install this JVMSERVER once.
It is OK if it is enabled by checking with `CEMT I JVMSERVER`.

```
I JVMS                                                
STATUS:  RESULTS - OVERTYPE TO MODIFY                 
 Jvm(DFHWLPX ) Ena     Prf(DFHWLPX ) Ler(DFHAXRO )    
    Threadc(012) Threadl( 015 ) Cur(65873224)              
```

### JCICSX feature / server-side configuration

Since "com.ibm.cics.jvmserver.wlp.autoconfigure=true" is specified in the JVM Profile, Liberty is automatically configured when the JVM Server is installed.

`<WORK_DIR>/CT56B4A1/DFHWLPX/wlp/usr/servers/defaultServer/server.xml` has been created, so edit it.
Add a feature `cicsts:jcicsxServer-1.0` as follows:

```xml:server.xml
...
    <featureManager>
        <feature>cicsts:core-1.0</feature>
        <feature>cicsts:defaultApp-1.0</feature>
        <feature>jsp-2.3</feature>
        <feature>wab-1.0</feature>
        <feature>transportSecurity-1.0</feature>
        <feature>cicsts:jcicsxServer-1.0</feature>
    </featureManager>
...
```

When you restart the JVM Server, you can see the following log as the Liberty startup message.(`<WORK_DIR\>/CT56B4A1/DFHWLPX/wlp/usr/servers/defaultServer/logs/messages.log`)

```log:messages.log
...
[8/7/20 8:13:40:387 GMT] 00000050 com.ibm.ws.webcontainer.osgi.webapp.WebGroup                 I SRVE0169I: Loading Web Module: com.ibm.cics.wlp.jcicsxserver.
[8/7/20 8:13:40:387 GMT] 00000050 com.ibm.ws.webcontainer                                      I SRVE0250I: Web Module com.ibm.cics.wlp.jcicsxserver has been bound to default_host.
[8/7/20 8:13:40:387 GMT] 00000050 com.ibm.ws.http.internal.VirtualHostImpl                     A CWWKT0016I: Web application available (default_host): http://xx.xx.xx:56461/jcicsxServer/
...
```

The URL shown here is used in the Liberty configuration on the client-side.

## Liberty on local PC (client-side) configuration

### Install Eclipse/Liberty
Set up the Eclipse environment on Windows 10 and install Liberty.
Please refer to appropriate document for this.

### Add JCICSX related feature
Double-click the target Liberty feature manager in Eclipse server view to open server.xml and click Add to the right of the feature list
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/164b017c-6294-14e4-75a1-dce12d563b86.png)

Click "Install additional features"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/a5a43339-a25e-866e-94c0-2bbc6ad25faa.png)

If you specify "JCICS" for the filter, the JCICSX development feature for Java will be listed. Click "Install" and "Next".
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/efbaea96-1da3-40db-680e-9d4441c71116.png)

Confirm license and Finish.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/b01a81a9-6ef4-c922-17ee-62cb10eae272.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/f3213b4c-0739-277c-71df-e0de318d8042.png)

Now that the feature is installed, select `usr:jcicsxClient-1.0`, which is filtered by jcicsx and displayed.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/65db0d50-b33f-2150-ca1f-114bd02b1d9c.png)

Added as a feature.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/1c8f0536-e3bb-c5da-e165-1a9b0449ba06.png)

Looking at the source of server.xml, it looks like this.

```xml:server.xml
    <featureManager>
        <feature>jsp-2.3</feature>
        <feature>localConnector-1.0</feature>
    	<feature>servlet-3.1</feature>
		<feature>jca-1.7</feature>
		<feature>jndi-1.0</feature>
		<feature>ejb-3.2</feature>
		<feature>usr:jcicsxClient-1.0</feature>
	</featureManager>
...
```

### JCICSX feature / client-side configuration

Edit server.xml and add the following settings.

```xml:server.xml
...
    <!-- JCICSX Client Config -->
    <usr_jcicsxClient serverUri="http://etp1:56461"/>
...
```

The serverUri address and port are CICS-Liberty endpoints configured for the JCICSX server.
If you look at server.xml in Design view, it will look like this:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/37063f46-e997-faf6-e90f-4e9063a8618e.png)

This completes the "remote development" configuration.

# Developing applications on a local PC using JCICSX

## JCICSX development environment maintenance

There are several ways to provide the JCICSX class library, and it is also included in the CICS SDK for Java in CICS Explorer. If you incorporate the CICS Explorer function into Eclipse, it will be easier to manage, so we will include CICS Explorer in the Eclipse environment.

Reference: [Downloading and starting CICS Explorer](https://www.ibm.com/docs/en/cics-explorer/5.5.0?topic=downloading-starting-cics-explorer)

Select "Help" - "Install New Software" from the Eclipse menu
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/496cca20-bc3e-da4c-92cb-207ae97e0e6f.png)

Press "Add" button to add the following repositories.
「https://public.dhe.ibm.com/ibmdl/export/pub/software/htp/zos/tools/aqua3.2/ 」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/066a6e93-edd8-f42a-eef3-4ad34e782255.png)

Select "IBM CICS Explorer" and Next
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/2eae14c9-5d76-55ac-4c8b-abf6473f61bf.png)

"Next"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/207c1cf3-76e3-cacc-556d-3546eebc5a2e.png)

Confirm license and Finish.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/0bd701e3-70c5-39d5-baa4-3d6d563c6066.png)

It takes a long time to install. This kind of confirmation about certification may appear on the way, so take appropriate action.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/6d10e2ad-1c31-ee36-563b-efd1c5f9a278.png)

When it is completed, a pop-up prompting you to restart will appear, so restart Eclipse.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/96ee3bdc-3ab7-1f17-a257-1850fe68ad7a.png)

The CICS Explorer feature is now built into Eclipse.

## Import sample application
Here, I will try running the sample provided on GitHub.
[GitHub: cics-java-jcicsx-samples](https://github.com/cicsdev/cics-java-jcicsx-samples)
Clone locally.

```
c:\y\workspace\cicsts56>git clone https://github.com/cicsdev/cics-java-jcicsx-samples.git
Cloning into 'cics-java-jcicsx-samples'...
remote: Enumerating objects: 361, done.
remote: Counting objects: 100% (361/361), done.
remote: Compressing objects: 100% (157/157), done.
Receiving objects:  76% (275/361)   ed 350 (delta 137), pack-reused 0
Receiving objects: 100% (361/361), 97.91 KiB | 331.00 KiB/s, done.
Resolving deltas: 100% (145/145), done.
```

Of the several samples, import "char-link-program-sample" into Eclipse.

Right click on Enterprise Explorer view in JavaEE perspective, Select "Import"
"Maven" -"Existing Maven projects"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1424383/b9de234a-e164-89da-5dfe-3b32f4fc484a.png)

Select "char-link-program-sample" under the cloned directory
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/499163cb-9fea-0875-f330-344f7e860242.png)


The project has been created.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/0e16eb1a-9e21-e6de-3f94-cfe8bd7c2640.png)

## Check the contents

Let's take a look at pom.xml.

```xml:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.ibm.cics</groupId>
  <artifactId>char-link-program-sample</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.annotation</groupId>
      <artifactId>jsr250-api</artifactId>
      <version>1.0</version>
      <scope>provided</scope>
    </dependency>

    <!-- JCICSX dependency, used in CharLinkServlet.java -->
    <dependency>
      <groupId>com.ibm.cics</groupId>
      <artifactId>com.ibm.cics.jcicsx</artifactId>
      <version>1.000.0-5.6</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>

      <!-- The below bundles the application as a WAR in a CICS bundle and deploys this to CICS using the CICS bundle deployment API.
           This is optional and can be removed if you don't wish to deploy the application this way -->
      <plugin>
        <groupId>com.ibm.cics</groupId>
        <artifactId>cics-bundle-maven-plugin</artifactId>
        <version>1.0.0</version>
        <executions>
          <execution>

            <!-- These goals will firstly run the war packaging on the project, and then will run the deploy goal, which will happen during the verify phase of the lifecycle by default-->
            <goals>
              <goal>bundle-war</goal>
              <goal>deploy</goal>
            </goals>

            <configuration>
              <!-- The bundle classifier indicates that the war should be packaged into a CICS bundle -->
              <classifier>cics-bundle</classifier>

              <!-- Update the default JVM server that the application will be installed into by default, This is used when creating the bundle, and goes into the CICS bundle's manifest -->
              <jvmserver>DFHWLP</jvmserver>
              
              <!-- Set the URL of the deploy target -->
              <url>http://yourcicsurl.com:9080</url>

              <!-- We'd recommend that you use Maven's password encryption, or supply your credentials using environment variables or properties, as shown here. -->
              <username>${cics-user-id}</username>
              <password>${cics-password}</password>

              <!-- Identify which bundle definition you're going to use from the CSD and which region and CICSPlex you want to deploy to -->
              <bunddef>DEMOBUNDLE</bunddef>
              <csdgroup>BAR</csdgroup>
              <cicsplex>CICSEX56</cicsplex>
              <region>IYCWEMW2</region>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>
```

A JCICSX dependency has been specified.
The settings for the BUNDLE definition are also included, but for now, leave them as they are.

Next, let's take a look at the Servlet source.


```java:CharLinkServlet.java
package sample;

/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* SAMPLE                                                                 */
/*                                                                        */
/* (c) Copyright IBM Corp. 2020 All Rights Reserved                       */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or disclosure */
/* restricted by GSA ADP Schedule Contract with IBM Corp                  */
/*                                                                        */

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ibm.cics.jcicsx.CICSConditionException;
import com.ibm.cics.jcicsx.CICSContext;

/**
 * A sample servlet to demonstrate how to use JCICSX to LINK to a CICS Program
 * with CHAR data
 */
@WebServlet("/SampleServlet")
public class CharLinkServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	/**
	 * Name of the program to invoke.
	 */
	private static final String PROG_NAME = "EDUCHAN";

	/**
	 * Name of the channel to use.
	 */
	private static final String CHANNEL = "MYCHANNEL";

	/**
	 * Name of the container used to send data to the target program.
	 */
	private static final String INPUT_CONTAINER = "INPUTDATA";

	/**
	 * Name of the container which will contain the response from the target
	 * program.
	 */
	private static final String OUTPUT_CONTAINER = "OUTPUTDATA";

	/**
	 * Data to place in the container to be sent to the target program.
	 */
	private static final String INPUTSTRING = "Hello from Java";

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html");

		response.getWriter().print("Hello world! ");

		// Message to emit as the response
		String resultStr = null;

		// Gets the current CICS Context for the environment we're running in
		CICSContext task = CICSContext.getCICSContext();

		try {
			// Create a reference to the Program we will invoke and specify the channel
			// Don't syncpoint between remote links, this is the default
			// Link to the program with an input container, containing the input string of
			// "Hello from Java"
			task.createProgramLinkerWithChannel(PROG_NAME, CHANNEL).setSyncOnReturn(false)
					.setStringInput(INPUT_CONTAINER, INPUTSTRING).link();

			// Get the data from the output container as a string
			// You could remove task.getChannel(CHANNEL) and do this as one chained command
			// above, but this demonstrates how you could call this part later on in your
			// program
			resultStr = task.getChannel(CHANNEL).getCHARContainer(OUTPUT_CONTAINER).get();

			if (resultStr == null) {
				// Missing response container
				resultStr = "<missing>";
			}

			// Format the final message and print it
			String msg = "Returned from link to \'" + PROG_NAME + "\' with a text response of \'" + resultStr + "\'";
			response.getWriter().println(msg);

		} catch (CICSConditionException e) {
			response.getWriter().println("An exception has occured" + "\nRESP: " + e.getRespCode() + "\nRESP2: "
					+ e.getResp2() + "\nMessage: " + e.getMessage());
		}
	}

}
```

Here, the JCICSX class is used to perform operations on Channel & Container and LINK the program.
Specifically, the following operations are performed.

- Create a container "INPUTDATA" in the channel "MYCHANNEL" and enter the string "Hello from Java"
- Call the COBOL program "EDUCHAN" with "MYCHANNEL"
- Obtain data from the container "OUTPUTDATA" of "MY CHANNEL" and display the result on the screen

The COBOL source is also provided, so check that as well.

```cbl:EDUCHAN
      *----------------------------------------------------------------*
      *  Licensed Materials - Property of IBM                          *
      *  SAMPLE                                                        *
      *  (c) Copyright IBM Corp. 2016 All Rights Reserved              *
      *  US Government Users Restricted Rights - Use, duplication or   *
      *  disclosure restricted by GSA ADP Schedule Contract with       *
      *  IBM Corp                                                      *
      *----------------------------------------------------------------*

      ******************************************************************
      *                                                                *
      * Module Name        EDUCHAN.CBL                                 *
      * Version            1.0                                         *
      * Date               22/10/2016                                  *
      *                                                                *
      * CICS back-end channel/container sample                         *
      *                                                                *
      * This program expects to be invoked with a CHAR container named *
      * INPUTDATA and returns the following containers:                *
      * A CHAR container containing the reversed input string          *
      * A CHAR container containing the time                           *
      * A BIT container containing the CICS return code from reading   *
      * the input container                                            *
      ******************************************************************

       IDENTIFICATION DIVISION.
       PROGRAM-ID. EDUCHAN.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.

      *  Container name declarations
      *  Channel and container names are case sensitive
       01 DATE-CONT          PIC X(16) VALUE 'CICSTIME'.
       01 INPUT-CONT         PIC X(16) VALUE 'INPUTDATA'.
       01 OUTPUT-CONT        PIC X(16) VALUE 'OUTPUTDATA'.
       01 LENGTH-CONT        PIC X(16) VALUE 'INPUTDATALENGTH'.
       01 ERROR-CONT         PIC X(16) VALUE 'ERRORDATA'.
       01 RESP-CONT          PIC X(16) VALUE 'CICSRC'.


      *  Data fields used by the program
       01 INPUTLENGTH        PIC S9(8) COMP-4.
       01 DATALENGTH         PIC S9(8) COMP-4.
       01 CURRENTTIME        PIC S9(15) COMP-3.
       01 ABENDCODE          PIC X(4) VALUE SPACES.
       01 CHANNELNAME        PIC X(16) VALUE SPACES.
       01 INPUTSTRING        PIC X(72) VALUE SPACES.
       01 OUTPUTSTRING       PIC X(72) VALUE SPACES.
       01 RESPCODE           PIC S9(8) COMP-4 VALUE 0.
       01 RESPCODE2          PIC S9(8) COMP-4 VALUE 0.
       01 DATE-TIME.
         03 DATESTRING         PIC X(10) VALUE SPACES.
         03 TIME-SEP           PIC X(1) VALUE SPACES.
         03 TIMESTRING         PIC X(8) VALUE SPACES.
       01 RC-RECORD          PIC S9(8) COMP-4 VALUE 0.
       01 ERR-RECORD.
         03 ERRORCMD           PIC X(16) VALUE SPACES.
         03 ERRORSTRING        PIC X(32) VALUE SPACES.


       PROCEDURE DIVISION.
      *  -----------------------------------------------------------
       MAIN-PROCESSING SECTION.
      *  -----------------------------------------------------------

      *  Get name of channel
           EXEC CICS ASSIGN CHANNEL(CHANNELNAME)
                            END-EXEC.

      *  If no channel passed in, terminate with abend code NOCH
           IF CHANNELNAME = SPACES THEN
               MOVE 'NOCH' TO ABENDCODE
               PERFORM ABEND-ROUTINE
           END-IF.


      *  Read content and length of input container
           MOVE LENGTH OF INPUTSTRING TO INPUTLENGTH.
           EXEC CICS GET CONTAINER(INPUT-CONT)
                            CHANNEL(CHANNELNAME)
                            FLENGTH(INPUTLENGTH)
                            INTO(INPUTSTRING)
                            RESP(RESPCODE)
                            RESP2(RESPCODE2)
                            END-EXEC.

      *  Place RC in binary container for return to caller
           MOVE RESPCODE TO RC-RECORD.
           EXEC CICS PUT CONTAINER(RESP-CONT)
                            FROM(RC-RECORD)
                            FLENGTH(LENGTH OF RC-RECORD)
                            BIT
                            RESP(RESPCODE)
                            END-EXEC.

           IF RESPCODE NOT = DFHRESP(NORMAL)
             PERFORM RESP-ERROR
           END-IF.

      *  Place reversed string in output container
           MOVE FUNCTION REVERSE(INPUTSTRING) TO OUTPUTSTRING.

           EXEC CICS PUT CONTAINER(OUTPUT-CONT)
                            FROM(OUTPUTSTRING)
                            FLENGTH(LENGTH OF OUTPUTSTRING)
                            CHAR
                            RESP(RESPCODE)
                            END-EXEC.

           IF RESPCODE NOT = DFHRESP(NORMAL)
             PERFORM RESP-ERROR
           END-IF.

      *  Get the current time
           EXEC CICS ASKTIME ABSTIME(CURRENTTIME)
                            END-EXEC.

      *  Format date and time
           EXEC CICS FORMATTIME
                     ABSTIME(CURRENTTIME)
                     DDMMYYYY(DATESTRING)
                     DATESEP('/')
                     TIME(TIMESTRING)
                     TIMESEP(':')
                     RESP(RESPCODE)
                     END-EXEC.

      *  Check return code
           IF RESPCODE NOT = DFHRESP(NORMAL)
               STRING 'Failed' DELIMITED BY SIZE
                            INTO DATESTRING END-STRING
           END-IF.

      *  Place current date in container CICSTIME
           EXEC CICS PUT CONTAINER(DATE-CONT)
                            FROM(DATE-TIME)
                            FLENGTH(LENGTH OF DATE-TIME)
                            CHAR
                            RESP(RESPCODE)
                            END-EXEC.
      *  Check return code
           IF RESPCODE NOT = DFHRESP(NORMAL)
             PERFORM RESP-ERROR
           END-IF.



      *  Return back to caller
           PERFORM END-PGM.

      *  -----------------------------------------------------------
       RESP-ERROR.
             MOVE 'EDUC' TO ABENDCODE
             PERFORM ABEND-ROUTINE.

           PERFORM END-PGM.

      *  -----------------------------------------------------------
      *  Abnormal end
      *  -----------------------------------------------------------
       ABEND-ROUTINE.
           EXEC CICS ABEND ABCODE(ABENDCODE) END-EXEC.

      *  -----------------------------------------------------------
      *  Finish
      *  -----------------------------------------------------------
       END-PGM.
           EXEC CICS RETURN END-EXEC.


```

In the COBOL program, the character strings received in the INPUTDATA container are set in the OUTPUTDATA container in the reverse order and returned. In addition, we are adding a container to store the date and time and RESP Code.

The source is used as it is without any modification.

## Preparation for COBOL program

Since this sample is a scenario of creating a Java program that calls an existing COBOL program, the COBOL application must be prepared in the development environment. Transfer the COBOL source (EDUCHAN) to z/OS, compile/link it, and add the program definition in the CICS region where the CICS-Liberty configuration for remote development is performed. This is the same as the procedure for a traditional CICS-COBOL application.

## Build/Deploy/Test Java application

Right click on the project, and select "Maven" - "Update Project".
Select a project and OK.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/b4554aa9-b8c3-c698-0428-3c78767e6869.png)

Right click on CharLinkServlet.java, and select "Run" - "Run on server".
Select Liberty Server with jcicsx configuration and Next.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/101e5e88-2b91-6af6-4773-1a6b436db932.png)

Finish
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/4812c227-97a3-f90a-a370-b82e3bd95b86.png)

After the specified Liberty is launched and the app is deployed, the browser will open and the Servlet will be executed.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/4098811d-0416-0137-7328-4afbec187929.png)

It ran successfully! The string "Hello from Java" is returned in reverse order. In other words, you can see that the COBOL program on CICS was called even though it was run on the local Liberty. It was confirmed that if you configure JCICSX for remote development in advance, you can even test on Liberty just by operating the PC side!
It means, as a normal development process, you can complete the modification, deployment, and testing your JCICSX application on your PC.