😄

JDK8->17 バージョンアップでやったこと

に公開

はじめに

業務でWebアプリケーションのバックエンド側をJDK8から17にバージョンアップしました。
本記事では、その際に対応したポイントや、修正が必要だった箇所についてご紹介します。

環境

  • JDK:OpenJDK8(Eclipse Temurin)

バージョンアップ時の注意点

JDK 17への移行では、単にバージョンを上げるだけでなく、削除された機能や動作仕様の変更など、いくつか注意すべきポイントがあります。

1. 削除された機能の確認

JDKのバージョンアップに伴い、一部のパッケージやJVM起動オプションが削除されました。
JVM起動オプションは、起動時にコンソールログに出力されることがあります。

  • パッケージ
    • javax.xml.bind.*
    • javax.xml.ws.*
    • java.applet.*
    • jdk.nashorn.*

これらはJava EEやJavaFXに関連するAPIで、JDK 11以降では標準から除外されています。
必要に応じて外部ライブラリで代替する対応が必要です。

  • JVM起動オプション
    • GC関連
      -XX:+CMSIncrementalMode
      -XX:+UseConcMarkSweepGC
      -XX:+UseParNewGC
      -XX:+UseParallelOldGC

    • ログ出力関連
      -Xloggc:<filename>
      -XX:+PrintGC
      -XX:+PrintGCDetails
      -XX:+PrintGCTimeStamps
      -XX:+PrintGCDateStamps
      -XX:+PrintGCApplicationStoppedTime
      -XX:+PrintGCApplicationConcurrentTime
      -XX:+UseGCLogFileRotation
      -XX:NumberOfGCLogFiles=<number>
      -XX:GCLogFileSize=<size>
      これらのオプションは、JDK 9以降で導入された統一されたロギングフレームワーク(-Xlog)に置き換えられています。

2. JVMの仕様変更の確認

利用GCのデフォルトの変更

JDK 9以降、デフォルトのGC(ガベージコレクション)は G1GC に変更されました。
従来のParallel GCやCMS GCを使用していた場合は、パフォーマンスの違いが出る可能性があります。
必要に応じて明示的にGCを指定し、性能検証を行うことをおすすめします。

モジュールシステムによるアクセス制限

JDK9から導入された「モジュールシステム」により、クラスのアクセス制御が強化されました。
これにより、たとえpublicなクラスであっても、モジュール外からアクセスできないケースがあります。

この制限によって、実行時にエラーが発生する場合があります。

例:

module {モジュール名} does not "opens {パッケージ名}" to unnamed module

暫定対策として、JVM起動引数に以下を追加することで回避可能です。

JVM引数に以下を追加してください。
--add-opens={モジュール名}/{パッケージ名}=ALL-UNNAMED

ただし、将来的にサポートされなくなる可能性があるため、該当クラス・メソッドの使用の見直しを推奨します。

JDKツールや付属機能の確認

JDKで配布されているツール(JVisualVMなど)が削除されたり、別途ダウンロードが必要になっている場合があります。
また、Oracle JDKでは一部のツールが有償となっていることもあるため、利用中のツールの対応状況を確認してください。

バージョンアップで困ったときは?

JDKの大きな変更点は「JEP」という形で公開されています。
LTS間での移行であれば、その間のバージョンのJEPを一覧で確認することで、変更点を体系的に把握できます。

JDK17の変更点であれば、以下のサイトが参考になります。

おわりに

JDK 17への移行は、一見すると単純なバージョンアップに見えますが、JVMオプションやアクセス制限などの落とし穴が多数存在します。
事前にJEPや公式ドキュメントを確認し、余裕を持った検証と対応を行うことで、スムーズな移行を実現できるはずです。

Discussion