2019-04-19  Java プログラミング

Java 11で和暦 - 新元号「令和」を表示する

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.java
import 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 に指定する必要があります。

最終更新日 2024-12-16
この記事を共有しませんか?
ブックマーク ポスト