ここでは、COBOL と Java のデータ型の対応関係について説明します。
Java 言語では、COBOL で使用されるデータ形式とは異なる、Java 用のデータ型が定義されています。図 6-1 に示すように、COBOL から Java (または Java から COBOL) が呼び出されると、COBOL ランタイムシステムによって COBOL と Java 間でデータ型が自動的に変換されます。

図 6-1: COBOL と Java 間のデータマッピング
数値データ形式は、COBOL プログラムが手続き型、オブジェクト指向のどちらで作成されている場合も同じように変換されますが、オブジェクトや文字列の場合はこれらの作成手法によって変換結果が異なります。
オブジェクト COBOL では Java オブジェクトは COBOL オブジェクト参照として扱われますが、手続き型 COBOL ではポインタとして扱われます。
COBOL から Java にデータを送信するときには、そのデータが適切な Java データ型に変換されます。同様に、Java プログラムが COBOL にデータを返信するときにも、Java データ型から COBOL データ形式への変換が行われます。次の表は、Java と COBOL の間でデータがやり取りされるときに行われる型変換を示しています。一部のデータ型は、手続き型 COBOL (『Java からの手続き型 COBOL の呼出し』の章を参照) と オブジェクト COBOL の Java ドメイン (『オブジェクト COBOL からの Java の呼出し』および『Java からのオブジェクト COBOL の呼出し』の章を参照) では扱いが異なる場合があります。表中の「COBOL」欄は、.cobcall(…) で手続き型 COBOL に適用される規則、「オブジェクト COBOL」欄は .cobinvoke() でオブジェクト COBOL Java ドメインに適用される規則を示しています。
| Java データ型 | COBOL データ形式 .cobcall(...) 使用 |
オブジェクト COBOL データ形式 .cobinvoke() 使用 |
説明 |
|---|---|---|---|
| byte | pic s99 comp-5 | pic s99 comp-5
pic s99 comp |
1 バイトの符号付き整数 |
| short | pic s9(4) comp-5 | pic s9(4) comp-5
pic s9(4) comp |
2 バイトの符号付き整数 |
| int | pic s9(9) comp-5 | pic s9(9) comp-5
pic s9(9) comp |
4 バイトの符号付き整数 |
| long | pic s9(18) comp-5 | pic s9(18) comp-5
pic s9(18) comp 1 |
8 バイトの符号付き整数 |
| boolean | pic 99 comp-5 | pic 99 comp-5 | 0 は false、0 以外の値はtrue |
| char (Unicode) | pic 9(4) comp-5 | pic s9(4) comp | Java の文字はすべてダブルバイトの Unicode 文字で表される。 |
| float | comp-11 | comp-1 1 | 浮動小数点数値 |
| double | comp-2 1 | comp-2 1 | 倍精度浮動小数点数値 |
| String | mf-jstring 2
pointer 3 |
pic x(n) | 容量は常に 0。COBOL プログラムに渡される文字列は読み取り専用で、変更できないものと考える必要がある。 |
| StringBuffer | mf-jstring 2
pointer 3 |
pic x(n) | 容量はバッファの合計サイズで、サイズはバッファに格納されている文字列の長さ |
| objects | pointer | オブジェクト参照 | あらゆる Java オブジェクト。手続き型 COBOL では、返されたポインタを JNI 呼出しに使用できる (『Java からの手続き型 COBOL』の章の『COBOL での JNI の使用』の節を参照)。 |
| object[] | pointer | jarray クラスのインスタンスへのオブジェクト参照 | Java オブジェクトの配列。手続き型 COBOL では、返された JNI 呼出しに使用できる (『Java からの手続き型 COBOL の呼出し』の章の『COBOL での JNI の使用』を参照)。jarray は Java 配列の内容にアクセスするためのオブジェクト COBOL クラス (『Jarray クラスの使用』の節を参照)。 |
| DataType | 構造体 | 構造体 | 複合データ構造体 |
| Comp3 | comp-3 | comp-3 | COMP(UTATIONAL)-3 または PACKED-DECIMAL |
| Pointer(StringBuffer)
Pointer(String, int capacity) |
pic x(99) | pic x(99) | String や StringBuffer をラップすることによって、正しいサイズが割り当ててられた状態で COBOL プログラムに渡し、COBOL 側で Java オブジェクトを安全に編集できるようにする。
StringBuffer の容量は、COBOL 側で編集可能な最大長として使用される。 |
| java.sql.Date(long)
CobolDate(date) |
0x jyear pic 9(4).
0x filler pic x. 0x jmonth pic 99. 0x filler pic x. 0x jday pic 99. |
cobcall と同じ | JDBC で使用される標準 SQL Date 型 |
| java.sql.time(long)
CobolTime(time) |
0x jhour pic 99.
0x filler pic x. 0x jminute pic 99. 0x filler pic x. 0x jseconds pic 99. |
cobcall と同じ | JDBC で使用される標準 SQL Time 型 |
|
CobolBigDecimal(java.math.BigDecimal) |
pic s9(19)v9(19) comp-3 | cobcall と同じ | COBOL 側での BigDecimal 値の更新を可能にする CobolBigDecimal ラッパークラス。CobolBigDecimal() のコンストラクタは初期値をとる。更新後の値を取得するには、getValue() メソッドを使用する。 |
|
CobolBigInteger(java.math.BigInteger) |
pic S9(38) comp-3 | cobcall と同じ | COBOL 側での BigInteger 値の更新を可能にする CobolBigInteger ラッパークラス。CobolBigInteger() のコンストラクタは初期値をとる。更新後の値を取得するには、getValue() メソッドを使用する。 |
| CustomRecord | 構造体 | 構造体 | Java でオブジェクト配列として表される複合データ構造体 |
| CobolNational | pic x(n) (usage 句に national を使用) | cobcall と同じ | UTF-16 文字列を生成して COBOL に渡すための Java クラス。 |
脚注:
参照渡しのみ。浮動小数点データ型の場合は、この制約が適用されるのは UNIX プラットフォームに限定されます。long データ型の場合は、32 ビットプラットフォームでは参照渡しのみ、64 ビットプラットフォームでは参照渡しと値渡しが可能です。
.cobcall(...) で mf-jstring を使用します。受信側の COBOL プログラムで Java の String または StringBuffer にアクセスするには、ptr2string ポインタを使用する必要があります。mf-jstring を使用すると、COBOL プログラムから Java オブジェクトのサイズと容量にアクセスできます。
.cobcall(...) でポインタを使用します。
「COBOL データ形式」欄と「オブジェクト COBOL データ形式」欄のどちらにも含まれない COBOL データ形式への変換はサポートされていません。ここに挙げられていない型の COBOL データ項目を使用するには、サポートされる型の中間データ項目を使用して、必要なデータ項目の中間データ項目との間でデータを転記します。
コピーファイル javatypes.cpy には、Java データ型に対応する一連の COBOL データ形式が定義されており、Java で使用するデータ項目を COBOL プログラム内で宣言するときに利用できます。このコピーファイルは、$COBDIR/cpylib ディレクトリ内にあります。
これらの型定義を次の表に示します。いずれも先頭文字が j になっています。
| 型定義 | COBOL 形式 |
|---|---|
| jbyte | pic s99 comp-5 |
| jshort | pic s9(4) comp-5 |
| jint | pic s9(9) comp-5 |
| jlong | pic s9(18) comp-5 |
| jboolean
JNI-TRUE is true JNI-FALSE is false |
pic 99 comp-5 |
| jchar | pic 9(4) comp-5 |
| jfloat | comp-1 |
| jdouble | comp-2 |
| jobject | pointer |
| jbigdecimal | pic s9(19)v9(19) comp-3 4 |
| jbiginteger | pic s9(38) comp-3 4 |
| mf-sql-date
(javatypes.cpy での定義) |
0x jyear pic 9(4).
0x filler pic x. 0x jmonth pic 99. 0x filler pic x. 0x jday pic 99. |
| mf-sql-time
(javatypes.cpy での定義) |
0x jhour pic 99.
0x filler pic x. 0x jminute pic 99. 0x filler pic x. 0x jseconds pic 99. |
脚注:
これらの型定義を使用するすべてのプログラムは、INTLEVEL 4 指令でコンパイルする必要があります。
jarray クラスは、オブジェクト COBOL で Java 配列を操作するためのラッパーです。詳細は、 『Java Run-time Class Library』で説明されています。
次の COBOL プログラムは Java オブジェクトから配列を受け取り、次元を検出して、配列の内容を表示します。
$set ooctrl(+p-f)
Program-id. ReadArray.
class-control.
arraydemo is class "$Java$arraydemo"
.
thread-local-storage section.
01 aJavaObj object reference.
01 theTotal pic 9(9).
01 CDims pic x(4) comp-5.
01 Dims.
03 Dims-entry pic x(4) comp-5 occurs 256.
01 Bounds.
03 Bounds-entry pic x(4) comp-5 occurs 256.
01 ind0 pic x(4) comp-5.
01 ind1 pic x(4) comp-5.
01 arrayElement pic x(4) comp-5.
01 wsTable object reference.
01 wsResult pic x(4) comp-5.
procedure division.
invoke arraydemo "new" returning aJavaObj
invoke aJavaObj "getArray" returning wsTable
*> 配列内の要素数を調べます。
invoke wsTable "getDimensions" returning CDims
display "配列は " CDims " 次元です。"
*> 各次元の要素数を取得します。
display "次元は " with no advancing
invoke wsTable "getBounds" using Bounds
perform varying ind0 from 1 by 1 until ind0 > CDims
display Bounds-entry(ind0) with no advancing
if ind0 < CDims
display " by " with no advancing
end-if
end-perform
display " "
*> 配列内の各要素を表示します。
perform varying ind0 from 0 by 1
until ind0 = Bounds-entry(1)
move ind0 to Dims-entry(1)
perform varying ind1 from 0 by 1
until ind1 = Bounds-entry(2)
move ind1 to Dims-entry(2)
invoke wsTable "getElement" using
by value CDims
by reference Dims
by reference arrayElement
display "要素 " ind0 ","
ind1 " は " arrayElement
*> 配列の内容を変更します。
add 50 to arrayElement
invoke wsTable "putElement" using
by value CDims
by reference Dims
by reference arrayElement
end-perform
end-perform
この ReadArray プログラムで使用される arraydemo クラスの実装を次に示します。このプログラムは 2 次元配列を生成します。
import com.microfocus.cobol.*;
import java.io.*;
public class arraydemo extends RuntimeSystem
{
int myArray[][];
public arraydemo()
{
myArray = new int[5][2];
int i,j;
for (i = 0; i < 5; i++)
{
for (j = 0; j < 2; j++)
myArray[i][j] = i * 100 + j;
}
}
public int[][] getArray()
{
return myArray;
}
}
com.microfocus.cobol.lang で定義されている ParameterList() クラスは、Java と COBOL の間でパラメータをやり取りする手段として役立ちます。
ParameterList() は通常、次の形式で使用します。
RuntimeSystem.cobcall("myProgram",
new ParameterList()
.add(myOneInt,RuntimeSystem.BY_VALUE)
.add(mySecondParameter,RuntimeSystem.BY_REFERENCE)
.add(99) // 数値 99 の参照渡し
);
パラメータの内容は、次のとおりです。
| myProgram | 呼び出すプログラムの名前 |
| myOneInt | 値渡しする整数型パラメータ |
| mySecondParameter | 参照渡しするパラメータ |
| 99 | 参照渡しする数値 |
COBOL プログラムやオブジェクト COBOL のメソッドでは、連絡節で構造体を使用し、Java クラスから渡されたデータをその中に格納することが可能です。ただし、対応する Java 側のパラメータが、com.microfocus.cobol.lang.Datatype または com.microfocus.cobol.lang.CustomRecord を実装したオブジェクトであることが前提になります。次にこれらのインターフェイスの定義を示します。
package com.microfocus.cobol.lang;
public interface DataType
{
void synchronizeData();
byte[] getBytes();
}
および
package com.microfocus.cobol.lang;
public interface CustomRecord
{
public Object[] getParameters();
public void setParameters(Object[] parms);
}
com.microfocus.cobol.lang.Datatype/com.microfocus.cobol.lang.CustomRecord を使用すると、複雑な構造のデータを COBOL のプログラムやメソッドに渡すことができます。多数の基本データ型でインターフェイスを作り直す必要はありません。
com.microfocus.cobol.lang.Datatype インターフェイスを実装したクラスの例が、mfcobol.jar で定義されている com.microfocus.cobol.lang.Pointer です。com.microfocus.cobol.lang.Pointer のコンストラクタを次に示します。
/* String initString から Pointer オブジェクトを作成します。 */ public Pointer(String initString); /* StringBuffer initString から Pointer オブジェクトを作成します。 */ public Pointer(StringBuffer initString); /* capacity で指定されるバイト数の Pointer オブジェクトを作成します */ /* (initString の文字数が capacity より小さい場合は、 */ /* 余剰部分は空白文字でパディングされます)。 */ public Pointer(String initString, int capacity);
カスタムレコードは、既存の COBOL プログラムに集団項目を渡すのに実用的です。.cobcall 機能とともに使用します。
CustomRecord インターフェイスの定義を次に示します。
package com.microfocus.cobol.lang;
public interface CustomRecord
{
public Object[] getParameters();
public void setParameters(Object[] parms);
}
RecordDemo2 の customerDetails は次のように定義されています。
01 customerDetails.
03 customerName pic x(30).
03 customerAddress pic x(30).
03 customerRef pic 9(6).
Java による CustomRecord インターフェイスの実装例を次に示します。
import com.microfocus.cobol.lang.*;
import java.text.*;
public class RecordData implements
com.microfocus.cobol.lang.CustomRecord
{
private String customerName;
private StringBuffer customerAddress;
private int customerRef;
RecordData(String name, String address, int ref)
{
customerName = name;
customerAddress = new StringBuffer(address);
customerRef = ref;
}
public String getCustomerName()
{
return this.customerName;
}
public String getCustomerAddress()
{
return this.customerAddress.toString();
}
public int getCustomerRef()
{
return this.customerRef;
}
public Object[] getParameters()
{
String strCustomerRef =
Integer.toString(this.customerRef);
while(strCustomerRef.length() < 6)
{
strCustomerRef = "0"+strCustomerRef;
}
customerAddress.setLength(30);
/* 必ず正しい長さを指定してください。 */
customerAddress.ensureCapacity(30);
return new ParameterList()
.add(new Pointer(this.customerName,30))
.add(this.customerAddress)
.add(strCustomerRef.getBytes())
.getArguments();
}
public void setParameters(Object[] parms)
{
Pointer ptr = (Pointer)parms[0];
this.customerName = ptr.toString();
this.customerAddress = (StringBuffer)parms[1];
byte[] byteCustomerRef = (byte[])parms[2];
this.customerRef =
Integer.parseInt(new String(byteCustomerRef));
}
public String toString()
{
return "Customer Name : "+this.customerName+"\n"+
"Customer Address : "+this.customerAddress+"\n"+
"Customer Ref : "+this.customerRef;
}
}
本 COBOL 開発システムには、Java から COBOL の構造体にデータを渡す方法を示すサンプルプログラムが付属しています。製品のインストール先の $COBDIR/demo/javademo/oocobol/record と $COBDIR/demo/javademo/cobol/record ディレクトリには、サンプルプログラムのすべての関連ファイルと、それらを詳細に説明しているファイル readme.txt が格納されています。