皆さんはJDKの更新をしたことがありますでしょうか。
私はこれまでやったことはありませんでした。。
理由は単純で基本的にJDKはLTS(長期サポート)を使用し更新する機会がなかったからです。
しかし今回偶然にもJDKの更新をする機会があったので更新する際にどのようなことを考えながら実施したかを
備忘録がてらご紹介したいと思います。
考えること1: JDKのEOL
現在、主に使用されているJDKは古い順から8, 11, 17, 21だと思われます。
これらはまだEOL(End of Life)を迎えておらずアップデートの対象です。
ここでRed HatのOpenJDKのサポート期間を見てみましょう。
JDK8 |
JDK11 |
JDK17 |
JDK21 |
2026年11月 |
2024年10月 |
2027年10月 |
2029年12月 |
JDK8がそろそろEOLかと思いきやJDK11の方が早くEOLを迎えてしまいます。
これはJDK8を使用したアプリケーションが世の中に多く存在することや、
JDK8からJDK11への更新難易度が高いためと言われています。
では、最新のJDK21に更新すればOKというわけにも行きません。。これについては次で説明します。
考えること2: 使用しているMW(ミドルウェア)の対応バージョン
Javaは無数のフレームワークやライブラリに支えられており開発の容易性や効率性に富んでいます。
しかし、その反面 現在はライブラリのメンテナンスが行われていないものも多く存在します。
これらが最新のJDKでは動作しない可能性があります。
JDKの更新は行う際にはしっかりと各ライブラリが動作するかを確認する必要があります。
また、更新の際にはMWだけでなく静的解析ツールなども更新すべきです。
JDKの更新によって新しいコードの書き方ができるようになったりするためコード解析が正常に動作しない可能性があります。
考えること3: JDK本体の更新内容
JDKの更新によってJDK内部の動作に変更があり、本番コードまで影響がある場合があります。
例を上げるとすればJDK17の更新に含まれるJEP403の「JDK内部の強力なカプセル化」などが挙げられます。
これによってJDK内部のAPIへのアクセスが制限されるようになり一部フレームワークやライブラリはこの影響を受けると考えられます。
以上のようなJDKの更新内容についても確認すべきです。
考えること4: 性能テスト
JDK17からデフォルトのGC(ガベージコレクション)がG1 GCに変更されました。
これを受けて主にGCの種類について検証しました。
JDK17の段階で使用できるGCは以下の通りです。
以下のGCをそれぞれ設定し性能テストを実施しチューニングを見直しました。
GC |
一言説明 |
Serial GC |
シングルコア環境で主に使用する |
Parallel GC |
マルチコア環境ではJDK11までデフォルト |
G1 GC |
ヒープサイズの大きいアプリケーションに適している。JDK17からデフォルト |
Z GC |
8MBから16TBまでのヒープサイズをサポートしている |
Shenandoah GC |
アプリケーションのスレッドと並列的に動作するGC |
まとめ
実際に更新に着手した際にはどこから手をつけるべきか悩むことが多いと思います。
アプリケーションの規模にもよりますが、膨大な作業を行う必要があったりもするかと思います。
今回ほぼ手探りで大規模なアプリケーションのJDK更新を行ってみて以下のような学びがありました。
- JDKのEOLを事前に確認する(JDK11のように短くなってしまう例もある)
- 更新を行った際のドキュメントは残しておく
- MWやビルドツール、静的解析ツールの更新を怠らない(EOLなMWがあると更新が難しいこともありそう)
- 性能テストを実行する環境があると便利(色々な種類のGCを試せた)
さらっと書きましたが、実際はここに到達するまで1年以上かかってたりするので
これからJDK更新をする誰かの指針になったら幸いです。