ILE RPGからJavaメソッドを呼び出す備忘録です。
「IBM Rational Development Studio for i ILE RPGプログラマーの手引き」(IBM i バージョン7.2)にも記載されていますが、あまり詳しくは書かれていなかった為実際に試してみました。
なお実行したIBMiの環境は、バージョン:V5R4、Java:1.4.2です。
(V7R2、Java1.8.0でも稼働しました。)
少し実用性を持たせるため、稼働中ジョブの状況を返すプログラムを作ってみました。
引数に文字列(ジョブ名)を渡し、文字列(状況)を返します。
(同じジョブ名が複数存在する場合は最初に取得したジョブの状態を返します。)
#IBMi環境確認
以下のコマンドでJavaのバージョンが返ってくれば大丈夫です。
CHGJOB CCSID(5035)
STRQSH
java -version
#フォルダの構成
IBMi上のIFSのフォルダ構成は以下としました。
/Root
|-JavaApps
|-/bin
|-/mypackage
|-As400Funcs.class
|-/lib
|-jt400.jar
|-/src
|-/mypackage
|-As400Funcs.java
#Javaプログラムの準備
package mypackage;
import com.ibm.as400.access.AS400;
import com.ibm.as400.resource.RJob;
import com.ibm.as400.resource.RJobList;
import com.ibm.as400.resource.ResourceException;
public class As400Funcs {
public static void main(String[] args) {
System.out.println(GetJobSts("DSP01"));
}
public static String GetJobSts(String searchJob) {
AS400 as400 = new AS400("192.168.XXX.XXX" ,"MYUSER" ,"MYPASS");
//init
String resultStatus = "NONE";
//get JobList
RJobList jobList = new RJobList(as400);
try {
jobList.setSelectionValue(RJobList.PRIMARY_JOB_STATUSES, new String[] { RJob.JOB_STATUS_ACTIVE });
jobList.setSelectionValue(RJobList.JOB_NAME,searchJob);
jobList.open();
jobList.waitForComplete();
//Get First Job
long numberOfJobs = jobList.getListLength();
for (long i = 0; i<numberOfJobs; ++i){
RJob ajob = (RJob)jobList.resourceAt(i);
RJob rjob = new RJob(as400,searchJob,(String)ajob.getAttributeValue(RJob.USER_NAME),(String)ajob.getAttributeValue(RJob.JOB_NUMBER));
resultStatus = (String)rjob.getAttributeValue(RJob.ACTIVE_JOB_STATUS);
System.out.println("JOB Status:"+resultStatus);
System.out.println("JOB Name:"+searchJob);
break;
}
} catch (ResourceException e) {
e.printStackTrace();
}
return resultStatus;
}
}
#Javaプログラムのコンパイルとテスト実行
環境変数をセットします。(念のため一度サインオフしてから実行して下さい。)
ADDENVVAR ENVVAR(CLASSPATH) VALUE('/JavaApps/bin:/JavaApps/lib/jt400.jar')
コンパイルとテスト実行(QSHELL)
javac -d /JavaApps/bin /JavaApps/src/mypackage/As400Funcs.java
java mypackage/As400Funcs
サンプルでは、引数のジョブ名に「DSP01」としましたが、
実際に稼働しているジョブを指定して下さい。正しく状態が取得できれば大丈夫です。
#RPGプログラムの準備とコンパイル
*
* JAVAのメソッドを呼び出すサンプルプログラム
*
H DFTACTGRP(*NO)
D MAIN PR EXTPGM('GETJOBSTSR')
D 10A
D MAIN PI
D searchJob 10A
D newString PR O ExtProc(*JAVA:
D 'java.lang.String':
D *CONSTRUCTOR)
D Class(*JAVA:'java.lang.String')
D bytes 10A Const Varying
D GetJobSts PR O ExtProc(*JAVA:
D 'mypackage.As400Funcs'
D :'GetJobSts')
D STATIC
D CLASS(*JAVA:'java.lang.String') // 戻り型
D string O CLASS(*JAVA:'java.lang.String') Const// パラメータ
D getBytes PR 10A ExtProc(*JAVA:
D 'java.lang.String':
D 'getBytes')
D Varying
D string1 S O Class(*JAVA:'java.lang.String')
D StringResult S O Class(*JAVA:'java.lang.String')
D StringDisply S 10A Varying
/Free
String1 = newString(searchJob) ;
StringResult = GetJobSts(String1) ;
StringDisply = getBytes(StringResult) ;
dsply StringDisply;
*inLR = *on ;
return ;
/End-Free
CRTBNDRPG PGM(MYLIB/GETJOBSTSR) SRCFILE(MYLIB/MYSRC) DBGVIEW(*SOURCE)
#RPGプログラムの実行
CALL GETJOBSTSR PARM('DSP01')
画面にジョブの状態が表示されればOKです。
#「JAVAメソッドの呼び出し時にJAVA例外を受け取りました」エラー
java.lang.NoClassDefFoundError
エラーの場合、ほとんどが環境変数「CLASSPATH」が正しくない場合が多いです。
特に一度RPGを実行してしまうとそのジョブでJVMが起動し、その後
ADDENVVAR ENVVAR(CLASSPATH) VALUE('/JavaApps/bin:/JavaApps/lib/jt400.jar')
を実行しても反映されません。
(JVMの再起動は出来ないようで、いったんサインオフしないと駄目なようです。)