7 JDK 8から後続のJDKリリースへの移行

JDK 8と後続のJDKリリースとの間では、重要な変更が行われました。

新しいJava SEがリリースされると必ず、以前のリリースとのバイナリ、ソース、および動作上の非互換が発生します。JDK 9以降で発生したJava SEプラットフォームのモジュール化には多くのメリットがありましたが、同時に多くの変更も伴いました。公式のJava SEプラットフォームAPIおよびサポートされているJDK固有のAPIのみを使用するコードは、変更なしでそのまま動作します。JDK内部APIを使用するコードは引き続き動作しますが、サポート対象のAPIを使用するように移行する必要があります。

アクセス不可となった、削除された、またはデフォルト動作が変更されたAPIもあります。アプリケーションのコンパイルまたは実行時に問題が発生する可能性があります。削除されたツールとコンポーネントおよびセキュリティ・アップデートを参照してください。

次の各項では、JDK 8アプリケーションを後続のJDKリリースに移行する際に注意する必要があるJDKパッケージの変更点について説明します。

アプリケーションが最新バージョンのJDKで正常に動作するようになったら、「次のステップ」を確認し、今後のリリースにおいて問題が発生するのを回避するのに役立てます。

不正なリフレクション・アクセス

一部のツールやライブラリでは、リフレクションを使用して内部使用のみを目的としたJDKの部分にアクセスします。これは不正なリフレクション・アクセスと呼ばれ、デフォルトではJDK 16以降では許可されません。

次の例では、変更の潜在的な影響を示します:

  • JDKの内部APIに直接アクセスする以前のリリースで正常にコンパイルされたコードは、デフォルトでは機能しなくなります。次に例を示します:
    System.out.println(sun.security.util.SecurityConstants.ALL_PERMISSION);

    コンパイラはIllegalAccessErrorを生成し、コードはInaccessibileObjectExceptionをスローします。

  • リフレクションを使用してエクスポート済java.* APIのprivateフィールドにアクセスするコードは、デフォルトでは機能しなくなります。次に例を示します:
    var ks = java.security.KeyStore.getInstance("jceks");
    var f = ks.getClass().getDeclaredField("keyStoreSpi");
    f.setAccessible(true);

    コードはInaccessibileObjectExceptionをスローします。

  • リフレクションを使用してエクスポート済java.* APIのprotectedメソッドにアクセスするコードは、デフォルトでは機能しなくなります。次に例を示します:
    var dc = ClassLoader.class.getDeclaredMethod("defineClass",
                                                 String.class,
                                                 byte[].class,
                                                 int.class,
                                                 int.class);
    dc.setAccessible(true);

    コードはInaccessibileObjectExceptionをスローします。

java起動ツール・オプション--illegal-accessは、緩和された強いカプセル化を制御します。このオプションのデフォルト値は--illegal-access=denyで、これにより不正なアクセス操作は無効化されます。

一時的な解決策として、--illegal-access=permitまたは--illegal-access=warnオプションを指定して、不正なアクセス操作の実行を続行します。スタック・トレースを含む不正なリフレクション・アクセス操作に関する詳細情報を取得するには、--illegal-access=debugオプションを指定します。

カプセル化解除を可能にする具体的なオプションが2つあります(ほとんどの内部APIはカプセル化されています)。これらは、--illegal-accessコマンドライン・オプションと組み合せて使用できます。
  • アクセスできない内部APIを使用する必要がある場合、--add-exportsランタイム・オプションを使用します。コンパイル時に--add-exportsを使用して内部APIにアクセスすることもできます。
  • 非publicメンバーにアクセスするためにクラス・パスにあるコードにディープ・リフレクションの実行を許可する必要がある場合は、--add-opensランタイム・オプションを使用します。

すべてのリフレクション・アクセス警告を抑制する場合は、必要に応じて--add-exportsおよび--add-opensオプションを使用します。

--add-exports

デフォルトでアクセスできないようになっている内部APIを使用する必要がある場合、--add-exportsコマンドライン・オプションを使用してカプセル化を解除できます。

--add-exportsオプションの構文は次のとおりです。
--add-exports <source-module>/<package>=<target-module>(,<target-module>)*
ここで、<source-module>および<target-module>はモジュール名、<package>はパッケージの名前です。

--add-exportsオプションでは、ターゲット・モジュールがソース・モジュールを読み取る場合に、ターゲット・モジュール内のコードがソース・モジュールの名前付きパッケージ内のタイプにアクセスすることを許可します。

