CICS-Javaアプリケーションを動かす - (5)JCICSXの利用

# はじめに
CICS Transaction ServerではJavaからCICS機能を利用するためのJCICSというクラスライブラリーが提供されています。これはいわゆるEXEC CICS APIのJava版とも言えるもので、LINKで他のCICSプログラムを呼び出したりTSQ/TDQなどのCICS管理リソースにアクセスできたりします。これを使用することでJavaでCICSのアプリケーションが書けるということになります。
2020/06/12に出荷されたCICS TS V5.6では、JCICSを拡張したJCICSXという新しいJava用のCICS APIが提供されるようになりました。ここではそのJCICSXを動かしてみた時の一連の流れを記載します。

## 関連記事
[CICS-Javaアプリケーションを動かす - (1)単純なサンプルアプリの稼働](https://qiita.com/tomotagwork/items/aac10ad84fe83d88bb5f)
[CICS-Javaアプリケーションを動かす - (2)Mavenによるビルド管理](https://qiita.com/tomotagwork/items/a487484835d4e8dd2d6f)
[CICS-Javaアプリケーションを動かす - (3)Gradleによるビルド管理](https://qiita.com/tomotagwork/items/6fae5bd3440635ad26af)
[CICS-Javaアプリケーションを動かす - (4)Spring Bootアプリ](https://qiita.com/tomotagwork/items/9bdef46069e1591103ba)
[CICS-Javaアプリケーションを動かす - (5)JCICSXの利用](https://qiita.com/tomotagwork/items/cac290f6435453c19b7b)

# 環境情報
**開発環境**
Windows10

**実行環境**
z/OS V2.4
CICS Transaction Server for z/OS V5.6

# JCICSX概要
「JavaからCICS機能を使用するためのクラスライブラリー≒EXEC CICS APIのJava版」という位置づけはJCICSもJCICSXも同様です。
何が違うのかというと、JCICSXはローカルPC上(開発環境上)でのテストをしやすくするために拡張されたAPIである、という点です。
また、JCICSの場合割と広範囲にEXEC CICS相当の機能をサポートしていますが、JCICSXはまだ限定的で、Channel&ContainerおよびLink関連の機能のみしか提供されていません。
参考:
[JCICS Javadoc](https://www.ibm.com/support/knowledgecenter/ja/SSGMCP_5.6.0/reference-javadocs/jcics-javadoc/index.html)
[JCICSX Javadoc](https://www.ibm.com/support/knowledgecenter/ja/SSGMCP_5.6.0/reference-javadocs/jcicsx-javadoc/index.html)

"ローカルPC上(開発環境上)でテストしやすい"というのは具体的には以下の2つのポイントがあります。

(1) テスト用フレームワークを使用した単体テストが可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/abd640de-bca6-979a-04b7-e529d1ba743c.png)

ローカルPC上には当然CICSランタイムが無いので、CICS依存のコード(JCICSX部分)はそのままだと実行できません。DBアクセスなど環境依存のコードを含むモジュールの単体テストを行う場合、外部リソースアクセス部分をMockとして取り扱うようなフレームワーク(Mockitoなど)がありますが、それをCICSアクセス部分にも応用するという話になります。(これはMockitoなどのフレームワークで提供される機能の恩恵が主だと思います。)

(2) PC上のLibertyサーバー上で稼働確認が可能
こちらがCICSの拡張機能としては主要なものになりますが、ローカルPC上(開発環境上)のLibertyでJCICSXの稼働確認が行える仕組みを提供しています。イメージとしては以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/f996d88b-4de4-061a-7d89-79b26f054a98.png)


この仕組みは"リモート開発"と呼ばれています。PC上のLibertyと、開発環境用にCICS-Libertyを用意しておき、それぞれJCICSXリモート開発用フィーチャーの構成をしておきます。このような構成をしておくことで、ローカルPC上のLibertyがあたかもCICS上で稼働しているかのように動作してくれます。そのため、トライ&エラーやテストを行う際に毎回ホスト側にアプリをデプロイして動作確認を行う必要は無く、ローカルPC上で動作確認、修正の細かいサイクルを回すことができます。
最終的にコードが固まったら、それをそのままテスト環境/本番環用の実CICS-Liberty環境にデプロイして稼働させることが可能です。

つまり、Channel&Containerでデータを受け渡してLinkで既存アプリを呼び出すLibertyアプリを作る場合にはJCICSXを使うと便利ですよ、ということになります(COMMAREA渡しのLINKは不可)。

以降、PC上のLibertyサーバーでJCICSXのテストを行うための構成手順を示します。

# CICS-Libertyリモート開発環境構成
参考: [Configuring the environment for JCICSX](https://www.ibm.com/support/knowledgecenter/en/SSGMCP_5.6.0/applications/developing/java/jcicsx-api.html#jcicsx-api__configure)

## CICS-Liberty側(サーバー側)の構成

### JVMプロファイル

USS上にJVMプロファイルを準備します。(JVMServerに関するプロパティーは実質このUSS上のファイルに指定します。JVMSERVER資源定義ではこのJVMプロファイルのファイル名をポイントすることになります。)
サンプルが提供されているのでそれをコピーして使用します。

/var/cicsts/cicsts56/CT56B4A1/JVMProfiles というディレクトリを作成し、そこに/usr/lpp/cicsts/cicsts56/JVMProfiles/DFHWLP.jvmprofile(CICS導入ディレクトリ下に配置されているLiberty用のサンプル定義)を、DFHWLPX.jvmprofileという名前でコピーします。
環境に合わせて適宜カスタマイズします。

```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

上のプロパティーファイルを配置したディレクトリを、SITパラメーター"JVMPROFILEDIR"に指定します。

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

変更反映のためにリージョンを再起動します。

### JVMServer定義

JVMSERVER資源定義を準備します。
製品提供のDFH$WLPというグループにあるJVMSERVER定義"DFHWLP"を適当なグループに"DFHWLPX"という名前にコピーしてカスタマイズします。

```
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となっていますが、これはSITのJVMPROFILEDIRに指定されたディレクトリ下のDFHWLPX.jvmprofileというファイルがJVMプロパティーファイルとして使用されることを意味します。

一旦このJVMSERVERをインストールします。

CEMT I JVMSERVERで見てEnableになっていればOK。

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

### JCICSXフィーチャー / サーバー側構成

JVMProfileで「com.ibm.cics.jvmserver.wlp.autoconfigure=true」を指定しているので、JVMServerインストール時に自動でLibertyが構成されます。

\<WORK_DIR\>/CT56B4A1/DFHWLPX/wlp/usr/servers/defaultServer/server.xmlが作成されているので、それを編集します。
以下のように、cicsts:jcicsxServer-1.0というフィーチャーを追加します。

```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>
...
```

JVMServerを再起動すると、Liberty起動時メッセージとして以下のようなログが確認できます。
(\<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/
...
```

ここで示されているURLはPC側のLiberty構成で使用します。


## ローカルPC上のLiberty(クライアント側)の構成

### Eclipse/Liberty導入
Windows10上にEclipse環境をセットアップしてLibertyを導入します。
手順は以下の記事のものをそのまま使用します。
[WebSphere Application Server Liberty Base - JCA接続環境構築メモ - 開発環境セットアップ(Windows)](https://qiita.com/tomotagwork/items/73d84923cc1a1ee6f6b0#%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97windows)


### JCICSX関連フィーチャー追加
Eclipseのサーバービューで対象のLibertyのフィーチャーマネージャーをダブルクリックしてserver.xmlを開き、フィーチャーリストの右の追加をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/164b017c-6294-14e4-75a1-dce12d563b86.png)

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

フィルターに「JCICS」を指定すると、JCICSX development feature for Javaがリストされるので、インストールをクリックして次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/efbaea96-1da3-40db-680e-9d4441c71116.png)

ライセンスを確認して完了
![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)

フィーチャーがインストールされたので、jcicsxでフィルターして表示された user:jcicsxClient-1.0を選択してOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/65db0d50-b33f-2150-ca1f-114bd02b1d9c.png)

フィーチャーとして追加されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/1c8f0536-e3bb-c5da-e165-1a9b0449ba06.png)

server.xmlのソースをみるとこんな感じになっています。

```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フィーチャー / クライアント側構成

server.xmlを編集して以下の設定を追加します。

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

serverUriのアドレスとポートは、JCICSXサーバー用の構成をしたCICS-Libertyのエンドポイントです。
server.xmlをデザインビューで見ると以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/37063f46-e997-faf6-e90f-4e9063a8618e.png)

これで一通り"リモート開発"の構成は完了です。

# JCICSXを使用したローカルPC上でのアプリケーションの開発

## JCICSX開発環境整備

JCICSXのクラスライブラリーの提供のされかたはいくつかありますが、CICS ExplorerのCICS SDK for Javaにも含まれています。CICS Explorer機能をEclipseに組み込めば管理もしやすいので、Eclipse環境にCICS Explorerを入れることにします。

参考: [Downloading and starting CICS Explorer](https://www.ibm.com/support/knowledgecenter/SSSQ3W_5.5.0/com.ibm.cics.core.help/topics/concepts/install_planning_client.html)

Eclipseのメニューから ヘルプ-新規ソフトウェアのインストールを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/496cca20-bc3e-da4c-92cb-207ae97e0e6f.png)

追加を押して、以下のリポジトリを追加します。
「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)

CICS Explorerを選択して次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/2eae14c9-5d76-55ac-4c8b-abf6473f61bf.png)

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

ライセンスを確認して完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/0bd701e3-70c5-39d5-baa4-3d6d563c6066.png)

インストールに結構時間がかかります。途中こういう確認が出たりしますので適宜対応。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/6d10e2ad-1c31-ee36-563b-efd1c5f9a278.png)

完了すると以下のポップアップが出るのでEclipse再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/96ee3bdc-3ab7-1f17-a257-1850fe68ad7a.png)

これでCICS Explorer機能がEclipseに組み込まれました。

## サンプルアプリの取り込み
ここではGitHubに提供されているサンプルを動かしてみることにします。
[GitHub: cics-java-jcicsx-samples](https://github.com/cicsdev/cics-java-jcicsx-samples)
ローカルにクローンを作成します。

```
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.
```

いくつかあるサンプルのうち、「char-link-program-sample」をEclipseに取り込みます。

JavaEEパースペクティブのEnterprise Explorerビューを右クリック - インポート
Maven - 既存Mavenプロジェクトを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/7d9bfb5d-2f20-8e1b-dc94-7c6eb71f0b39.png)

クローンしたディレクトリ下の「char-link-program-sample」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/499163cb-9fea-0875-f330-344f7e860242.png)


