Java SE 9にスムーズに移行するための互換性チェックポイント

Oracle Java & Developers編集部
2017-02-13 11:00:00
  • このエントリーをはてなブックマークに追加

2017年7月に登場予定の「Java SE 9」では、JDKに関していくつかの変更が予定されている。既存アプリケーションをスムーズに移行するためのチェックポイントを紹介する。

Java SE 9への移行では内部実装の変更や機能削除による互換性の問題に注意すべし


日本オラクル Javaプラットフォーム・グループのデイビッド・バック氏

 Javaは、これまで後方互換性の維持にコミットしてバージョンアップが行われてきた。2017年7月にリリース予定の「Java SE 9」では、モジュール機構(Project Jigsaw)をはじめとする新機能が導入される一方、JDKに関しては既存機能の廃止などいくつかの変更が予定されている。それらの変更に伴い、従来バージョンで作られたアプリケーションをJava SE 9上で動作させる際には、互換性の問題が生じる可能性がある。日本オラクルが2016年12月に開催したセミナー「Javaで創るクラウド時代のエンタープライズ開発 ~マイクロサービス、DevOpsとJavaの最新動向~」におけるセッション「Java SE 9アップデートと移行のポイント」では、Java SE 9の従来バージョンとの互換性について、2016年9月に開催された「JavaOne 2016 San Francisco」における関連セッションの情報を基に日本オラクルのデイビッド・バック氏(Javaプラットフォーム・グループ)が解説した。

 これまで幾度もバージョンアップを重ねてきたJavaでは、常に旧バージョンとの互換性(後方互換性)の確保に力が注がれてきた。廃止や仕様変更が予定される機能は事前に予告され、十分な移行期間を経たうえで適用されるが、それでも古いバージョンで作られた既存のJavaプログラムとの間で互換性の問題が生じるケースがある。バック氏は、そのような“非互換性”に関する過去の事象をいくつか紹介したうえで、「世の中に存在する全てのJavaプログラムが、次のバージョンでも常に正しく動作するという保証はありません。Java SE 9を導入する際にも、互換性に関してどのような問題が生じる可能性があるのかを知っておくことは重要です」と呼びかける。

 次に示す図は、Java SEの3種のアップデート・リリース「Security Update」、「Feature Update」、「Platform Release」における互換性の影響範囲を示したものだ。


Java SEのリリースにおける互換性の範囲

Java SEのPlatform Releaseにおける互換性の範囲

 Security Updateは対象個所だけを修正するもので、プログラムの振る舞いやソースコードへの影響は限定的となる。また、Feature Updateは振る舞いとソースコードにもう少し大きな影響が及ぶ可能性があるが、バイナリ・レベルの互換性は保たれる。これに対して、Java SE 8や同9などのメジャー・アップデートに当たるPlatform Releaseは、バイナリ・レベルでも非互換性が含まれることがある。つまり、ソースコードを修正してコンパイルし直さなければ動作しなくなる可能性があるということだ。

 具体的には、次のような要素が非互換性の原因になりうるという。

  • バグ修正
  • 対応アルゴリズムの変更
  • セキュリティ改善
  • サポート対象プラットフォームの変更
  • ネイティブ・コードの使用
  • プロパティの変更
  • 非推奨の勧告
  • デプロイ系の変更
  • 内部実装の変更。例えば、ガーベジ・コレクション(GC)のアルゴリズムや内部的に使用しているAPI(内部使用API)など
  • パッケージ構成の変更
  • ツールやファイルの削除
  • すでに廃止対象とされ、非推奨となっていたメソッド、クラス、機能の削除

 これらの中でも、Java SE 9(JDK 9)では「内部使用APIの変更」と「非推奨のメソッド、クラス、機能の削除」に注意してほしいとバック氏は話す。特に内部使用APIの変更については、自分が作ったアプリケーションだけでなく、そのアプリケーションが依存しているライブラリやツールから影響を受けるケースもあるため、アップデートのタイミングに注意する必要がある。以降では、Java SE 9で互換性に関して留意すべき事項について、影響度の大きさの順に説明する。

「影響度:大」─コードの修正が必要かつ該当するアプリケーションが多く存在するもの

 まず「影響度:大」と考えられるのが、コードの修正が必要であり、なおかつ該当するアプリケーションが多いものだ。主なものとしては次が挙げられる。なお、以降の見出し末尾に付記した「JEP」とは「JDK Enhancement Proposals」の略であり、JDK(OpenJDK)における機能拡張の提案に付けられた番号である。各JEPの詳細はOpenJDKのWebサイトで確認することができる。

JDKの内部APIの大半が利用できなくなる(JEP 260)

 JDKには、JDK外部からの利用を想定していないAPIが多数含まれている。これらのAPIは隠蔽されておらず、ごく普通に使うことが可能であったため、少なからぬアプリケーションで使われてきた。しかし、JDK 9からは大半の内部APIへのアクセスが不可能となり、アプリケーション開発において利用できなくなる。

 ただし、以下に示すAPIについては、代替となるPublicなAPIが用意されるまで、例外的にアクセスが可能なまま残されることになっている。

  • sun.misc.Cleaner
  • sun.misc.{Signal,SignalHandler}
  • sun.misc.Unsafe
  • sun.reflect.Reflection::getCallerClass
  • sun.reflect.ReflectionFactory

 アプリケーションが内部APIを使用しているかどうかは、JDK 8以降に付属するツール「jdeps」を使って調べられるが、JDK 8のjdepsとJDK 9 EA(Early Access)版のjdepsは異なる結果を返す可能性があるため、JDK 9 EA版のjdepsを使って確認することを推奨する。また、JDK 9以降でも、実行時のコマンドラインのフラグによって元の振る舞いに戻せるという。

バージョン文字列の書式変更(JEP 223)

 これまで、JDKのバージョンは「JDK 1.8.0_121」といった書式の文字列で表されていた。だが、この書式はわかりづらく、標準化もされていなかったことから、今後はセマンティック・バージョニングに準拠したものに変更される。具体的には、「JDK 9.1.9」のような書式となり、該当するプロパティやJDKのファイル名も変更される。ただし、変更されるのはJDK 9以降のみであり、JDK 8以前のバージョン書式は従来のまま残される。

モジュール化によるJDKの内部構成の変更(JEP 220)

 Project Jigsawに伴うモジュール化の導入により、、JDK内部のパッケージ構成に大きな修正が加えられ、ディレクトリ構成やファイル名なども変更される。同時に、これまでランタイム・ライブラリ本体のファイルとして存在していたrt.jarも廃止される。そのため、もしJDKのインストール・ディレクトリ内の構造に依存するコードがある場合は正しく動作しなくなる可能性がある。