【Docker】同じソースコードを複数バージョンのJDKで実行する方法

f:id:shogonir:20180207221136p:plain

 

目次

  1. この記事の目的
  2. ソースコードを準備する
  3. Dockerコンテナ上でコンパイルと実行
  4. 複数バージョンのJDKで実行
  5. まとめ

 

1. この記事の目的

同じソースコードを複数バージョンのJDKで実行する方法を紹介します。
これができると、JDKごとにパフォーマンス測定などが気軽にできるようになります。
実際に文字列連結処理のパフォーマンス測定を行った記事が下記です。

shogonir.hatenablog.com

 

今回は仮想環境を準備した方が楽なのでDockerを使いました。
ソースコードGitHubにあげました。

github.com

 

2. ソースコードを準備する

実行するJavaソースコードを準備します。
今回は文字列の連結をStringStringBuilderで行うソースコードを準備しました。

 

public class StringConcatWithOperator {

    public static void main (String[] args) {
        
        long startTime = System.currentTimeMillis();

        String message = "";

        for (int i = 0; i < 100 * 1000; i++) {
            message += "a";
        }
        
        long endTime = System.currentTimeMillis();

        System.out.println("    " + (endTime - startTime) + "ms");
    }
}

 

public class StringConcatWithBuilder {

    public static void main (String[] args) {
        
        long startTime = System.currentTimeMillis();

        StringBuilder builder = new StringBuilder();

        for (int i = 0; i < 100 * 1000; i++) {
            builder.append("a");
        }

        String message = builder.toString();
        
        long endTime = System.currentTimeMillis();

        System.out.println("    " + (endTime - startTime) + "ms");
    }
}

 

3. Dockerコンテナ上でコンパイルと実行

Dockerに関する説明は割愛します。
今回はopenjdkのイメージを使用します。

まずはDockerコンテナ内で実行するシェルスクリプトを準備します。
このスクリプトの中でJavaソースコードコンパイル・実行します。
Javaソースコードはコンテナの/javaにあるものとします。

 

cd /java

echo "  concat with operator"
javac StringConcatWithOperator.java
java  StringConcatWithOperator

echo "  concat with builder"
javac StringConcatWithBuilder.java
java  StringConcatWithBuilder

 

次にこのシェルスクリプトをコンテナ内で実行するDockerコマンドを紹介します。

 

docker run --rm -v $(pwd):/java -it openjdk:8 sh /java/execute.sh

 

docker run -it openjdk:8 sh /java/execute.shとすることで、openjdkのコンテナでsh /java/execute.shを実行できます。
openjdk:8はイメージの名前とタグで、タグの8JDKのバージョンに対応しています。
--rmオプションをつけることで、実行が終わった段階でDockerプロセスを閉じます。
-v $(pwd):/javaでカレントディレクトリと、コンテナ内の/javaを同期します。
こうすることでカレントディレクトリにあるJavaソースコードをコンテナ内に置きます。

 

4. 複数バージョンのJDKで実行

あとは上記のコマンドを複数のバージョンで実行するだけです。
具体的にはイメージのタグを変更してopenjdk:9openjdk:10にします。

普通はシェルスクリプトで行うのだと思いますが、ゆとりの私はPythonを使いました。

 

#! /usr/bin/env python
# -*- coding:utf-8 -*-


import os


if __name__ == '__main__':
    
    for jdk_version in range(8, 11):
        
        image = 'openjdk:{0}'.format(jdk_version)
        command = 'java/execute.sh'
        docker = 'docker run --rm -v $(pwd):/java -it {0} sh {1}'.format(image, command)
        
        print docker
        os.system(docker)

 

5. まとめ

今回はDockerを使って、同じソースコードを複数バージョンのJDKで実行する方法を紹介しました。
こういう時はDockerの便利さが際立ちます。
「環境構築しようかな」と思ったらDockerのことを思い出すようにしたいです。