プロジェクトが作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/0e16eb1a-9e21-e6de-3f94-cfe8bd7c2640.png)


## 中身の確認

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>
```

JCICSXの依存関係が指定されています。
BUNDLE定義用の設定も含まれていますが、ここでは一旦そのまま置いておきます。

次にServletのソースを見てみます。

```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());
		}
	}

}
```

ここではJCICSXのクラスを使って、Channel&Containerに対する操作、および、プログラムのLINKを実施しています。
具体的には以下のような操作をしています。

- "MYCHANNEL"というチャネルに"INPUTDATA"というコンテナを作って、"Hello from Java"という文字列を投入
- "MYCHANNEL"を指定して"EDUCHAN"というCOBOLプログラムを呼び出す
- "MYCHANNEL"の"OUTPUTDATA"というコンテナからデータを取得して結果を画面に表示

COBOLのソースも提供されているのでそちらも確認しておきます。

```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.


```

COBOLプログラムでは、INPUTDATAコンテナで受け取った文字列を逆順にしたものをOUTPUTDATAコンテナにセットして返しています。その他日時やRESP Codeを入れるコンテナを追加したりしています。

特に修正はせずにそのままソースは使用します。

## COBOLアプリ準備

このサンプルは既存のCOBOLプログラムを呼び出すJavaプログラムを作成する、というシナリオなので、COBOLアプリは開発環境に準備しておく必要があります。COBOLソース(EDUCHAN)をz/OSに転送して、コンパイル/リンクし、リモート開発用CICS-Liberty構成を行ったCICSリージョンにプログラム定義を登録しておきます。これは従来のCICS-COBOLアプリケーションの手順と変わらないので、ここでは割愛します。

## Javaアプリケーションのビルド/デプロイ/テスト

プロジェクトを右クリック - Maven - プロジェクトの更新を選択
プロジェクトを選択してOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/b4554aa9-b8c3-c698-0428-3c78767e6869.png)

CharLinkServlet.javaを右クリック - 実行 - サーバーで実行
jcicsxの構成を行ったLiberty Serverを選択して次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/101e5e88-2b91-6af6-4773-1a6b436db932.png)

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

指定したLibertyが起動してアプリがデプロイされた後、ブラウザが開いてServletが実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/4098811d-0416-0137-7328-4afbec187929.png)

正常に実行されました！ "Hello from Java"という文字列が逆順になって返されています。すなわち、ローカルのLibertyで動かしたにも関わらず、CICS上のCOBOLプログラムが呼び出されたことが分かります。つまり、事前にJCICSXのリモート開発用構成を行っておけば、PC側の操作だけでLiberty上のテストまでできることが確認できました！ 
通常の開発プロセスとしてPC上で修正、デプロイ、テストが完結して行えることになります。

# 実CICS-Liberty環境へのデプロイ/テスト

## CICS側準備

実際にCICS-Libertyアプリケーションを動かすためには、Liberty用のJVMSERVERの構成が必要になります。ここではJCICSXのリモート開発用のフィーチャーは必要ありませんので、通常通りのJVMSERVER構成をすればOKです。また、ここではMavenプロジェクトとしてDeployまで自動化する想定なので、ターゲットのCICSはCICSplexに属していて、WUIにはDeployment APIの構成を行っておく必要があります。その辺りは以下の"実行環境の準備"がそのまま該当します。
参考: [CICS-Javaアプリケーションを動かす - (2)Mavenによるビルド管理](https://qiita.com/tomotagwork/items/a487484835d4e8dd2d6f#%E5%AE%9F%E8%A1%8C%E7%92%B0%E5%A2%83zos-cics)

## pom.xmlの編集

pom.xmlには、CICS Bundleプロジェクト用の構成も含まれています。実際のCICS環境にアプリをデプロイする場合その辺りの構成が必要になりますので上で設定した実行環境に合わせて編集します。

```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>cics004-char-link-program-sample</artifactId>
  <version>1.0.0</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://etp1:56002</url>

              <!-- We'd recommend that you use Maven's password encryption, or supply your credentials using environment variables or properties, as shown here. -->
              <username>TAG</username>
              <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>CHARLINK</bunddef>
              <csdgroup>TAGGRP</csdgroup>
              <cicsplex>C73PLX</cicsplex>
              <region>CT56B4A1</region>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>
