opensource COBOL 4J はじめの一歩

# はじめに
COBOLをお持ちのIT部門の方より、現在のCOBOL資産をJavaに移行したいという相談をよく聞きます。この記事では、そのような検討をしているご担当者様向けに、オープンソースソフトウェア（以下、OSS）の **opensource COBOL 4J** による COBOL to Java 変換を試す手順をご紹介します。

https://github.com/opensourcecobol/opensourcecobol4j

# opensource COBOL 4Jとは
[opensource COBOL 4J](https://github.com/opensourcecobol/opensourcecobol4j) は、[OSSコンソーシアム](https://www.osscons.jp/)が開発して Github で公開しているOSSのCOBOLコンパイラです。COBOLコンパイルの過程で、COBOLを中間Javaソースに変換し、Javaコンパイラでバイトコードを生成する仕組みです。処理の流れは下図のとおりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728615/124efabc-24b0-1123-f417-a08d0a95f4e2.png)

兄貴分の [opensource COBOL](https://github.com/opensourcecobol/opensource-cobol) やその親の [OpenCOBOL (GnuCOBOL)](https://sourceforge.net/projects/gnucobol/)は、COBOLをC言語に変換する仕組みですが、これをJavaに変換するように移植したものが opensource COBOL 4J です(4J = for Java)。NISTのCOBOL85テストを通過しており、COBOL85の構文をJavaで再現しています。

opensource COBOL 4Jは、OSSライセンス（コンパイラがGPL3、ランタイムライブラリがLGPL3）で公開されており、誰でもダウンロードして利用可能です。中間Javaソースが残るため、COBOL to Java変換を実現する方式の1つとして注目を集めています。

でも、評価をするためには、Linuxサーバーを準備したり、前提ソフトウェアを導入したり、makeでエラーが起きたら解決策を探したり、少しだけ手間がかかります。この記事では、OSSコンソーシアムが [Docker Hubで公開しているコンテナ](https://hub.docker.com/r/opensourcecobol/opensourcecobol4j) を使い、お手元のWindows PCで手っ取り早く COBOL to Java 変換を試す手順を紹介します。

# 手順1. まずは Docker をインストールする
[Docker Desktop for Windows](https://www.docker.com/get-started) をダウンロードし、**Docker Desktop Installer.exe** をダブルクリックしてインストールを開始します。インストール後、Dockerアプリケーションを起動します。ステータスバーにクジラのアイコンが表示されれば、Docker Desktopは起動・実行中です。アイコンが赤い場合は、クジラを右クリックして、restartを選択してください。

https://www.docker.com/get-started

# 手順2. opensource COBOL 4J コンテナを作成
Dockerを起動後、コマンドプロンプトを開いて下記コマンドを実行します。

```console
docker run -itd -v /c/Develop/share:/root/share --name cobol4j opensourcecobol/opensourcecobol4j
```
opensource COBOL 4J がインストールされたコンテナ **cobol4j** が作成されます。PCの **C:\Develop\share** フォルダは、コンテナ内の **/root/share** にマウントされています。

# 手順3. サンプルプログラムを作成

**C:\Develop\share** に **HELLO.cbl** という名前で下記のサンプルプログラムを作成します。

```text: HELLO.cbl
      ******************************************************************
       IDENTIFICATION              DIVISION.
      ******************************************************************
       PROGRAM-ID.                 HELLO.
       AUTHOR.                     HIROIMON.
       DATE-WRITTEN.               2022-07-01.
      ******************************************************************
       DATA                        DIVISION.
      ******************************************************************
       WORKING-STORAGE             SECTION.
       01  MY-TEXT                 PIC X(40).
      ******************************************************************
       PROCEDURE                   DIVISION.
      ******************************************************************
       MAIN-RTN.
           MOVE "HELLO WORLD!" TO MY-TEXT.
           DISPLAY MY-TEXT.
           STOP RUN.
```

# 手順4. コンパイルと実行確認
コマンドプロンプトより、下記のコマンドでコンテナ **cobol4j** を起動してアタッチします。
```console
docker start cobol4j
docker attach cobol4j
```
:::note info
手順2で docker run -itdをした後であれば、docker startは不要です。
:::
アタッチをした後、**/root/share** に先ほど作成した **HELLO.cbl** があることを確認します。
```console
# cd /root/share
# ls -l
total 4
-rwxrwxrwx 1 root root  937 Nov 29 09:55  HELLO.cbl
```
opensource COBOL 4J の **cobj** コマンドを実行します。このコマンド一発で、COBOL to Java変換による **HELLO.java** の作成と、その後の **javac** コマンドの起動が行われ、**HELLO.class** が生成されます。
```console
# cobj HELLO.cbl
# ls -l
total 36
-rw-r--r-- 1 root root 1187 Nov 29 09:59 'HELLO$1.class'
-rw-r--r-- 1 root root 1187 Nov 29 09:59 'HELLO$2.class'
-rw-r--r-- 1 root root 1187 Nov 29 09:59 'HELLO$3.class'
-rw-r--r-- 1 root root 1635 Nov 29 09:59 'HELLO$4.class'
-rwxrwxrwx 1 root root  937 Nov 29 09:55  HELLO.cbl
-rw-r--r-- 1 root root 5677 Nov 29 09:59  HELLO.class
-rw-r--r-- 1 root root 6102 Nov 29 09:59  HELLO.java
```
**java** コマンドでサンプルの動作確認をします。コンソールに **HELLO WORLD!!** が出力されました。COBOLのプログラムが無事にJavaに移行されていることが確認できました。
```console
# java HELLO
HELLO WORLD!
```
**exit** でコンテナから抜けてコマンドプロンプトに戻り、コンテナ **cobol4j** を停止しました。
```console
# exit
docekr stop cobol4j
```
# そして、Javaプログラムを見てみる
ディレクトリ **C:\Develop\share** に **HELLO.java** が生成されています。
下記は、COBOLの手続き部やデータ部の初期化に相当する箇所を抜粋したコードです。COBOLの変数名や手続き部の該当行がコメントで生成されています。COBOLの各命令は、**opensource COBOL 4Jランタイムライブラリ(libcobj.jar)** が提供する様々なclassに変換されています。このランタイムライブラリのJavaプログラムもOSSで公開されていますので、ブラックボックスはありません。
OSSコンソーシアムやコミュニティでは、処理性能の改善や可読性の向上が議論されています。今後のリリースにも期待です。

```java:HELLO.java
  public CobolControl[] contList = {
    new CobolControl(0, CobolControl.LabelType.label) {
      public Optional<CobolControl> run() throws CobolRuntimeException, CobolGoBackException, CobolStopRunException {
        return Optional.of(contList[1]);
      }
    },
/* ＜中略＞ */
    /* MAIN-RTN */
    new CobolControl(3, CobolControl.LabelType.label) {
      public Optional<CobolControl> run() throws CobolRuntimeException, CobolGoBackException, CobolStopRunException {
        /* HELLO.cbl:16: MOVE */
        {
          f_MY_TEXT.moveFrom (c_1);
        }
        /* HELLO.cbl:17: DISPLAY */
        {
          CobolTerminal.display (0, 1, 1, f_MY_TEXT);
        }
        /* HELLO.cbl:18: STOP */
        {
          CobolStopRunException.throwException (b_RETURN_CODE.intValue());
        }
        return Optional.of(CobolControl.pure());
      }
    },
    CobolControl.pure()
  };
/* ＜中略＞ */
  public void init()
  {
    try {
      cob_unifunc = null;
      b_RETURN_CODE = new CobolDataStorage(4);	/* RETURN-CODE */
      b_MY_TEXT = new CobolDataStorage(40);	/* MY-TEXT */
      initAttr();
      f_MY_TEXT	= CobolFieldFactory.makeCobolField(40, b_MY_TEXT, a_1);	/* MY-TEXT */
      c_1	= CobolFieldFactory.makeCobolField(12, "HELLO WORLD!", a_1);
    } catch(Exception e) {
      e.printStackTrace();
    }
  }
```

# まとめ
いかがだったでしょうか。
今回は、opensource COBOL 4J はじめの一歩として、Dockerコンテナを使って COBOL to Java 変換を試す手順をご紹介しました。ご検討中の方々の参考になれば幸いです。
今後も少しずつ opensource COBOL 4J を堀り下げてご紹介していきます。

以上