「Java」「COBOL」Java から OpenCOBOL を呼び出す

Java から COBOL ( OpenCOBOL ) 呼び出してみたので、その時のメモ。
インタフェースには JNI を使います。

[ 環境情報 ]
CentOS 6.2
Java SE 7 Update 21
OpenCOBOL 2.0
GCC 4.4.7

※ 今回作業ディレクトリは "/usr/local/tmp/javatocobol" としています。
Java のインストールディレクトリは "/usr/local/java/jdk1.7.0_21" になります。
OpenCOBOL のインストールディレクトリは "/usr/local/cobol/2.0" になります。

1. COBOL プログラムの作成 ( hello.cob )

      *Sample COBOL program
       IDENTIFICATION DIVISION.
       PROGRAM-ID. hello.
       PROCEDURE DIVISION.
       DISPLAY "**** Hello World".
       EXIT PROGRAM.


2. Java プログラムの作成 ( Hello.java )

class Hello {

  public native void hello();

  public static void main(String[] args) {
    System.loadLibrary("Hello");
    Hello inst = new Hello();
    System.out.println("java start");
    inst.hello();
    System.out.println("java end");
  }
}


3. C プログラムの作成 ( Hello.c )

#include "Hello.h"
#include <stdio.h>
#include <libcob.h>

extern int hello();

JNIEXPORT void JNICALL Java_Hello_hello(JNIEnv *env, jobject obj)
{
  printf("**jni stat\n");
  cob_init(0, NULL);
  hello();
  printf("**jni end\n");
}


4. コンパイル

cobc -c -static hello.cob
gcc -shared -I /usr/local/java/jdk1.7.0_21/include/ -I /usr/local/java/jdk1.7.0_21/include/linux/ -L /usr/local/cobol/2.0/lib/ -lcob hello.o `cob-config --cflags` -o libHello.so Hello.c


上記で作業は完了です。以下の出力が得られれば成功かと。

java -Djava.library.path=/usr/local/tmp/javatocobol Hello
java start
**jni stat
**** Hello World
**jni end
java end


きっと C 言語辺りの知識があれば、もっともっとスマートなやり方はあるはずです。
ただ、現状の僕にはこれが限界です。眠いし ( 言い訳・・・ )。

以上です。


■ 追記
すみません。上記の内容だけで Hello.class を実行すると、以下のようなエラーが発生します。

Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/local/tmp/javatocobol/libHello.so: libcob.so.4: 共有オブジェクトファイルを開けません: そのようなファイルやディレクトリはありません
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1939)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1864)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1854)
        at java.lang.Runtime.loadLibrary0(Runtime.java:845)
        at java.lang.System.loadLibrary(System.java:1084)
        at Hello.main(Hello.java:6)

ldd で libHello.so を確認すると確かに not found になってます。

        linux-gate.so.1 =>  (0x00bb0000)
        libcob.so.4 => not found
        libc.so.6 => /lib/libc.so.6 (0x00110000)
        /lib/ld-linux.so.2 (0x008bc000)

なので、"/usr/local/cobol/2.0/lib" を環境変数 LD_LIBRARY_PATH に設定するか /etc/ld.so.conf に追記 ( ldconfig ) してあげてください。これでうまくいくはずです。