はじめに
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)単純なサンプルアプリの稼働
CICS-Javaアプリケーションを動かす - (2)Mavenによるビルド管理
CICS-Javaアプリケーションを動かす - (3)Gradleによるビルド管理
CICS-Javaアプリケーションを動かす - (4)Spring Bootアプリ
CICS-Javaアプリケーションを動かす - (5)JCICSXの利用
環境情報
開発環境
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
JCICSX Javadoc
"ローカルPC上(開発環境上)でテストしやすい"というのは具体的には以下の2つのポイントがあります。
ローカルPC上には当然CICSランタイムが無いので、CICS依存のコード(JCICSX部分)はそのままだと実行できません。DBアクセスなど環境依存のコードを含むモジュールの単体テストを行う場合、外部リソースアクセス部分をMockとして取り扱うようなフレームワーク(Mockitoなど)がありますが、それをCICSアクセス部分にも応用するという話になります。(これはMockitoなどのフレームワークで提供される機能の恩恵が主だと思います。)
(2) PC上のLibertyサーバー上で稼働確認が可能
こちらがCICSの拡張機能としては主要なものになりますが、ローカルPC上(開発環境上)のLibertyでJCICSXの稼働確認が行える仕組みを提供しています。イメージとしては以下の通りです。
この仕組みは"リモート開発"と呼ばれています。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
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という名前でコピーします。
環境に合わせて適宜カスタマイズします。
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というフィーチャーを追加します。
...
<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)
...
[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)
JCICSX関連フィーチャー追加
Eclipseのサーバービューで対象のLibertyのフィーチャーマネージャーをダブルクリックしてserver.xmlを開き、フィーチャーリストの右の追加をクリック
Install additional featuresをクリック
フィルターに「JCICS」を指定すると、JCICSX development feature for Javaがリストされるので、インストールをクリックして次へ
フィーチャーがインストールされたので、jcicsxでフィルターして表示された user:jcicsxClient-1.0を選択してOK
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を編集して以下の設定を追加します。
...
<!-- JCICSX Client Config -->
<usr_jcicsxClient serverUri="http://etp1:56461"/>
...
serverUriのアドレスとポートは、JCICSXサーバー用の構成をしたCICS-Libertyのエンドポイントです。
server.xmlをデザインビューで見ると以下のように表示されます。
これで一通り"リモート開発"の構成は完了です。
JCICSXを使用したローカルPC上でのアプリケーションの開発
JCICSX開発環境整備
JCICSXのクラスライブラリーの提供のされかたはいくつかありますが、CICS ExplorerのCICS SDK for Javaにも含まれています。CICS Explorer機能をEclipseに組み込めば管理もしやすいので、Eclipse環境にCICS Explorerを入れることにします。
参考: Downloading and starting CICS Explorer
Eclipseのメニューから ヘルプ-新規ソフトウェアのインストールを選択
追加を押して、以下のリポジトリを追加します。
「https://public.dhe.ibm.com/ibmdl/export/pub/software/htp/zos/tools/aqua3.2/」
インストールに結構時間がかかります。途中こういう確認が出たりしますので適宜対応。
これでCICS Explorer機能がEclipseに組み込まれました。
サンプルアプリの取り込み
ここではGitHubに提供されているサンプルを動かしてみることにします。
GitHub: 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プロジェクトを選択
クローンしたディレクトリ下の「char-link-program-sample」を選択
中身の確認
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のソースを見てみます。
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のソースも提供されているのでそちらも確認しておきます。
*----------------------------------------------------------------*
* 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
CharLinkServlet.javaを右クリック - 実行 - サーバーで実行
jcicsxの構成を行ったLiberty Serverを選択して次へ
指定したLibertyが起動してアプリがデプロイされた後、ブラウザが開いてServletが実行されます。
正常に実行されました! "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によるビルド管理
pom.xmlの編集
pom.xmlには、CICS Bundleプロジェクト用の構成も含まれています。実際のCICS環境にアプリをデプロイする場合その辺りの構成が必要になりますので上で設定した実行環境に合わせて編集します。
<?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を選択
コンソールビューにてmvn installの実行結果が確認できます。
BUILD SUCCESSが出力されていればOKです。
念のため、CICS Explorerでバンドル、バンドルパーツがインストールされていることも確認しておきます。
実行
以下のURLでCICS-Libertyアプリにアクセス
http://etp1:56441/cics004-char-link-program-sample-1.0.0/SampleServlet
実CICS-Liberty環境でも同一のコードで稼働確認がとれました!