RPGからJavaメソッド呼び出し（独自クラスでのメソッドの呼び出し）

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プログラムの準備

```As400Funcs.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プログラムの準備とコンパイル

```GETJOBSTSR.rpgle
      *                                                                                      
      * 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の再起動は出来ないようで、いったんサインオフしないと駄目なようです。）