意訳には(僕に)定評のあるGradleのリリースノートですが、前回訳した時に、意図して訳さなかったのか、JavaOne開催中でProject Jigsaw関連に合わせるためにその時には書かれていなかったのか、どっちか定かではありませんが、リリースノートの意訳にExplicit declaration of library API with experimental Java software model(JavaソフトウェアモデルにおけるライブラリーAPIの明示的宣言)の訳がありませんでした。というわけで、意訳を書いておきます。
JavaソフトウェアモデルにおけるライブラリーAPIの明示的宣言
現在のJavaソフトウェアモデルでの開発はより強力になりました。それも、ライブラリーAPIを構成するパッケージと依存性を明示的に宣言できるようになったからです。
JVMライブラリーのAPIを宣言できることは次のような利点があります。
- ライブラリー利用者に不必要に内部で使われるクラスを見せなくて済む。
- ライブラリーの署名が変更されていない場合に、再コンパイルしなくて済む。
- JDK9にて登場するJavaモジュールシステムへの移行パスが提示される。JDK9が実行時におこなう分離作業をコンパイル時に先取りすることができる。
JVMライブラリーにふくまれるAPIのパッケージ宣言
ライブラリーのAPIで提供されるパッケージを宣言することができます。それはapi {}
ブロックに記述することで可能です。
model { components { myJvmLibrary(JvmLibrarySpec) { api { // `com.acme`パッケージが外部に公開されるAPIであると宣言する exports 'com.acme' } } } }
Gradleは自動的にmyJvmLibrary
コンポーネント用のAPIのjarを生成します。このコンポーネントに依存するコンポーネントはmyJvmLibrary
のAPIのjarに依存してコンパイルされます(つまり、myJvmLibrary
で公開されないクラスはコンパイル時に参照できない)。
API jarが含むクラスは宣言されたパッケージ以下に所属するクラスのみで構成されます。
- ライブラリー利用者がAPIでないクラスにアクセスしようとした場合にはコンパイルエラーとなります。
- APIとして公開されていないクラスが変更された場合は、利用者の方のライブラリーの再コンパイルは行われなくなります。
- APIの署名が変更されないようなAPI変更がなされた場合でも、ライブラリー利用者は再コンパイルの必要性がありません(つまり、実装クラスを変更して、パラメーター名を変更して、プライベートメソッドを追加した場合など)。
JVMライブラリーのAPIを構成する依存性の宣言
公開するパッケージと同様に、ライブラリーのAPIは依存ライブラリーを宣言できます。この場合、依存ライブラリーのAPIはライブラリーAPIに含まれることになります。
APIに含まれる依存性は、これまでのコンパイル依存性定義と同じような方法で宣言することができますが、api{}
ブロックの中で宣言する必要があります。
model { components { logging(JvmLibrarySpec) { api { exports 'my.logging.api' } } myJvmLibrary(JvmLibrarySpec) { api { exports 'com.acme' dependencies { // 'loggng'ライブラリーのAPIが'myJvmLibrary'のAPIに含まれるようになります。 // 'logging'ライブラリー中の'my.logging.api'パッケージに含まれるクラスが'myJvmLibrary'のAPIとして公開されます。 library 'logging' // ':util'プロジェクトの'calc'ライブラリーのAPIが'myJvmLibrary'のAPIに含まれるようになります。 library 'calc' project ':util' } } } } }
main
ライブラリーがmyJvmLibrary
ライブラリーに依存する場合、myJvmLibrary
のAPIおよび、logging
ライブラリーの公開APIを参照してコンパイルされることになります。myJvmLibrary
ライブラリーの非公開クラスや、logging
ライブラリーの非公開クラスにmain
ライブラリーのクラスがアクセスすることは認められません。
以上