[戻る]

Java読書会BOF 「The Java Module System」を読む会 第3回

開催概要
日時 2020年1月11日 10:00 - 17:00
場所 川崎市教育文化会館 第3会議室
出席者(敬称略) 高橋(智)、高橋(徹)、大部、今井、遠藤、石黒、平山、岩室(書記)

3 Defining modules and their properties

3.1 Modules: The building blocks of modular applications

3.1.4 The many types of modules

p.59 先頭 (Platform modules and most application modules have ...) から。

  • observable - (p.58に記載) ランタイムが提供する全てのプラットフォームモジュールおよびアプリケーションモジュール。
  • non-observable - 処理系自身は提供しているが、jlink等によりランタイムから除外されたモジュールを指す?

3.2 Readability: Connecting the pieces

  • customer / bar: 「foo」「bar」の「bar」と、酒場の「bar」をかけている模様。
  • 「reads」という概念があり、モジュール間の関係性を、モジュールデスクリプタの「requires」や、「--add-reads」オプションで指定できる。

3.2.1 Achieving reliable configuration

  • 異なるモジュールでpackage名が重複することは許されない。
  • exportしないpackageはモジュールの外部から保護される。

⇒ 使用するライブラリと同じpackageに属すクラスを定義することで、自分のライブラリやアプリケーションコードから対象ライブラリのパッケージスコープ要素にアクセスするような手段は使えなくなる。

3.2.2 Experimenting with unreliable configurations

  • 同じ名前のモジュールがモジュールパス内に複数ある場合はエラーになる。(異なるjarファイルでも、モジュールデスクリプタに記述したモジュール名を同じにすることはできる)

  • モジュールの命名指針 → パッケージ名の命名指針(reverse domain notation)と同様の指針が推奨されている。

  • the modular diamond of death (Figure 3.6)
    • 左の図の場合 → 同じパッケージをエクスポートしている異なるモジュールがモジュールパスに存在すると、エクスポートしているパッケージが重複している旨のエラーになる。
    • 右の図の場合 → 左の図のエラーを回避するため、どちらか一方のモジュールを除去すると、使用しているモジュールが存在しない旨のエラーになる。

3.3 Accessibility: Defining public APIs

3.3.1 Achieving strong encapsulation

3.3.2 Encapsulating transitive dependencies

  • JPMSのようなモジュールシステムは他の言語にあるのか? → 少なくとも今回の参加者で、同じようなアクセス制御のある言語は聞いたことがない。
    • .NET Frameworkの場合、異なる概念ではあるが、アセンブリのリンクをビルド時に指定/使用されたバージョンに限定する仕組みがある。(「厳密名」「グローバル アセンブリ キャッシュ(GAC)」などのキーワードを参照)
  • 他のモジュールを使用するには原則としてrequiresに指定する必要がある。
    • ただし、利用されるモジュール側がtransitiveを使用することにより、暗黙のreadabilityが追加されるため、使用する全てのモジュールを明示的に記述しなくて良い場合がある。(詳細はセクション11.1「Implied readability: Passing on dependencies」参照)
      • p.71のセクション番号「11.11」は「11.1」の間違い。

3.3.3 Encapsulation skirmishes

  • Springのようなフレームワークがリフレクションでアプリケーションコード側にアクセスする場合、アプリケーション側はパッケージもしくはモジュール全体をopenにする必要がある。(「opens パッケージ名」もしくは「open module モジュール名」)
    • モジュールパスでなくクラスパスに指定されている場合は、モジュール側も含めてどこからでもアクセス可能である。
      • よって、アプリケーションコードをモジュールに含めない(=クラスパスに含める)場合はopenする必要はない。
  • モジュールに対するreadが無くても(requiresを指定してなくても)、そのモジュールに含まれるクラス/インターフェースを直接用いるのでなければ、そのモジュールがエクスポートしているパッケージをリフレクションでアクセス可能。

3.4 The module path: Letting Java know about modules

3.4.1 Module resolution: Analyzing and verifying an application's structure

  • モジュールパスに複数のディレクトリを指定した場合、異なるディレクトリに同名のモジュールが複数あると、最初に見付かったモジュールが選択される。(後続のモジュールは使用されないだけでエラーにならない)
    • 同一ディレクトリ内にある同名のモジュールはエラーになる。

    • これまで説明されてきた厳密なチェックに反する仕様なのではないか? ⇒ 著者は「unfotunate」と書いており、良い仕様とは考えていないと思われる。

    • このような振る舞いは意図的に実現する必要があると考えられるので、何らかの不可欠なユースケースがあったのではないか?
      • 例えば、あるモジュールのベータ版だけを別のディレクトリに置き、一時的にそのディレクトリをモジュールパスに加えることで、静的な部分に手を加えることなくベータ版のモジュールを使用することができる。
    • せめて警告メッセージなどを出した方がよいのではないか?
      • 実際の処理系ではメッセージなどは出ないのか? ⇒ 宿題
    • 同じライブラリの新旧両方をを含めた場合、従来のクラスパスだと新旧のクラスが混じる可能性があるが、モジュールパスだと新旧のどちらか一方しか使われないという利点はあるのではないか。

3.4.2 Module graph: Representation of an appliation's structure

3.4.3 Adding modules to the graph

3.4.4 Adding edges to the graph

  • 「--add-reads」オプションで循環参照を付けるとエラーになるか? ⇒ 宿題?
    • dynamicならエラーにならない? (セクション8.3.2に書いてあるらしい)

3.4.5 Accessibility is an ongoing effort

  • 「shell game」: いんちき詐欺、ペテンの意
  • 「green-field」:(物理的な)インフラ用語で「整地されていない、草ぼうぼうの土地」の意。対語は「brown-field」(「既に整地されていて工場などが建っている土地」の意)

4 Building modules from source to JAR

4.1 Organizing your project in a directory structure

4.1.1 New proposal --- new convention?

  • これは新しい提案/規約か? ⇒ そうではない。(JPMSの)入門資料などでは採用されているが、(著者としては)推奨しない。後述の、既存のビルドツール(MavenやGradle)が採用しているディレクトリ構造を推奨する。

4.1.2 Established directory structure

Note

次回はセクション4.1.3から。

(以上)

[戻る]