最新のjava言語仕様で見るモジュールシステム #jjug

19

Click here to load reader

Upload: justsystems-corporation

Post on 21-Jan-2018

488 views

Category:

Software


0 download

TRANSCRIPT

Page 1: 最新のJava言語仕様で見るモジュールシステム #jjug

最新のJava言語仕様で見るモジュールシステムfrom The Java® Language Specification

Java SE 9 Edition

JJUG ナイト・セミナー2017/12/27

Page 2: 最新のJava言語仕様で見るモジュールシステム #jjug

自己紹介

• 株式会社ジャストシステム 福嶋 航• Twitter @fukushiw• Java歴約20年、JavaでWebサービス作っています• #Java100 本ノックの人https://github.com/JustSystems/java-100practices

Page 3: 最新のJava言語仕様で見るモジュールシステム #jjug

本資料に出てくる内容は特に断りがない場合すべて、

The Java® Language Specification Java SE 9 Edition https://docs.oracle.com/javase/specs/jls/se9/html/index.html

(2017年12月22日現在)

に記載されている内容をベースにしております。

あれ、おかしいな? と思ったら上記原典をご覧下さい。

Page 4: 最新のJava言語仕様で見るモジュールシステム #jjug

最新のJava言語仕様で見るモジュールシステム

Page 5: 最新のJava言語仕様で見るモジュールシステム #jjug

Java SE 9

91 JEPshttp://openjdk.java.net/projects/jdk9/

Page 6: 最新のJava言語仕様で見るモジュールシステム #jjug

中でも超ビッグな変更のアイツ

Page 7: 最新のJava言語仕様で見るモジュールシステム #jjug

Java PlatformModule System

(JSR 376)http://openjdk.java.net/projects/jigsaw/spec/

Page 8: 最新のJava言語仕様で見るモジュールシステム #jjug

Java言語仕様にどう記載されたかを追いかけてみた

Page 9: 最新のJava言語仕様で見るモジュールシステム #jjug

https://docs.oracle.com/javase/specs/jls/se9/html/index.html

Page 10: 最新のJava言語仕様で見るモジュールシステム #jjug

(snip)If a set of packages is sufficiently cohesive, then the packages may be grouped into a module. (snip) Thus, a module controls how its packages use other modules (by specifying dependences) and controls how other modules use its packages (by specifying which of its packages are exported).(snip)

• 十分に凝集されたパッケージセットはモジュールとしてグループ化されうる

• モジュールは他のモジュールをどう使うか、他のモジュールからどう使われるかを制御する

Chapter 7. Packages and Modules

Page 11: 最新のJava言語仕様で見るモジュールシステム #jjug

ModuleDeclaration: {Annotation} [open] module Identifier {. Identifier} { {ModuleDirective} }

ModuleDirective: requires {RequiresModifier} ModuleName ; exports PackageName [to ModuleName {, ModuleName}] ; opens PackageName [to ModuleName {, ModuleName}] ; uses TypeName ; provides TypeName with TypeName {, TypeName} ;

RequiresModifier: (one of) transitive static

7.7. Module Declarations

Page 12: 最新のJava言語仕様で見るモジュールシステム #jjug

ModuleDeclaration: {Annotation} [open] module Identifier {. Identifier} { {ModuleDirective} }

ModuleDirective: requires {RequiresModifier} ModuleName ; exports PackageName [to ModuleName {, ModuleName}] ; opens PackageName [to ModuleName {, ModuleName}] ; uses TypeName ; provides TypeName with TypeName {, TypeName} ;

RequiresModifier: (one of) transitive static

7.7. Module Declarations

せっかくなので比較的出現頻度が低そうなやつらを調べてみた

Page 13: 最新のJava言語仕様で見るモジュールシステム #jjug

{Annotation}• ElementType に追加されている

https://docs.oracle.com/javase/9/docs/api/java/lang/annotation/ElementType.html#MODULE

• JDK 9.0.1 で、アノテーションのタイプに MODULE が出現するのは、 @Deprecated と @SuppressWarnings の2つ

Page 14: 最新のJava言語仕様で見るモジュールシステム #jjug

open

コンパイル時 実行時

open明示的にexport宣言されたパッケージへのアクセ

スを許可

全パッケージへのアクセスを許可

非open

明示的にexport宣言されたパッケージへのアクセスを許可

Page 15: 最新のJava言語仕様で見るモジュールシステム #jjug

opensコンパイル時 実行時

opens アクセス不許可

1.public/protectedな型とその型のpublic/protectedなメンバーへのアクセスを許可

2.すべての型とメンバーへのリフレクションアクセスを許可

exports

1.public/protectedな型とその型のpublic/protectedなメンバーへのアクセスを許可

2.それらの型とメンバーへのリフレクションアクセスを許可

Page 16: 最新のJava言語仕様で見るモジュールシステム #jjug

transitive• requires につけて使う

例)requires transitive java.desktop;• requires transitive の定義があるモジュール(例:m.B)を

requiresしているモジュール(例:m.A)が、暗黙的にその定義されているモジュール(例:m.C)をrequiresしていることになるmodule m.A { requires m.B;}module m.B { requires transitive m.C;}module m.C { exports p;}

モジュール m.A のコードからパッケージ p のコードが呼び出せる

Page 17: 最新のJava言語仕様で見るモジュールシステム #jjug

static• requires につけて使う

例)requires static hogehoge;

• コンパイル時には依存が必須だが、実行時には必須ではないことを示す• JDK 9.0.1 のソースには出現しない• lombokのようにコンパイル時のみ必要なアノテーションを使うときとかに使う?

Page 18: 最新のJava言語仕様で見るモジュールシステム #jjug

(ついでに) module-info.java• ソースのルートディレクトリに置く

例)com.example.hoge パッケージを使う場合、comフォルダのあるディレクトリにmodule-info.javaを格納する。

src├ module-info.java└ com  └ example    └ hoge      └ Main.java

• 正しくモジュールが作成できたかどうか確認する 例) jar -d -f modulehoge.jar

「モジュール・ディスクリプタが見つかりません。自動モジュールが導出されました。」というメッセージが出た場合、 module-info が正しく定義できていない。

これは言語仕様には書いていないので実際にやってみた

Page 19: 最新のJava言語仕様で見るモジュールシステム #jjug

まとめ• モジュールシステムの仕様は Java言語仕様 (Java SE 9 Edition) で確認できる

• 7章、特に7.7節にメインの説明がある• モジュールにつけられるアノテーションタイプ(MODULE)が追加されている

• JDK 9.0.1 では @Deprecated と @SuppressWarnings がある• module の前に open がつくと:

• コンパイル時、明示的にexport宣言されたパッケージへのアクセスを許可• 実行時、全パッケージへのアクセスを許可

• opens ディレクティブがついているパッケージは:• コンパイル時にはアクセス不許可• 実行時にはpublic/protectedな型とその型のpublic/protectedなメンバーへ

のアクセスを許可;すべての型とメンバーへのリフレクションアクセスを許可• requires transitive しているモジュールは、その宣言をしているモジュールをrequires

しているモジュールからも(直接のrequires宣言をしなくても)呼び出せるようになる• requires static しているモジュールは、コンパイル時のみ依存するが実行時にはなくて

もよい• module-info.java はソースのルートディレクトリに置く

• 正しくモジュールが作成できたかどうかは jar -d -f modulehoge.jar で確認