特殊なケースとして、<target-module>ALL-UNNAMEDの場合、ソース・パッケージが名前のないすべてのモジュールに、それが最初から存在するか後から作成されたかにかかわらずエクスポートされます。次に例を示します:
--add-exports java.management/sun.management=ALL-UNNAMED
この例では、名前のないすべてのモジュールのコード(クラス・パスにあるコード)がjava.management/sun.managementのpublicタイプのpublicメンバーにアクセスできるようにします。クラス・パスにあるコードがディープ・リフレクションによる非publicメンバーへのアクセスを試行すると、そのコードは失敗します。
クラス・パスで実行されるアプリケーションoldAppが、java.managementモジュールのエクスポートされていないcom.sun.jmx.remote.internalパッケージを使用する必要がある場合、必要なアクセス権を次のように付与できます。
--add-exports java.management/com.sun.jmx.remote.internal=ALL-UNNAMED
JARファイル・マニフェストを使用してカプセル化を解除することもできます。
Add-Exports:java.management/sun.management

--add-exportsオプションは慎重に使用してください。これを使用すれば、ライブラリ・モジュールの内部APIに、またはJDKそのものの内部APIであってもアクセスできますが、これは自己責任になります。その内部APIが変更または削除されると、ライブラリやアプリケーションは失敗します。

JEP 261に関する項も参照してください。

--add-opens

非publicメンバーにアクセスするためにクラス・パスにあるコードにディープ・リフレクションの実行を許可する必要がある場合は、--add-opensランタイム・オプションを使用します。

一部のライブラリはディープ・リフレクションを実行する(つまりsetAccessible(true)となっている)ため、privateなメンバーを含め、すべてのメンバーにアクセスできます。このアクセス権は、javaコマンドラインで--add-opensオプションを使用して付与できます。このオプションの使用により警告メッセージが生成されることはありません。

--illegal-access=denyの場合、実行時にIllegalAccessExceptionまたはInaccessibleObjectExceptionメッセージが表示され、例外メッセージに表示される情報に基づいて引数に--add-opensランタイム・オプションを使用できます。

--add-opensオプションの構文は次のとおりです。
--add-opens module/package=target-module(,target-module)*
このオプションでは、モジュール宣言にかかわらず、<module><package><target-module>に開くことを許可します。
特殊なケースとして、<target-module>ALL-UNNAMEDの場合、ソース・パッケージが名前のないすべてのモジュールに、それが最初から存在するか後から作成されたかにかかわらずエクスポートされます。次に例を示します:
--add-opens java.management/sun.management=ALL-UNNAMED
この例では、クラス・パスにあるすべてのコードがjava.management/sun.managementパッケージのpublicタイプの非publicメンバーにアクセスできるようにします。

ノート:

たとえばJava Web StartのJNLPファイルなど、JNI呼出しAPIを使用している場合、--add-opensとその値の間に等号を含める必要があります。
<j2se version="10" java-vm-args="--add-opens=module/package=ALL-UNNAMED"  />

--add-opensとその値の間の等号記号は、コマンド・ラインのオプションです。

新しいバージョン文字列スキーム

JDK 10では、時間ベースの解放モデルへの対応を改善するために、JDK 9で導入されたバージョン文字列のスキームが少し変更されています。JDK 11以降ではJDK 10で導入されたバージョン文字列の書式が保持されます。

コードでメジャー、マイナー、セキュリティおよびパッチ更新を識別するのにバージョン文字列形式に依存している場合、更新が必要となる可能性があります。

新しいバージョン文字列の形式は次のとおりです。

$FEATURE.$INTERIM.$UPDATE.$PATCH

バージョン文字列を解析、検証および比較するための単純なJava APIが追加されました。java.lang.Runtime.Versionに関する項を参照してください。

Java Platform, Standard Editionインストレーション・ガイドバージョン文字列の書式を参照してください。

JDK 9で導入されたバージョン文字列に対する変更の詳細は、JEP 223: 新規バージョン文字列のスキームを参照してください。

JDK 10で導入されたバージョン文字列の変更の詳細は、JEP 322: 時間ベースのリリースのバージョニングを参照してください。

インストール済JDK/JREイメージに加えられた変更

JDKおよびJREに大きな変更が加えられています。

JDKおよびJREレイアウトの変更

JDKのインストール後にファイル・システムを参照するとわかるとおり、ディレクトリ・レイアウトがJDK 9より前のリリースとは異なっています。

