CentOSのOpenJDKについてちょっとだけ調べた
最近、JDKの話題をTLで見ることが増えましたね。
どれを使えばよいのかは人それぞれだと思いますが、以下をひと通り読むと良さそうです。
- 今後のJavaのサポートやアップデートについてJavaチャンピオンが執筆したドキュメント、Java is Still Freeの日本語訳を公開
- (2019年4月時点)JVM言語を使う方がどのJDK/JVMを使うか?アンケートと考察まとめ
- 有償化やEOLに関して誤解があるけど、様々なクラウドやサービス系企業でJava/JVMが使われ続けてるよって話
- Red HatがOpenJDK 8 / 11 LTSの修正を主導することへの見解や反響
- OpenJDK 8u212/11.0.3 LTS以降でのリリースノートや脆弱性の追い方
- 「Java 有償化」で誤解する人になるべく分かりやすく説明するためのまとめ
- OpenJDK まとめ(2019年5月6日版)
- JDKの新しいリリース・モデルおよび提供ライセンスについて
ところで、Oracle Code Tokyo 2019で@yamadamnさんのセッションがあるみたいですよ。
Oracle Code Tokyo、私も「最適なOpenJDKディストリビューションの選び方」って内容で登壇予定です。JJUG CCCの前日ですが、よろしければご参加ください。https://t.co/FwHu7ulpvn
— Takahiro YAMADA (@yamadamn) April 15, 2019
ここからがこの記事の本題です。
そういえば、CentOSでもOpenJDK 11がyumでインストール出来るなーという事を思い出し、
Red HadのOpenJDK 11と何が違うのか気になったので調べてみました。
まず、Twitterで「openjdk centos
」というキーワードで検索すると以下が見つかります。
RHEL の openjdk ソース群に必要に応じて修正を加えたソースからビルドされているようです。
— jfut (@jfut) April 25, 2019
そのため、CentOS 独自の修正があっても無くても、ビルド環境が違うので RHEL のバイナリとハッシュ値まで同じ完全に同一なバイナリではないようです。https://t.co/5CZDtrb3GXhttps://t.co/W3Ixq0QbIs
なるほどなるほど。
CentOSのOpenJDK 11のrpmソースはここですね。
https://git.centos.org/rpms/java-11-openjdk/commits/c7
コミットを見てみると、java-11-openjdk-11.0.2.7-0.el7_6
と、
java-11-openjdk-11.0.3.7-0.el7_6
の差分はこの1つだけでした。
https://git.centos.org/rpms/java-11-openjdk/c/d00a18099714d5f49ee7fb611210853246445912?branch=c7
更に、Filesディレクトリとspecファイルのchangelogを見てみると、
ソースファイルはshenandoah-jdk11-shenandoah-jdk-11.0.3+7.tar.xz
を使い、
Upstream(shenandoah-jdk11)にマージされていないパッチはこのディレクトリで管理・適用されているようです。
CentOSのrpmソースを見ても、shenandoah-jdk11-shenandoah-jdk-11.0.3+7.tar.xz
をどこからダウンロードしてるのかわからなかったのですが、Fedoraの方を見るとOpenJDKのshenandoah/jdk11
みたいですね。
- OpenJDKのshenandoah/jdk11
- Fedoraのrpmソースにあるshellスクリプト
誰がメンテしてくれてるのかなと思って、specファイルのchangelogを見てみると、CentOSもFedoraもRed Hatの人達が2〜3人でメンテしてくれているようです。
ちなみに、Shenandoahっていうのは、Red Hatが開発している新しいGCアルゴリズムです。
JDK 12から入ってます。
- Shenandoah GC
- JEP 189: Shenandoah: A Low-Pause-Time Garbage Collector (Experimental)
- OpenJDKの新しいガベージ・コレクタ
上記Shenandoah GCのwikiを見ると、Backports to JDK 8u and JDK 11u are available as well
って書いてるので、ちょっと確認してみましょう。
$ docker container run --rm -it centos:7.6.1810 bash
[root@a860c23cf664 /]# yum install -y java-11-openjdk-devel
[root@a860c23cf664 /]# java -version
openjdk version "11.0.3" 2019-04-16 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.3+7-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.3+7-LTS, mixed mode, sharing)
[root@a860c23cf664 /]# java -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal 2>/dev/null | egrep "Use.*GC "
bool UseAdaptiveSizePolicyWithSystemGC = false {product} {default}
bool UseConcMarkSweepGC = false {product} {default}
bool UseEpsilonGC = false {experimental} {default}
bool UseG1GC = true {product} {ergonomic}
bool UseMaximumCompactionOnSystemGC = true {product} {default}
bool UseParallelGC = false {product} {default}
bool UseParallelOldGC = false {product} {default}
bool UseSerialGC = false {product} {default}
bool UseShenandoahGC = false {product} {default}
bool UseZGC = false {experimental} {default}
UseShenandoahGCっていうJVMオプションがあるので、OpenJDK 11でShenandoah GC使えるみたいですね。
そして、experimentalじゃなくてproductになってる・・・?
OpenJDK 8でも試してみましょう。
$ docker container run --rm -it centos:7.6.1810 bash
[root@0e0f3ad821d8 /]# yum install -y java-1.8.0-openjdk-devel
[root@0e0f3ad821d8 /]# java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-b04)
OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)
[root@0e0f3ad821d8 /]# java -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal 2>/dev/null | egrep "Use.*GC "
bool UseAdaptiveSizePolicyWithSystemGC = false {product}
bool UseConcMarkSweepGC = false {product}
bool UseG1GC = false {product}
bool UseMaximumCompactionOnSystemGC = true {product}
bool UseParNewGC = false {product}
bool UseParallelGC := true {product}
bool UseParallelOldGC = true {product}
bool UseSerialGC = false {product}
bool UseShenandoahGC = false {product}
OpenJDK 8でもShenandoah GC使えるみたいです。こちらもproduct。
ついでなので、Red HatのOpenJDK 11も確認しておきます。
(AWSのEC2を使いました)
rpmソースが見つからなかった(サブスクリプション契約があれば見れる?)ので、ソースファイルがどれかわかりませんでしたが、 きっとOpenJDKのshenandoah/jdk11だと思うので、ビルド番号とShenandoahが含まれているかどうか程度の確認をします。
[ec2-user@ip-xx-xx-xx-xx ~]$ sudo yum install -y java-11-openjdk-devel
[ec2-user@ip-xx-xx-xx-xx ~]$ java -version
openjdk version "11.0.3" 2019-04-16 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.3+7-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.3+7-LTS, mixed mode, sharing)
[ec2-user@ip-xx-xx-xx-xx ~]$ java -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal 2>/dev/null | egrep "Use.*GC "
bool UseAdaptiveSizePolicyWithSystemGC = false {product} {default}
bool UseConcMarkSweepGC = false {product} {default}
bool UseEpsilonGC = false {experimental} {default}
bool UseG1GC = true {product} {ergonomic}
bool UseMaximumCompactionOnSystemGC = true {product} {default}
bool UseParallelGC = false {product} {default}
bool UseParallelOldGC = false {product} {default}
bool UseSerialGC = false {product} {default}
bool UseShenandoahGC = false {product} {default}
bool UseZGC = false {experimental} {default}
ビルド番号がCentOSと同じbuild 11.0.3+7-LTS
で、Shenandoahも含まれています。
OpenJDK 8も確認してみます。
[ec2-user@ip-xx-xx-xx-xx ~]$ sudo yum install -y java-1.8.0-openjdk-devel
[ec2-user@ip-xx-xx-xx-xx ~]$ java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-b04)
OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)
[ec2-user@ip-xx-xx-xx-xx ~]$ java -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal 2>/dev/null | egrep "Use.*GC "
bool UseAdaptiveSizePolicyWithSystemGC = false {product}
bool UseConcMarkSweepGC = false {product}
bool UseG1GC = false {product}
bool UseMaximumCompactionOnSystemGC = true {product}
bool UseParNewGC = false {product}
bool UseParallelGC := true {product}
bool UseParallelOldGC = true {product}
bool UseSerialGC = false {product}
bool UseShenandoahGC = false {product}
こちらもビルド番号がCentOSと同じbuild 1.8.0_212-b04で、Shenandoahも含まれています。
まとめ
- CentOSとFedoraのOpenJDK 11は、OpenJDKのshenandoah/jdk11をベースにUpstreamにマージされていないパッチを当てているっぽい
- CentOS独自のパッチが当たっているのかは、rpmソースをぱっと見てもわからなかった。Red Hatのrpmソースと比べたらわかるのかも
- Red HatとCentOSでコンパイルオプションなどに違いがあるのかはrpmソースをぱっと見てもわからなかった。Red Hatのrpmソースと比べたらわかるのかも
- ビルド番号とShenandoah有無から見ると、Red HatとCentOSは同じOpenJDKのshenandoah/jdk11をベースにしている気がする
- Red HatのOpenJDKにできるだけ近いものを無償で使いたい場合(Red HatのOpenJDKは無償ではありません)、CentOSのOpenJDKは選択肢の1つになりそう
あと、僕はまだ試してないですが、ojdkbuildっていうやつもあるみたいです。
ojdkbuildとCentOS OpenJDKの立ち位置の違いが気になるところです。
ちなみに昔は気づいてなかったけど、これはojdkbuild https://t.co/dEavlOvbNo の成果をRed Hatとして正式採用する方向とみられます。
— Takahiro YAMADA (@yamadamn) May 3, 2019
つまりojdkbuildがFedoraで、今回のがRHEL/CentOS的な扱いになってると見てもよさそう。https://t.co/6EJrm3i2ej