java.base の module-info.java を読んでみた

# どこから新機能に触れるか

とてもたくさんの機能が追加された Java SE Development Kit 9 ですが、特に大物といえば [Java Platform Module System (JSR 376)](http://openjdk.java.net/projects/jigsaw/spec/) でしょう。様々なサイト[^1] で解説されているのでこれがどういうものかはここでは記述せず、実例を見ていきながら理解を深めていきたいと思います。

[^1]: 一例として→ https://www.slideshare.net/skrb/introduction-of-project-jigsaw

# 実例と言えば

やはりJDKに付いてくるソースが一番です。Oracle JDK 9 の Windows版では、デフォルトでは `C:\Program Files\Java\jdk-9.0.1\lib\src.zip` に入るようです。これを展開して確認します。
（従来は `lib` の下ではなかったので、変わっています）

## あれれ？ おかしいですね？

JDK 8 までは `src.zip` の中身はいきなり Java パッケージのフォルダがありましたが、JDK 9 ではまずモジュールのフォルダがあり、その下に `module-info.java` と Java パッケージのフォルダがあります。

```
C:\Java\JDKsrc>dir /b 1.8.0_131
com
java
javax
launcher
org

C:\Java\JDKsrc>dir /b 9.0.1
java.activation
java.base
java.compiler
java.corba
java.datatransfer
java.desktop
java.instrument
java.logging
java.management
java.management.rmi
java.naming
java.prefs
java.rmi
java.scripting
java.se
java.se.ee
java.security.jgss
java.security.sasl
java.smartcardio
java.sql
java.sql.rowset
java.transaction
java.xml
java.xml.bind
java.xml.crypto
java.xml.ws
java.xml.ws.annotation
javafx.base
javafx.controls
javafx.fxml
javafx.graphics
javafx.media
javafx.swing
javafx.web
jdk.accessibility
jdk.attach
jdk.charsets
jdk.compiler
jdk.crypto.cryptoki
jdk.crypto.ec
jdk.crypto.mscapi
jdk.dynalink
jdk.editpad
jdk.hotspot.agent
jdk.httpserver
jdk.incubator.httpclient
jdk.internal.ed
jdk.internal.jvmstat
jdk.internal.le
jdk.internal.opt
jdk.internal.vm.ci
jdk.jartool
jdk.javadoc
jdk.jcmd
jdk.jconsole
jdk.jdeps
jdk.jdi
jdk.jdwp.agent
jdk.jlink
jdk.jshell
jdk.jsobject
jdk.jstatd
jdk.localedata
jdk.management
jdk.management.agent
jdk.naming.dns
jdk.naming.rmi
jdk.net
jdk.pack
jdk.packager
jdk.packager.services
jdk.policytool
jdk.rmic
jdk.scripting.nashorn
jdk.scripting.nashorn.shell
jdk.sctp
jdk.security.auth
jdk.security.jgss
jdk.unsupported
jdk.xml.bind
jdk.xml.dom
jdk.xml.ws
jdk.zipfs

C:\Java\JDKsrc>
```

ちょっと一つのぞいてみます。

```
C:\Java\JDKsrc>dir /b 9.0.1\java.activation
com
javax
module-info.java

C:\Java\JDKsrc>
```

こういう感じです。

まあ言われてみれば（開いてみれば）なるほど、という感じです。

# 読んでみる

何はともあれ新登場の `module-info.java` でしょう。これを読んでいきます。せっかくなので、 `java.base` のものを見てみることにします。

## APIドキュメントみたいなコメントがある

先頭はお決まりのCopyrightなどのコメントで、次にAPIドキュメントのような `/**` で始まるコメント部があります。この中に、これまで見たことがないタグが使われています。

[Java Platform, Standard Edition Javadoc Guide Release 9](https://docs.oracle.com/javase/9/javadoc/JSJAV.pdf ) を頼りに意味を読み解いてきます。

|タグ|具体例|意味|JDK Bug System|
|:--|:-----|:----|:------------|
|`@index`|`{@index jrt jrt}`|`javadoc`ツールによってインデックスされる単語やフレーズを登録する。|[JDK-8144287](https://bugs.openjdk.java.net/browse/JDK-8144287)|
|`@extLink`|`{@extLink keytool_tool_reference keytool}`|外部ドキュメントへの参照。|[JDK-8178725](https://bugs.openjdk.java.net/browse/JDK-8178725)|
|`@provides`|`@provides java.nio.file.spi.FileSystemProvider`|`@provides`を使っていることの宣言|[JDK-8160196](https://bugs.openjdk.java.net/browse/JDK-8160196)|
|`@uses`|`@uses java.lang.System.LoggerFinder`|`@uses`を使っていることの宣言|同上|
|`@moduleGraph`|`@moduleGraph`|モジュールのサブグラフ|[JDK-8173303](https://bugs.openjdk.java.net/browse/JDK-8173303)|

新しく追加されたタグがこれで全てかはわかりませんが、`java.base`の`module-info.java`での新出はこれら5つでした。
`@moduleGraph` というのは、[java.baseのAPIドキュメント](https://docs.oracle.com/javase/9/docs/api/java.base-summary.html)で表示されていますね。ふむふむなるほど。

## あとはモジュール定義がずらずらと

```java
    exports java.io;
```

とか、

```java
    exports jdk.internal.jmod to
        jdk.compiler,
        jdk.jlink;
```

という感じ。`export`先が1つしかないときは

```java
    exports sun.util.resources to jdk.localedata;
```

のように1行で書いているようです。
`exports` の動作については、[module-info.javaのディレクティブまとめ](http://d.hatena.ne.jp/bitter_fox/20160921/1474476977) がわかりやすいですね。

最後は

```java
    uses sun.util.spi.CalendarProvider;
    provides java.nio.file.spi.FileSystemProvider with jdk.internal.jrtfs.JrtFileSystemProvider;
}
```

で終わっています。
`uses`と`provides`についても同じブログ [JigsawでSPIを使用する](http://d.hatena.ne.jp/bitter_fox/20160720/1469042323) がわかりやすいと思います。