JDK 11以降

JDK 11以降にはJREイメージがありません。『Java Platform, Standard Editionインストレーション・ガイド』JDKのインストール済ディレクトリの構造に関する項を参照してください。

JDK 9およびJDK 10

以前のリリースには2種類のランタイム・イメージがありました。1つはJREで、これはJava SE Platformの完全な実装、もう1つはJDKで、JRE全体がjre/ディレクトリに、開発ツールとライブラリとともに格納されていました。

JDK 9およびJDK 10では、JDKとJREは2種類のモジュラ・ランタイム・イメージで、次のディレクトリが含まれています。

  • bin: バイナリ実行可能ファイルが格納されます。

  • conf: 開発者、デプロイ実行者およびエンド・ユーザーによる編集を意図した、.properties.policyおよびその他のファイルが格納されます。これらのファイルは以前はlibディレクトリまたはそのサブディレクトリにありました。

  • lib: 動的にリンクされるライブラリおよびJDKの完全な内部実装が格納されます。

JDK 9およびJDK 10では、JDKとJREのダウンロードは引き続き分かれていますが、それぞれのディレクトリ構造は同じです。JDKイメージには、これまでJDKで提供されてきた追加のツールおよびライブラリが含まれています。jdk/jre/のラッパー・ディレクトリはなく、(javaコマンドなどの)バイナリは複製されません。

『JEP 220: Modular Run-Time Images』を参照してください。

新しいクラス・ローダー実装

JDK 9以降のリリースでは1.2リリースから存在するクラス・ローダー階層が引き続き保持されます。ただし、モジュール・システムの実装のために次の変更が加えられました。

  • アプリケーション・クラス・ローダーはURLClassLoaderのインスタンスではなくなり、内部クラスのインスタンスになります。これは、Java SEモジュールでもJDKモジュールでもないモジュールのクラスのデフォルト・ローダーです。

  • 拡張クラス・ローダーという名前がプラットフォーム・クラス・ローダーという名前に変更されました。Java SEプラットフォームのすべてのクラスは、プラットフォーム・クラス・ローダーにより参照可能となることが保証されます。

    クラスがプラットフォーム・クラス・ローダーにより参照可能であるからというだけで、クラスが実際にプラットフォーム・クラス・ローダーにより定義されているということにはなりません。Java SEプラットフォームの一部のクラスはプラットフォーム・クラス・ローダーにより定義されているのに対し、あるものはブートストラップ・クラス・ローダーにより定義されています。アプリケーションは、どのクラス・ローダーでどのプラットフォーム・クラスが定義されているかに依存しないようにしてください。

    JDK 9で実装されたこの変更は、親クラス・ローダーとしてnull (つまり、ブートストラップ・クラス・ローダー)が設定されたクラス・ローダーを作成し、親からすべてのプラットフォーム・クラスが参照可能であることを前提とするコードに影響する可能性があります。そのようなコードは、親としてプラットフォーム・クラス・ローダーを使用するように変更する必要があります(ClassLoader.getPlatformClassLoaderを参照してください)。

    プラットフォーム・クラス・ローダーはURLClassLoaderのインスタンスではなく、内部クラスのインスタンスです。

  • ブートストラップ・クラス・ローダーは引き続きJava仮想マシンに組み込まれており、ClassLoader APIにおいてnullで表されます。ここでは、java.baseといった、いくつかの重要なモジュールのクラスが定義されています。その結果、ここで定義されるクラスの数はJDK 8に比べてかなり少なくなり、-Xbootclasspath/aによりデプロイされるアプリケーションや親としてnullが設定されたクラス・ローダーを作成するアプリケーションは、前述のように変更が必要となる可能性があります。

rt.jarおよびtools.jarの削除

以前にlib/rt.jarlib/tools.jarlib/dt.jarおよびその他の各種内部JARファイルに格納されていたクラスおよびリソースのファイルは、libディレクトリ内の実装固有のファイルにさらに効率的な形式で格納されています。

