2019 年 4 月 16 日、 Oracle から Java SE 8u211 / Java SE 8u212 / Java SE 11.0.3 (LTS) / Java SE 12.0.1 がリリースされました。これらのバージョンから新元号 「令和」 に対応しているということなので、 Java での和暦表示を確認してみました。
jlink で JRE を作成する場合には、 ちょっとした工夫が必要になるので、 そういった注意点についても説明していきます。
2019 年、 Java (JDK) の状況は大きく変わりました。Oracle Technology Network (OTN) に登録することで引き続き Java を無償でダウンロードすることができるのですが、 ライセンスが Oracle Binary Code License (BCL) から Oracle Technology Network License に変更されており、 商用 ・ 本番環境での無償利用ができなくなりました。
Java を無償で商用利用する場合は、 Oracle JDK ではなく他の OpenJDK ビルドを使う必要があります。いくつかのコミュニティー、 ベンダーが OpenJDK ビルドを提供しています。
Oracle OpenJDK
もっとも有名な OpenJDK ビルドだと思います。Oracle がスポンサーをしていることから、 他の OpenJDK と区別するために Oracle OpenJDK と呼ばれることもあります。Oracle JDK と名前が似ていますが、 Oracle OpenJDK は Oracle がスポンサーとなっている OpenJDK ビルドであり、 無償での商用利用が可能となっています。
ただし、 Oracle がスポンサーをしているためか、 Oracle OpenJDK も Oracle JDK のサポート ・ ライフ ・ サイクルを色濃く反映しているようです。Oracle JDK には長期サポート (LTS) バージョンがありますが、 Oracle OpenJDK には LTS バージョンがありません。
そのため、 Oracle OpenJDK では新元号 「令和」 に対応した Java 11.0.3 はリリースされませんでした。Oracle OpenJDK で新元号 「令和」 に対応するためには Java 12.0.1 に移行する必要があります。
AdoptOpenJDK
こちらも有名な OpenJDK ビルドです。IBM などがスポンサーになっています。この AdoptOpenJDK の動きはとても早く、 4 月 16 日の Oracle JDK のリリースから遅れることわずか数日、 4 月 19 日には新元号 「令和」 に対応する AdoptOpenJDK 1.8.0_212 と AdoptOpenJDK 11.0.3 がリリースされました。
AdoptOpenJDK は Oracle と同じく Java 8 と Java 11 を長期サポート (LTS) バージョンと位置付けており、 Java 8 を少なくとも 2023 年まで、 Java 11 を少なくとも 2022 年までサポートすると表明しています。
他にも Zulu OpenJDK、 Amazon Corretto という OpenJDK ビルドがありますが、 2019 年 4 月 19 日時点では Java 8u211 / Java 11.0.3 に対応するバージョンはリリースされていませんでした。
というわけで今回は、 AdoptOpenJDK 11.0.3 を使用して、 新元号 「令和」 対応を確認していきます。
AdoptOpenJDK から Java 11.0.3 をダウンロードして、 C:\jdk-11.0.3+7
に展開しました。
以下のソースコードをサンプルとして使います。これは 1 年後の日付を和暦で表示するプログラムです。これを C:\temp\Sample.java
として保存します。文字コードは UTF-8
としています。
Sample.javaimport java.time.LocalDateTime;
import java.time.chrono.JapaneseChronology;
import java.time.format.DateTimeFormatter;
public class Sample {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("GGGG y 年 M 月 d 日")
.withChronology(JapaneseChronology.INSTANCE);
LocalDateTime datetime = LocalDateTime.now().plusYears(1);
String s = formatter.format(datetime);
System.out.println(s);
}
}
コマンドプロンプトを起動して、 環境変数 PATH に C:\jdk-11.0.3+7\bin
を追加します。Java のバージョンが 11.0.3 になっていることも確認しておきましょう。
コマンドプロンプトC:¥WINDOWS¥system32>SET PATH=C:¥jdk-11.0.3+7¥bin;%PATH% C:¥WINDOWS¥system32>java -version openjdk version "11.0.3" 2019-04-16 OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.3+7) OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.3+7, mixed mode)
Sample.java
を保存したフォルダー (C:\temp
) に移動して、 javac
コマンドでソースコードをコンパイルします。
コマンドプロンプトC:¥WINDOWS¥system32>cd C:¥temp C:¥temp>javac -encoding UTF-8 Sample.java
これで、 Sample.class
ができました。次は jar
コマンドを使って実行可能 JAR ファイルを作成します。
コマンドプロンプトC:¥temp>jar --create --file sample.jar --main-class Sample Sample.class
実行可能 JAR ファイル sample.jar
ができました。それでは、 実行してみましょう。
コマンドプロンプトC:¥temp>java -jar sample.jar 令和 2 年 4 月 19 日
ちゃんと、 新元号 「令和」 が表示されていますね。
jlink で JRE を作るときは注意が必要
次に、 jlink
コマンドで JRE を作成して、 その JRE で sample.jar
を実行してみます。jlink
の詳細については、 「アプリケーション配布用に小さな JRE を作る」 をご参照ください。
コマンドプロンプトC:¥temp>jlink --compress=2 --module-path "C:¥jdk-11.0.3+7¥jmods" --add-modules java.base --output jre-11.0.3
これで、 sample.jar
の実行に必要な小さな JRE が C:\temp\jre-11.0.3
に作成されました。この JRE で sample.jar
を実行してみます。
コマンドプロンプトC:¥temp>jre-11.0.3¥bin¥java.exe -jar sample.jar Reiwa 2 年 4 月 19 日
・ ・ ・ なんということでしょう! 元号が 「令和」 ではなく 「Reiwa」 とアルファベットで表示されてしまいました。
アルファベット表記になってはいますが、 これも一応、 和暦表示ですね。どうやら、 英語圏向けの和暦表示になってしまっているようです。こういったときは、 プログラムもしくはプラットフォームが日本語ロケールではなく英語ロケールに設定されているとか、 もしくは、 日本語ロケール用のリソースが欠落している、 といったことが疑われます。
調べてみると、 ロケールとモジュールについて説明しているページが見つかりました。
java.base
モジュールには英語ロケールのデータのみが含まれていて、 他の言語ロケールのデータは jdk.localedata
モジュールに含まれるとのことでした。
というわけで、 jdk.localedata
も含めて JRE を作り直してみます。
コマンドプロンプトC:¥temp>jlink --compress=2 --module-path "C:¥jdk-11.0.3+7¥jmods" --add-modules java.base,jdk.localedata --output jre-11.0.3 C:¥temp>jre-11.0.3¥bin¥java.exe -jar sample.jar 令和 2 年 4 月 19 日
今度は新元号 「令和」 が漢字で出力されています。しかし、 jre-11.0.3 のサイズが 26.8MB から 35.7MB と 9MB 以上も増加してしまいました。jdk.localedata
モジュールには日本語ロケールのデータだけでなく、 各国の様々なロケールデータが含まれているので、 サイズがとても大きいのです。
この jdk.localedate
のサイズ増加問題に対処するため、 jlink には include-locales というプラグインが用意されています。プラグインですが jlink に同梱されているので別途入手する必要はありません。jlink のオプションとして --include-locales=
を指定するだけで使用できます。
英語ロケールと日本語ロケールのみを含める場合は --add-modules jdk.localedata
と一緒に --include-locales=en,ja
を指定します。
コマンドプロンプトC:¥temp>jlink --compress=2 --module-path "C:¥jdk-11.0.3+7¥jmods" --add-modules java.base,jdk.localedata --include-locales=en,ja --output jre-11.0.3 C:¥temp>jre-11.0.3¥bin¥java.exe -jar sample.jar 令和 2 年 4 月 19 日
こうすると、 jdk.localedata
モジュールのすべてが含まれるのではなく、 指定したロケールのデータのみが JRE に含まれるようになります。jre-11.0.3 のサイズは 27.1MB となりました。jdk.localedata
モジュールをまったく含めなかった場合と比較して、 300KB 程度のサイズ増加に収まっています。このくらいのサイズなら気にならないですよね。
というわけで、 jlink で作成した JRE で和暦表示など日本語ロケールに応じた表示を必要とする場合は jdk.localedata
モジュールも指定するようにしましょう。jdk.localedata
モジュールは、 jdeps の --list-deps
で依存モジュールとして出てこないので、 忘れず明示的に jlink の --add-modules
に指定する必要があります。