今回はJVM component modelにおける用語について整理しておく。
前回、前々回とGradle3におけるJavaプロジェクトのビルドにおけるJVM component modelの入門を行っていった。
また、JVM component modelに関連する知識としてJigsawについて簡単なまとめを行った。
以上のエントリーの中で、僕は公式の(ただし今後変更される可能性のある)用語を幾つか混同していたので、それらをまとめておきたいと思う。また、公式のリンクは今後のリリースにともなって変更される可能性があるので、注意されたい。
用語
まず、基本的な用語を抑えておく
- コンポーネント
- ライブラリー
- ソースセット
- バリアント
- バイナリー
コンポーネント(component)
A component is a general concept for a piece of software that might be deliverable. Example of components are a standalone application, a web application, a library, etc. A component is often composed of other components.
コンポーネントは配布可能なソフトウェアの一部分を意味する。コンポーネントの例としてはスタンドアローンアプリケーション、ウェッブアプリケーション、一般的にライブラリーと呼ばれるものなどである。コンポーネントは他のコンポーネントとともに構成される。
以上が定義である。したがって、プロジェクトで成果物として作成されるものとして指定されるのがコンポーネントとなる。
ライブラリー(library)
A library is a buildable component. In the Java world, a library is often assimilated to a Jar file, but while a Jar file represents an output, a library is the description of how the output is build. A library is defined by the combination of its source sets and variants.
ライブラリーはビルド可能なコンポーネントである。一般的にライブラリーはjarファイルと同等視されている。しかしGradle3ではjarファイルは単なる出力であり、ライブラリーは成果物のビルド方法の定義である。ライブラリーは後に説明するソースセットとバリアントの組み合わせによって定義される。
ソースセット(source set)
A source set represents a logical group of source files in a component. Ass such, a source set is often an input to a single compilation task, which will produce an output(classes, compiled CSS, etc). A library may consist of multiple source sets.
ソースセットが表すのはコンポーネント内部のソースファイルの論理的グループである。したがって、ソースセットは一つのコンパイルタスクの入力である。なお、コンパイルタスクは出力(クラスファイルやコンパイルされたCSSなど)を生成する。ライブラリーは複数のソースセットで構成される。
バリアント(variant)
A variant represents a modulation of a component. A library, for example, might target Java 6 and Java 7, effectively producing two distinct outputs: a Java 6 jar and a Java 7 jar. In this case, the target platform is an example of a variant dimension. Custom library types may define their own variant dimensions, which will participate in dependency resolution.
バリアントが表すのはコンポーネントの種類である。ライブラリーは、例えば、Java6およびJava7を対象としており、結果として二つの異なる出力を生成する。Java6用のjarとJava7用のjarである。この例では対象プラットフォームのバリアント値を表している。ライブラリーによっては異なるバリアント値を取ることがあり、その値は依存性解決に利用されることがある。
バイナリー(binary)
A binary represents the output of a library. Given a combination of variants, a library may produce multiple binaries. A binary is often a consumable artifact of other components.
バイナリーはライブラリーの出力を表す。バリアントの組み合わせによってはライブラリーは複数のバイナリーを生成する。バイナリーは他のコンポーネントによって利用される成果物である。
また、基本的な用語に加え、次の一般的にも用いられている用語も利用する
API
- An API is a set of classes, interfaces, methods that are exposed to a consumer.
- An API specification is the specification of classes, interfaces or methods that belong to an API. It can be found in various forms, like
module-info.java
in Jigsaw, or theapi{...}
block that Gradle defines as part of those stories. Usually, we can simplify this to a list of packages, called exported packages.
- API仕様はAPIに含まれているクラス、インターフェース、メソッドの仕様である。これは様々な方法で定義されうる。Jigsawであれば
module-info.java
にて定義する。一方Gradleではapi{}
ブロックを利用する。通常、公開パッケージというパッケージのリストを指定することで簡略化する。
- ランタイムjarはAPIクラスと実行時にのみ使われる非APIクラスによって構成される。バリアント値にの組み合わせによっては複数のランタイムjarが存在しうる。ターゲットプラットフォーム、ハードウェア構成、ターゲットアプリケーションサーバーなど
Jigsawとの関連
次にJigsawとの関連を引用し、Jigsawの用語とJVM component modelの用語の対応を確認したい。
Gradleの公式ドキュメントでJigsawへの言及があるのは70.10 Enforcing API boundaries at compile time(API境界の強制をコンパイル時に行う)である。
Often a library will contain many types that -- despite having public visibility -- are intended for internal use only within that library. JDK 9 will introduce Jigsaw, the reference implementation of the Java Module System, which will provide both compile-time and run-time enforcement of strong encapusulation at the library (aka: module) level. This means that packages not intended for public consumption can remain private to the library, regardless whether the types within those packages have public visibility.
Gradle anticipates the arrival of JDK 9 and the Java Module System with an approach to specifying and enforcing strong encapsulation at compile-time. However, users need not wait for the arrival of JDK 9 to use it; this feature can be used on any version of the Java platform that Gradle supports.
--たとえアクセス修飾子がpublicであるにもかかわらず--ライブラリー内部だけでのみ使うように意図された型がライブラリーに含まれることはよくある。JDK 9が導入するJigsawは、Javaモジュールシステムの参照実装であるが、コンパイル時および実行時に強いカプセル化をライブラリー(モジュールとして知られている)に提供する。これによって、利用者に使われたくないパッケージ、たとえpublicにアクセス可能なパッケージであっても、それをライブラリー内だけで使えるようにすることができる。
GradleではJDK 9および、コンパイル時に強いカプセル化をおこなうアプローチのJavaモジュールシステムの到来を予想している。もちろんユーザーはJDK9のリリースを待つ必要はない。この機能(コンパイル時に強いカプセル化をおこなうこと)はGradleがサポートするすべてのJavaプラットフォームで利用できる。
ここで「強いカプセル化をライブラリー(モジュールとして知られている)」に着目すると、Gradle3のJVM component modelとJigsawの関係性が見えてくるようになる。
- | Gradle | Jigsaw |
---|---|---|
コンパイルの単位 | library | module |
公開パッケージの指定 | api{} ブロックでのexports(String) メソッド |
exports パッケージ名 |
依存ライブラリ(モジュール)の指定 | api.dependencies{} ブロックでのlibrary(String) メソッド |
requires パッケージ名 |
推移的依存ライブラリ(モジュール)の指定 | なし(すべて依存ライブラリーに推移的依存が適用される) | requires public パッケージ名 |
サービスローダー | なし | ユーザーモジュール : uses FQCN名 提供モジュール : provides FQCN名 with FQCN(実装)名 |
リンカー | なし | jlink コマンド |
ソースセット | java{} ブロックのsourceSet{} ブロックで指定 |
概念がない |
バリアント | targetPlatform (String)メソッド |
概念がないし、Java9固定 |
かなり中途半端な終わり方になるが、Gradle3 JVM component modelによるビルドとJigsawの関連が少し見えてきたのではないかと思う。また、自己中心的な考えだが、Gradleでの用語の確認ができたところが心強い。
次回は同一のプロジェクトをJigsawとGradle(2.9)とでビルドしてみたいと思う。
おわり