rt.jarおよび同様のファイルの削除により、次のような問題が発生します。

  • JDK 9以降では、ClassLoader.getSystemResourceはJARファイルを指すURLは返しません(JARファイルがないため)。かわりに、ランタイム・イメージに格納されたモジュール、クラス、およびリソースの名前をそのイメージの内部構造や形式を公開することなく示す、jrt URLを返します。

    次に例を示します:

    ClassLoader.getSystemResource("java/lang/Class.class");

    JDK 8で実行すると、このメソッドは次の形式のJAR URLを返します。

    jar:file:/usr/local/jdk8/jre/lib/rt.jar!/java/lang/Class.class

    これにはラインタイム・イメージ内の実際のJARファイルの名前を示すファイルURLが含まれています。

    モジュラ・イメージにはJARファイルは含まれないため、この形式のURLは意味をなしません。JDK 9以降のリリースでは、このメソッドは次の値を戻します。
    jrt:/java.base/java/lang/Class.class
  • java.security.CodeSource APIおよびセキュリティ・ポリシー・ファイルでは、特定の権限が付与されるコード・ベースの場所を示すのにURLを使用します。Java Platform, Standard Editionセキュリティ開発者ガイドポリシー・ファイル構文に関する項を参照してください。特定の権限を必要とするランタイム・システムのコンポーネントは現在、conf/security/java.policyファイルにおいてファイルURLを使用して識別されます。

  • 旧バージョンのIDEやその他の開発ツールでは、ランタイム・イメージに格納されたクラス・ファイルおよびリソース・ファイルを列挙する機能、およびrt.jarファイルおよび同様のファイルをオープンして読み取ることによりそのコンテンツを直接読み取る機能が必要となります。これはモジュラ・イメージでは不可能です。

拡張機能メカニズムの削除

JDK 8以前では、拡張メカニズムにより、クラス・パスで明示的に指定しなくても、ランタイム環境において拡張クラスを検出してロードすることが可能でした。JDK 9以降では、拡張クラスを使用する必要がある場合、JARファイルがクラス・パスにあることを確認してください。

JDK 9およびJDK 10では、java.ext.dirsシステム・プロパティが設定されている場合、またはlib/extディレクトリが存在する場合、javacコンパイラおよびjava起動ツールは終了します。プラットフォーム固有のディレクトリをシステム規模でさらに確認するには、-XX:+CheckEndorsedAndExtDirsコマンドライン・オプションを指定します。これにより、このディレクトリが存在していてかつ空でない場合に同じ終了動作が発生します。拡張クラス・ローダーはJDK 9以降のリリースでも引き続き保持され、プラットフォーム・クラス・ローダーとして指定されています(getPlatformClassLoaderを参照。)ただし、JDK 11でこのオプションは廃止され、使用すると警告が発行されます。

次のエラーは、システムが拡張メカニズムを使用するよう構成されていることを示しています。

<JAVA_HOME>/lib/ext exists, extensions mechanism no longer supported; Use -classpath instead.
.Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

java.ext.dirsシステム・プロパティが設定されている場合も同様のエラーが表示されます。

このエラーを修正するには、ext/ディレクトリまたはjava.ext.dirsシステム・プロパティを削除します。

『JEP 220: Modular Run-Time Images』を参照してください。

推奨標準優先メカニズムの削除

java.endorsed.dirsシステム・プロパティおよびlib/endorsedディレクトリは存在しなくなりました。このいずれかが検出された場合、javacコンパイラおよびjava起動ツールは終了します。

JDK 9以降では、アップグレード可能なモジュールを使用するか、またはJARファイルをクラス・パスに指定します。

このメカニズムは、アプリケーション・サーバーがJDKで使用されるコンポーネントをオーバーライドできるよう意図するものでした。更新されるパッケージはJARファイルに配置され、それがどこにあるかはシステム・プロパティjava.endorsed.dirsによりJavaランタイム環境側で判断できるようになっていました。このプロパティが指定されていない場合、デフォルトとして$JAVA_HOME/lib/endorsedが使用されるようになっていました。

JDK 8では、-XX:+CheckEndorsedAndExtDirsコマンドライン引数を使用して、システム上のどこかにあるそのようなディレクトリをチェックできます。

JDK 9以降のリリースでは、java.endorsed.dirsシステム・プロパティが設定されている場合、またはlib/endorsedディレクトリが存在する場合、javacコンパイラおよびjava起動ツールは終了します。

次のエラーは、システムが標準の推奨オーバーライド・メカニズムを使用するよう構成されていることを示しています。

<JAVA_HOME>/lib/endorsed is not supported. Endorsed standards and standalone APIs
in modular form will be supported via the concept of upgradeable modules.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

java.endorsed.dirsシステム・プロパティが設定されている場合も同様のエラーが表示されます。

このエラーを修正するには、lib/endorsedディレクトリを削除するか、またはjava.endorsed.dirsシステム・プロパティを設定解除します。

『JEP 220: Modular Run-Time Images』を参照してください。