```

先頭のartifactId, versionも同一CICSplex環境でユニークになるよう修正しておきます。

## BUNDLE定義の準備

上のpom.xmlの定義に合わせてCICS上にBUNDLE定義を作成します。

```
OBJECT CHARACTERISTICS                                    CICS RELEASE = 0730 
 CEDA  View Bundle( CHARLINK )                                                
  Bundle         : CHARLINK                                                   
  Group          : TAGGRP                                                     
  DEScription    : CICS-BUNDLE-DEMO                                           
  Status         : Enabled            Enabled | Disabled                      
  BUndledir      : /var/cicsts/cicsts56/bundles/cics004-char-link-program-sam 
  (Mixed Case)   : ple_1.0.0                                                  
                 :                                                            
                 :                                                            
                 :                                                            
  BAsescope      :                                                            
  (Mixed Case)   :                                                            
                 :                                                            
                 :                                                            
                 :                                                            
 DEFINITION SIGNATURE                                                         
  DEFinetime     : 08/11/20 16:05:22                                          
  CHANGETime     : 08/11/20 16:07:52                                          
```

ここではインストールは行いません。

## JVMSERVERの準備

今回、開発環境用と本番環境用のリージョンは同じものを使いますが、JVMServerは分けています。開発環境用としてはDFHWLPXというJVMSERVER定義を使用していましたがこれはDiscardして、本番環境用のJVMServer: DFHWLP(JCICSX用の構成がされていないもの)のみをEnableにしておきます。

## COBOLアプリケーションの準備

JavaアプリケーションからはEDUCHANというCOBOLプログラムをLINKしていますのでそのプログラムを呼び出せる状態にしておく必要があります。今回開発環境用と本番環境用は同一リージョンを使うので、COBOlプログラムも既にセットアップ済みの想定です。
リージョンを分けている場合は当然実環境にプログラム定義追加しておく必要があります。

## Javaアプリケーションのビルド/デプロイ
Eclipseでpom.xmlを右クリック - 実行 - Maven installを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/12189137-06ed-a9af-5cfb-75943ac1cfa7.png)

コンソールビューにてmvn installの実行結果が確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/c7f9548f-e28b-93fa-7701-763281de02e2.png)

BUILD SUCCESSが出力されていればOKです。

念のため、CICS Explorerでバンドル、バンドルパーツがインストールされていることも確認しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/4aebd83a-65d6-4d2d-c7d4-6f25e2f661dc.png)

## 実行
以下のURLでCICS-Libertyアプリにアクセス
http://etp1:56441/cics004-char-link-program-sample-1.0.0/SampleServlet
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/de9daf56-42d4-7d94-40d4-7468dac4a9d0.png)

実CICS-Liberty環境でも同一のコードで稼働確認がとれました！