「The Java Module System」を読む会これまでのまとめ(その1)
Java読書会「The Java Module System」を読む会(第1~3回)のまとめ(その1) #javareading
Java読書会BOFでは、2019年11月から「The Java Module Systems」(洋書)を読み進めています。
- 作者:Nicolai Parlog
- 出版社/メーカー: Manning Publications
- 発売日: 2019/07/23
- メディア: ペーパーバック
Java読書会は毎月1回実施しており、2020年1月11日に第3回を実施しました。ここまで読んだ書籍の内容を復習のために簡単にまとめてみます。
第1章 First piece of the puzzle
この本の第1章では、なぜモジュールシステムが必要になったのか、これまでのクラスパスおよびJARファイルで構成していた場合で生じる問題を述べ、モジュールシステムが解決しようとしていることはどういうことかを述べています。
これまでのクラスパスおよびJARファイルの問題
- JAR地獄→JARファイルの過不足
- 単にJARファイルが足りない
- 同一FQCNが複数のJARに含まれる(同じライブラリの別バージョン、ファットJAR、ライブラリの分離独立や改名、など)
Google Guavaライブラリを例に、アプリケーションが利用する複数のライブラリでそれぞれ別のバージョンのGuavaライブラリを利用している場合、クラスパス上で先に検出したバージョンのクラスが使われてしまう問題(本来使いたかったクラスがシャドウ)が発生することが解説されています。この問題はコンパイル時・起動時にはチェックができず、良くて実行時にクラッシュ、悪ければ誤動作(動作継続)となってしまう点で厄介です。
- publicな型は同じアプリケーション内からは自由にアクセスできてしまう
- ライブラリのメンテナーが内部用に設けたpublicな型を変更したら、アプリケーションから使われていて思わぬ影響が
- セキュリティチェックが困難
sun.misc.unsafe の例が紹介されています。sun.misc.safeは内部用に設けられ、名前からもJDK外から利用しないことを主張しているのですが、Netty、PowerMock、Neo4J、Hadoop、Hazelcastなどが使っており、結果たくさんのアプリケーションから依存されるパッケージとなっています。
- 多数のクラス、JARファイルで構成されるアプリケーションの起動が遅い
クラスの検索にすべてのJARをなめるので遅いとあります。
読書会の場では、mavenやgradleのようなビルドツールでも、JARの過不足問題を解決できるとの意見が出ていました。
モジュール(JPMS:Java Platform Module System)の導入
Java 9(2017年9月リリース)で導入されたモジュール(Java Platform Module System、略してJPMS)は、モジュールの同一性とモジュール間の依存関係を扱えるようにしたものです。
- 基本特性
- グローバルユニークな名前を持つ
- 他のモジュールへの依存関係を宣言する
- 公開するパッケージの構成を制御して明確なAPIを持たせる
書籍では、グローバルユニークな名前として、パッケージ名の命名規約に類似してドメイン名の逆順を推奨しています。
特に最初の2つ(信頼性のある構成、強いカプセル化)は2大ゴールとされています。 JavaVM起動時にモジュールの依存関係を検証し、モジュールの不足や競合があればエラーとします。 モジュールの境界を越えてアクセスできるのは、公開すると宣言されたパッケージの中のpublicな型のみで、リフレクションでもこの制約を回避できません。
逆に、JPMSのゴールに含まれていないのは以下です。
- バージョン制御
- 中央リポジトリでのモジュール管理
- 動的なモジュールグラフ
OpenJDK のモジュール
OpenJDK自身は、100のモジュールから成り、これらはplatform modulesに分類されます。 platform modulesは、効率の良いJMOD形式のファイルで提供されます。platform modules以外のモジュールは、モジュラーJARファイルで提供されます。
java --list-modules
で、OpenJDKのモジュール一覧が表示されます。
java --describe-module <モジュール名>
でモジュールの説明が表示されます。
第2章は次回