削除されたmacOS固有の機能

この項では、JDK 9以降で削除されたmacOS固有の機能について説明します。

プラットフォーム固有のデスクトップ機能

java.awt.Desktopクラスには、Apple固有のcom.apple.eawtおよびcom.apple.eioパッケージにあるAPIの代替が含まれています。新しいAPIはmacOS APIを置き換えるもので、プラットフォームに依存しません。

com.apple.eawtおよびcom.apple.eioパッケージのAPIはカプセル化されているため、JDK 9以降のリリースでこれらに対してコンパイルすることはできません。ただし、実行時にはアクセス可能であるため、古いバージョンにコンパイルされた既存のコードは引き続き動作します。最終的には、appleおよびcom.appleパッケージおよびそのサブパッケージの内部クラスを使用するライブラリやアプリケーションは新しいAPIへの移行が必要となります。

com.apple.concurrentおよびapple.applescriptパッケージは削除されており、代替はありません。

『JEP 272: Platform-Specific Desktop Features』を参照してください。

AppleScriptエンジンの削除

プラットフォーム固有のjavax.script実装であるAppleScriptエンジンはJDKで削除されており、代替はありません。

AppleScriptエンジンは、最近のリリースではほぼ使用できませんでした。JDK 7やJDK 8においてこの機能は、AppleバージョンのAppleScriptEngine.jarファイルがシステムにある場合にのみ動作していました。

Windowsレジストリ・キーの変更

Java 11以降のインストーラは、次のWindowsレジストリ・キーをJDKのインストール時に作成します。JDK 16の場合、インストーラによって次のWindowsレジストリ・キーが作成されます:

  • "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK"

  • "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK\16"

JDKの2つのバージョンがインストールされている場合、2つの異なるWindowsレジストリ・キーが作成されます。たとえば、JDK 15.0.1をJDK 16とともにインストールする場合は、インストーラによって次のように別のWindowsレジストリ・キーが作成されます。

  • "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK"

  • "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK\16"

  • "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK\15.0.1"

デプロイメント

Javaデプロイメント・テクノロジはJDK 9で非推奨になり、JDK 11で削除されました。

事前インストールされたシステムJREに依存するのではなく、JDK 9で導入されたjlinkツールを使用して、専用のランタイムをパッケージ化してデプロイしてください。

起動時のJREバージョン選択の削除

JDK 9以降では、起動時に起動されるJREとは異なるバージョンのJREを要求する機能は削除されています。

近年のアプリケーションは通常、Java Web Start (JNLP)、ネイティブOSパッケージ化システムまたはアクティブ・インストーラを使用してデプロイされます。これらのテクノロジは、必要なJREを必要に応じてダウンロードおよび更新する、必要となるJREを管理する独自の方法を備えています。そのため、起動ツールの起動時JREバージョン選択は非推奨となりました。

以前のリリースでは、アプリケーションの起動時にどのJREバージョン(またはバージョンの範囲)を使用するかを指定できました。バージョンの選択は、コマンドライン・オプションまたはアプリケーションのJARファイルのマニフェスト・エントリで可能でした。

JDK 9以降では、java起動ツールが次のように変更されています。
  • コマンドラインで-version:オプションが指定されているとエラー・メッセージを出力して終了します。
  • JRE-Versionマニフェスト・エントリがJARファイルにあると、警告メッセージを出力して続行します。

『JEP 231: Remove Launch-Time JRE Version Selection』を参照してください。

シリアライズされたアプレットのサポートの削除

JDK 9以降では、アプレットをシリアライズ・オブジェクトとしてデプロイする機能はサポートされていません。近年の圧縮およびJVMのパフォーマンスでは、このようにアプレットをデプロイするメリットはありません。

appletタグのobject属性およびobjectおよびjava objectアプレット・パラメータ・タグは、アプレットの起動時に無視されます。

アプレットをシリアライズするかわりに、通常の方法でデプロイしてください。

JNLP仕様の更新

JNLP (Java Network Launch Protocol)が、不整合の解消、コードのメンテナンス性の向上、セキュリティの強化を目的として更新されました。

