JJUG CCC 2017 Fallメモ【Java SE 9の紹介: モジュール・システムを中心に #ccc_e4】
JJUG CCC 2017 Fallに参加した。
表題のセッションに参加したので、参加メモを書いておく。
■JJUG CCC 2017 Fall
JJUG CCC 2017 Fall
■SlideShare
【概要】
2017年9月にリリースされたJava SE 9では、言語組み込みのモジュール・システムが追加されました。また、標準ライブラリ・言語仕様に改善が加えられています。
本セッションでは、アプリケーション基盤の構成に大きなインパクトがあるモジュール・システムを中心に、Java SE 9の全体像をお伝えします。
【内容】
■JavaSEってなんだっけ?
・JavaSEは「Java処理系の規格」
・JavaEEは「アプリケーションサーバの規格」
■JavaSE9のモジュール・システム
・Java8までの課題
①JAR地獄(JAR HELL)
→JARの関係性が複雑化し、依存関係がカオスになる状態
影響:下手にJARをクラスパスから外すと実行時例外が起こる etc
②内部向けパッケージの存在
→内部向けパッケージ(Java内部で使用するAPIやアプリ基盤の資産等)は本来外部からの使用を想定していない。
→Githubで「import sun.misc.Unsafe」をgrepすると58,233件ヒットする(!)
→移植性の低下、(既存のコードに影響を出さないように)実装の改善が難しくなる
・Java9ではJARを名前付きのモジュールとしてカプセル化し上記の解決を図れる
①JAR地獄(JAR HELL)
→モジュール単位で依存関係を整理。「module-info.java」に記述する。
②内部向けパッケージの存在
→外部からの使用を制限
・「exports」「requires」命令で公開範囲をパッケージ単位で制御する
→java.lang、java.utilパッケージなどは「java.base」パッケージに含まれ、全てのパッケージに暗黙的にrequiresされる。
・問題点:非公開なメンバへのリフレクションは外部モジュールからは通常不可能となり、色々困る。
例:DI先のフィールドは大抵privateなので、Injectできなくなってしまう etc
→リフレクションさせたいときは「open/opens」命令を追加することで、外部からのリフレクションを許可できる。
→OracleJDKでは外部モジュールからのリフレクションが可能らしい…いいのか
・問題点:世の中の多くのJARファイルは「module-info.class」を含んでいない
→経過措置として下記2モジュールが導入された。
①無名モジュール:クラスパス上のクラスファイルは無名モジュールに追加される
②自動モジュール:モジュールパス上のJARファイルのうち、module-info.classを持たないものが自動モジュールとして追加される
両者ともすべてのモジュール/パッケージをrequires/exportsし、自動モジュールはすべてのパッケージをopensする。
→配布されたOSSのメソッドをリフレクションしたいときは自動モジュールとして追加する必要がありそう
・モジュール化する場合もしない場合も『JDK9への移行ガイド』は必読。
Java Platform, Standard Edition Oracle JDK 9 Migration Guide, Release 9
・モジュール内のクラスのテスト
→ホワイトボックステストの実行時、JUnitやJMockit等のパッケージをテスト対象の資産はrequiresしていないため問題となる。
【正攻法】
・モジュール定義を一時的に上書きする
・javac/javaコマンドにオプションを指定
→クラス名の指定が必要なので煩雑
【次善策】
・あきらめてクラスパスに追加してテストする
■JavaSE9のその他のアップデート
(※かけ足で解説された)
・try-with-resourcesの改善
→try句の()内にBufferedReaderのインスタンスを取得するコードを書く必要があったが、try句以前で定義できるようになった。
・個人的にはJEP273 Secure Randomのアルゴリズム追加が気になった
→「-Djava.security.egd=file:/dev/urandom」のおまじないが不要となる日が来るのだろうか
→API追加されるようなので、アプリ基盤側でLinux使用時はデフォルトでurandomを使用するようにできるかも…?
■モジュール化の参考図書
Bakker, Mak (2017)『Java 9 Modularity』
shop.oreilly.com