Java メソッドの ILE RPG からの呼び出し
この節では、Java™ メソッドを ILE RPG プログラムから呼び出す方法について説明します。
メソッドが静的メソッドでない場合、これを「インスタンス・メソッド」と呼びます。 そのメソッドを呼び出すための特別な最初のパラメーターとして、オブジェクト・インスタンスがコーディングされなければなりません。 例えば、インスタンス・メソッドが 1 つのパラメーターを伴ってプロトタイプされている場合であれば、ユーザーは 2 つのパラメーターを指定して呼び出さなければならず、その最初がインスタンス・パラメーターになるようにする必要があります。
- Java メソッドは、既存の命令コード CALLP (戻り値がないと予想される場合) および EVAL (戻り値があると予想される場合) を使用して呼び出すことができます。ユーザーの RPG プロシージャーが Java メソッドを呼び出そうとすると、RPG はその Java 仮想マシン (JVM) が開始済みであるかどうかをチェックします。まだ開始されていない場合は、RPG はユーザーに代わって JVM を開始します。Java 仮想マシン (JVM) の作成で説明されている JNI 機能を使用して、ユーザー自身が JVM を開始することもできます。
- ユーザーが自分のクラス (あるいは通常の java.xxx クラス以外のすべてのクラス)
を使用している場合は、Java
メソッドを呼び出す前にユーザーの CLASSPATH 環境変数を必ずセットアップしておいてください。RPG がユーザーに代わって
JVM を呼び出す時、RPG はユーザーの CLASSPATH 環境変数の中にあるクラスを標準クラスパスへ追加します。
これによって、ユーザーが自分のクラスを使う時に Java はそれらのクラスを見つけることができます。CLASSPATH
環境変数を対話式に設定するには、次のようにします。
ディレクトリーはコロンで分ける必要があります。===>ADDENVVAR ENVVAR(CLASSPATH) VALUE('/myclasses/:/xyzJava/classes/') - 通常、Java は自分自身のガーベッジ・コレクションを行ない、オブジェクトがいつ不要になるかを検出します。ユーザーが非ネイティブ RPG プロシージャーから Java コンストラクターを呼び出すことによってオブジェクトを作成する場合は、Java はそのオブジェクトを破棄してよいということを知る方法がないため、それらを 破棄しません。複数のオブジェクトの同時解放を Java に通知 で説明する JNI 機能を呼び出すことによって、 複数のオブジェクトに対するガーベッジ・コレクションを同時に使用可能にできます。 もうオブジェクトが不要であることをユーザーが 知っている場合は、一時オブジェクトの使用が終了したことを Java に伝えるで説明する JNI 機能を 呼び出すことによって、このことを Java に伝える必要があります。
さまざまな JNI 機能の詳細については、Java を使用するためのその他の RPG コーディングを参照してください。
例 1
この例では、目的は 2 つの BigDecimal 値を一緒に加算することです。これを行なうため、2 つの BigDecimal オブジェクトは BigDecimal クラス用のコンストラクターを呼び出してインスタンス化される必要があり、フィールドは BigDecimal オブジェクトを保管できるように宣言される必要があり、さらに BigDecimal クラスにある add() メソッドが呼び出される必要があります。
* String パラメーターを受け取る BigDecimal コンストラクターのプロトタイプ。
* 新しい BigDecimal オブジェクトを戻します。
* string パラメーターはこのコンストラクターによって変更されないため、
* CONST キーワードをコーディングすることになります。これによって
* コンストラクターの呼び出しがより便利になります。
*
D bdcreate1 PR O EXTPROC(*JAVA:
D 'java.math.BigDecimal':
D *CONSTRUCTOR)
D str O CLASS(*JAVA:'java.lang.String')
D CONST
*
* double パラメーターを受け取る BigDecimal コンストラクターのプロトタイプ。
* 8F は Java の double データ・タイプにマップするため、
* VALUE で渡す必要があります。BigDecimal オブジェクトを戻します。
*
D bdcreate2 PR O EXTPROC(*JAVA:
D 'java.math.BigDecimal':
D *CONSTRUCTOR)
D double 8F VALUE
* BigDecimal オブジェクトを保管するフィールドを定義します。
*
D bdnum1 S O CLASS(*JAVA:'java.math.BigDecimal')
D bdnum2 S O CLASS(*JAVA:'java.math.BigDecimal')
*
* 使用しているコンストラクターのいずれかが、String オブジェクトを
* 必要としているため、これらのコンストラクターのいずれかを作成する必要が
* あります。byte 配列をパラメーターとして受け取る String コンストラクターを
* プロトタイプします。これは String オブジェクトを戻します。
*
D makestring PR O EXTPROC(*JAVA:
D 'java.lang.String':
D *CONSTRUCTOR)
D bytes 30A CONST VARYING
*
* String オブジェクトを保管するフィールドを定義します。
*
D string S O CLASS(*JAVA:'java.lang.String')
*
* BigDecimal 追加メソッドのプロトタイプ。BigDecimal オブジェクトをパラメーター
* として受け取り、BigDecimal オブジェクトを戻します (パラメーターおよび
* BigDecimal オブジェクトの合計が、この呼び出しを行なうために使用されます)。
*
D add PR O EXTPROC(*JAVA:
D 'java.math.BigDecimal':
D 'add')
D CLASS(*JAVA:'java.math.BigDecimal')
D bd1 O CLASS(*JAVA:'java.math.BigDecimal')
D CONST
*
* 合計を保管するフィールドを定義します。
*
D sum S O CLASS(*JAVA:'java.math.BigDecimal')
D
D double S 8F INZ(1.1)
D fld1 S 10A
* Define a prototype to retrieve the String version of the BigDecimal
D getBdString PR O CLASS(*JAVA:'java.lang.String')
D EXTPROC(*JAVA:
D 'java.lang.BigDecimal':
D 'toString')
* Define a prototype to retrieve the value of a String
D getBytes PR 65535A VARYING
D EXTPROC(*JAVA:
D 'java.lang.String':
D 'getBytes')
* Define a variable to hold the value of a BigDecimal object
D bdVal S 63P 5
呼び出しを行なうコードは次の通りです。
* fld1 から String オブジェクトを作成するために、String クラスのコンストラクターを
* 呼び出します。コンストラクターを呼び出しているため、
* 最初のパラメーターとして String オブジェクトを渡す必要はありません。
*
C EVAL string = makestring('123456789012345678901234567890')
*
* インスタンス化したばかりの String オブジェクトを使用して、String パラメーターを
* 受け取る BigDecimal コンストラクターを呼び出します。
*
C EVAL bdnum1 = bdcreate1(string)
*
* double をパラメーターをして受け取る BigDecimal コンストラクターを
* 呼び出します。
*
C EVAL bdnum2 = bdcreate2(double)
*
* add メソッドを呼び出すことにより、2 つの BigDecimal オブジェクトを
* 一緒に加算します。プロトタイプは、add が 1 つのパラメーターを
* 受け取ることを示していますが、add は静的メソッドではないため、
* 呼び出しを行なうために BigDecimal オブジェクトも渡す必要があり、
* かつそれは最初のパラメーターであることが必要です。
* bdnum1 は呼び出しを行なうために使用するオブジェクトで、
* bdnum2 はパラメーターです。
*
C EVAL sum = add(bdnum1:bdnum2)
* ここで sum には bdnum1 + bdnum2 の値を持つ BigDecimal
* オブジェクトが入ります。
C EVAL bdVal = %DECH(getBdString(sum) : 63 : 5)
* val には sum の値が入ります。
* sum の値が、変数 "val" が持つことができる数より大きい場合、
* オーバーフロー例外が発生します。
例 2
この例は、ILE RPG %TRIM 組み込み関数の代わりに trim() メソッドを使用して Java で TRIM を行なう方法について示します。String クラスにある trim() メソッドは静的メソッドではないため、これを呼び出すには String オブジェクトが必要です。
* トリムしたい String オブジェクトを保管するフィールドを定義します。
*
D str S O CLASS(*JAVA:'java.lang.String')
D makestring PR O EXTPROC(*JAVA:
D 'java.lang.String':
D *CONSTRUCTOR)
D CLASS(*JAVA:'java.lang.String')
D parm 65535A CONST VARYING *
* String を byte 配列に変換する String メソッド getBytes のプロトタイプ。
* 変換後はこの byte 配列を alpha フィールドに保管します。
*
D getBytes PR 65535A EXTPROC(*JAVA:
D 'java.lang.String':
D 'getBytes') VARYING
*
* String メソッド trim のプロトタイプ。これはパラメーターは取りませんが、
* 静的メソッドではないため、String オブジェクトを使用して
* 呼び出す必要があります。
*
D trimstring PR O EXTPROC(*JAVA:
D 'java.lang.String':
D 'trim')
D fld S 10A INZ(' hello ') VARYING
この呼び出しは次のようにコーディングされます。
* String コンストラクターを呼び出します。
*
C EVAL str = makestring(fld)
*
* String trim() メソッドを呼び出すことにより、ストリングをトリムします。
* この str フィールドを、結果を保管するために再利用します。
*
C EVAL str = trimstring(str)
*
* ストリングをバイト配列に変換して戻し、
* これを fld に保管します。
*
C EVAL fld = getBytes(str)
C EVAL fld = getBytes()
メソッドが値を戻さない場合は、CALLP 命令コードを使用します。