JNLPが次のように更新されました。

  1. JNLPファイルにおける&のかわりの&amp;の使用。

    JNLPファイル構文はXML仕様に準拠しており、すべてのJNLPファイルは標準のXMLパーサーによる解析が可能である必要があります。

    JNLPファイルでは複雑な比較を指定できます。これまでこれはアンパサンド(&)を使用して行われていましたが、これは標準XMLではサポートされていません。&を使用して複雑な比較を作成している場合、JNLPファイルで&amp;に置き換えてください。&amp;はすべてのバージョンのJNLPで互換性があります。

  2. 数値バージョン要素タイプと非数値バージョン要素タイプの比較。

    これまで、intバージョンの要素とintとして解析できない他のバージョンの要素を比較する際は、両者をASCII値として辞書式に比較していました。

    JDK 9以降では、intとして解析できる要素が他の要素より短い文字列である場合、ASCII値に基づいて辞書式に比較する前に先行のゼロが埋め込まれます。これにより循環がないことが保証されます。

    バージョン比較とJNLPサーブレットの両方が使用される場合、数値のみを使用してバージョンを表す必要があります。

  3. java (またはj2se)要素にネストされたリソースがあるコンポーネント拡張機能。

    これは仕様で許可されています。以前もサポートされていましたが、このサポートが仕様に反映されていませんでした。

  4. FX XML拡張。

    JNLP仕様が強化され、type属性がapplication-desc要素に、そしてサブ要素paramapplication-descに(すでにapplet-descにあるように)追加されました。

    JavaFXアプリケーションを指定する以前の方法も引き続きサポートされているため、これが既存のアプリケーションにおいて問題となることはありません。

JSR-056のJNLP仕様の更新に関する項を参照してください。

ガベージ・コレクションへの変更

この項では、JDK 9以降でガベージ・コレクションに加えられた変更について説明します。

デフォルトのガベージ・コレクタがG1に

ガベージファースト・ガベージ・コレクタ(G1 GC)は、JDK 9以降のリリースのデフォルトのガベージ・コレクタです。

大部分のユーザーにとって、G1 GCなどの一時停止の少ないコレクタは、JDK 8のデフォルトであったParallel GCなどのスループット指向のコレクタに比べて全体のパフォーマンスが優れています。

G1 GCのチューニングの詳細は、『Java Platform, Standard Edition HotSpot仮想マシン・ガベージ・コレクション・チューニング・ガイド』G1 GCのエルゴノミック・デフォルトに関する項およびチューニング可能なデフォルトに関する項を参照してください。

削除されたGCオプション

JDK 9以降のリリースでは、次のGCの組合せの場合に、アプリケーションの起動に失敗します。

  • DefNew + CMS
  • ParNew + SerialOld
  • インクリメンタルCMS

CMSのフォアグラウンド・モードも削除されています。削除されたコマンドライン・フラグは、-Xincgc-XX:+CMSIncrementalMode -XX:+UseCMSCompactAtFullCollection-XX:+CMSFullGCsBeforeCompactionおよび -XX:+UseCMSCollectionPassingです。

コマンドライン・フラグ-XX:+UseParNewGCは有効ではなくなりました。ParNewフラグはCMSとともにのみ使用でき、CMSではParNewが必須です。そのため、-XX:+UseParNewGCフラグは非推奨となっており、今後のリリースで削除対象となっています。

『JEP 214: Remove GC Combinations Deprecated in JDK 8』を参照してください。

Permanent世代の削除

Permanent世代はJDK 8で削除されており、関連するVMオプションでは警告が表示されます。次のオプションはスクリプトから削除する必要があります。

  • -XX:MaxPermSize=size

  • -XX:PermSize=size

JDK 9以降のリリースでは、JVMに次のような警告が表示されます。
Java HotSpot(TM) 64-Bit Server VM warning: Ignoring option MaxPermSize; support was removed in 8.0

Permanent世代を認識するツールは更新が必要となる可能性があります。

『JEP 122: Remove the Permanent Generation』およびJDK 9リリース・ノート - 削除されたAPI、機能およびオプションを参照してください。

GCログ出力の変更

ガベージ・コレクション(GC)ロギングではJVM統合ロギング・フレームワークを使用しており、新しいログと古いログとでいくらかの違いがあります。現在使用しているGCログ・パーサーは変更がほぼ必要となります。

さらに、JVMロギング・オプションも更新が必要となる可能性があります。GC関連のすべてのロギングにおいて、通常は他のタグと組み合せて、gcタグを(例: —Xlog:gc)使用する必要があります。—XX:+PrintGCDetailsオプションおよび-XX:+PrintGCオプションは非推奨となっています。

Java Development Kitツール仕様JVM Unified Logging Frameworkによるロギングの有効化に関する項および『JEP 271: Unified GC Logging』を参照してください。