6 移行の準備
次の項は、アプリケーションの移行を成功させるのに役立ちます。
デフォルトの文字セット
デフォルトのcharsetは、UTF-8です。ただし、JDK 17以前のリリースでは、デフォルトの文字セットはJavaランタイムの起動時に決定されます。つまり、macOSでは、POSIX Cロケール以外で使用されるデフォルトの文字セットはUTF-8になります。他のオペレーティング・システムでは、ユーザーのロケールおよびデフォルトのエンコーディングに依存していました。たとえば、Windowsでは、windows-1252
やwindows-31j
などのコードページ・ベースの文字セットです。メソッドjava.nio.charsets.Charset.defaultCharset()
は、デフォルトの文字セットを返します。
java -XshowSettings:properties -version 2>&1 | grep native.encoding
検出されたエンコーディングがUTF-8と異なる場合、環境で実行されているアプリケーションが影響を受ける可能性があります。
JDKのデフォルトの文字セットの変更
file.encoding
を使用してさらに調査します。コマンドラインの値を次のいずれかに設定します:
UTF-8
: デフォルトの文字セットはUTF-8です。COMPAT
: デフォルトの文字セットは、JDK 17以前のリリースと同じように決定されます。
file.encoding
のその他の値はサポートされません。
ノート:
- 既存のJDKを使用してコマンド
java -Dfile.encoding=UTF-8 <your application>
を実行します。これにより、JDK 18以降と同じ環境が提供されます。差異があるかどうかを確認します。 - JDK 18以降でコマンド
-Dfile.encoding=COMPAT <your application>
を実行して、以前の動作を取得し、差異があるかどうかを確認します。
詳細は、『Java Platform, Standard Edition国際化ガイド』のデフォルトの文字セットに関する項を参照してください。
再コンパイルする前のプログラムの実行
最新のJDKリリース(JDK 18)でアプリケーションを実行します。たいていのコードおよびライブラリは変更しなくてもJDK 18上で動作するはずですが、一部のライブラリはアップグレードの必要があります。
ノート:
移行は反復的なプロセスです。プログラムをまず実行してみてから(このタスク)、これらの3つのタスクを平行して進めるのがおそらく最善でしょう:
アプリケーションの実行時に、廃止されたVMオプションに関するJVMからの警告がないか確認します。VMの起動に失敗する場合は、「削除されたGCオプション」を確認してください。
アプリケーションが正常に起動する場合は、慎重にテストして動作が使用中のJDKバージョンのときと同じであることを確認します。たとえば、一部の早期導入者は日付および通貨の形式が違っていることに気付いてきました。「デフォルトでのCLDRロケール・データの使用」を参照してください。
- JDK 18の新機能および変更点の詳細は、「JDK 18の新機能 - 新機能および機能拡張」を参照してください。
- JDK 17の新機能および変更点の詳細は、「JDK 17の新機能 - 新機能および機能拡張」を参照してください。
- JDK 16の新機能および変更点の詳細は、「JDK 16の新機能 - 新機能および機能拡張」を参照してください。
- JDK 15の新機能および変更点の詳細は、「JDK 15の新機能 - 新機能および機能拡張」を参照してください。
- JDK 14の新機能および変更点の詳細は、「JDK 14の新機能 - 新機能および機能拡張」を参照してください。
-
JDK 13の新機能および変更点の詳細は、「JDK 13の新機能 - 新機能および機能拡張」を参照してください。
-
JDK 12の新機能および変更点の詳細は、「JDK 12の新機能 - 新機能および機能拡張」を参照してください。
-
JDK 11の新機能および変更点の詳細は、「JDK 11の新機能 - 新機能および機能拡張」を参照してください。
-
JDK 10の新機能および変更点の詳細は、JDK 10の新機能を参照してください。
-
JDK 9の包括的な新機能一覧は、『JDK 9の新機能』を参照してください。
JDK 9での変更点の詳細は、JDK 9リリース・ノートを参照してください。
プログラムが正常に動作しているようであっても、このガイドの残りのステップを完了して問題のリストを確認するようにしてください。
サードパーティ・ライブラリの更新
使用するすべてのツールおよびサードパーティ・ライブラリについて、最新のJDKリリースをサポートする更新版が必要となる可能性があります。
最新のJDKで動作するように設計された各ライブラリまたはツールのバージョンについては、サードパーティ・ライブラリおよびツール・ベンダーのWebサイトを確認してください。提供されている場合は、その新しいバージョンをダウンロードおよびインストールしてください。
MavenまたはGradleを使用してアプリケーションを構築している場合は、最新のJDKバージョンをサポートしている最近のバージョンにアップグレードしてください。
IDEを使用してアプリケーションを開発している場合は、既存のコードを移行するのに役立ちます。NetBeans、EclipseおよびIntelliJのIDEはいずれも、最新のJDKのサポートを含むバージョンが提供されています。
OpenJDK Wikiの品質支援に関する項で、多くのフリー・オープン・ソース・ソフトウェア(FOSS)プロジェクトをテストしたステータスを確認できます。
アプリケーションのコンパイル(必要に応じて)
問題があることがわかっているAPIや機能にコードが依存している可能性があるため、最新のJDKコンパイラでコードをコンパイルすると、将来のリリースへの移行が容易になります。ただし、必ず必要というわけではありません。
コードをJDK 11以降のコンパイラでコンパイルする必要がある場合、次の点に注意してください。
-
ソース・コードでアンダスコア文字
("_")
を一文字で識別子として使用している場合、JDK 11以降のリリースではそのコードはコンパイルできません。このように使用するとJDK 8では警告となり、JDK 9以降ではエラーとなります。次に例を示します:
static Object _ = new Object();
このコードではコンパイラにより次のエラー・メッセージが生成されます。
MyClass.java:2: error: as of release 9, '_' is a keyword, and may not be used as a legal identifier.
-
javac
で-source
および-target
オプションを使用する場合、使用する値を確認してください。-source/-target
のサポートされている値は、18 (デフォルト)、17、16、15、14、13、12、11、10、9、8および7です。JDK 8では、
-source
および-target
の値に1.5/5以前の値を指定するのは非推奨となり、警告が表示されました。JDK 9以降では、これらの値はエラーになります。>javac -source 5 -target 5 Sample.java warning: [options] bootstrap class path not set in conjunction with -source 5 error: Source option 5 is no longer supported. Use 6 or later. error: Target option 1.5 is no longer supported. Use 1.6 or later.
-source
および-target
オプションのかわりに新しい--release
フラグを使用します。Java Development Kitツール仕様のjavacに関する項を参照してください。--release
フラグの有効な引数には、-source
および-target
と同じく、"one plus three back"ポリシーが適用されます。javac
は、JDK 1.0.2クラス・ファイルまでさかのぼる、以前のすべてのJDKのクラス・ファイルを認識および処理できます。『JEP 182: Policy for Retiring javac -source and -target Options』を参照してください。
-
sun.misc.Unsafeなどの重要な内部JDK APIにはJDK 11以降でも引き続きアクセスできますが、JDKの大部分の内部APIにはコンパイル時にはアクセスできません。アプリケーションまたはそのライブラリが内部APIに依存していることを示すコンパイル・エラーが発生することがあります。
依存関係を特定するには、Java依存性分析ツールを実行します。「コードに対するjdepsの実行」を参照してください。可能であれば、サポートされている代替APIを使用するようにコードを更新してください。
JDK内部クラスへの参照があるソース・コードをコンパイルするための一時的な回避策として、
--add-exports
および--add-opens
オプションを使用できます。これらのオプションの詳細は、JEP 261: モジュール・システムに関する項および「JDK内の強力なカプセル化」を参照してください。 -
以前より多くの非推奨メッセージが表示される可能性があります。
コードに対するjdepsの実行
アプリケーションに対してjdeps
ツールを実行して、アプリケーションおよびライブラリが依存するパッケージおよびクラスを確認します。内部APIを使用している場合、jdeps
により、コードを更新する際に役立つ修正候補が表示されることがあります。
内部JDK APIの依存性を検出するには、jdeps
を-jdkinternals
オプションとともに実行します。たとえば、sun.misc.BASE64Encoder
を呼び出すクラスに対してjdeps
を実行すると、次のように表示されます。
>jdeps -jdkinternals Sample.class
Sample.class -> JDK removed internal API
Sample -> sun.misc.BASE64Encoder JDK internal API (JDK removed internal API)
Warning: JDK internal APIs are unsupported and private to JDK implementation that are
subject to be removed or changed incompatibly and could break your application.
Please modify your code to eliminate dependency on any JDK internal APIs.
For the most recent update on JDK internal API replacements, please check:
https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
JDK Internal API Suggested Replacement
---------------- ---------------------
sun.misc.BASE64Encoder Use java.util.Base64 @since 1.8
Mavenを使用している場合、利用可能なjdeps
プラグインがあります。
jdeps
の構文は、Java Development Kitツール仕様のjdeps
に関する項を参照してください。
jdeps
は静的分析ツールであり、コードの静的分析では依存性の完全なリストが得られない可能性があることに注意してください。コードでリフレクションを使用して内部APIが呼び出されている場合、jdeps
では警告は表示されません。