JavaFX と Project Jigsaw
この記事は、JavaFX Advent Calendar 2015 の 12 日目の記事です。
昨日は @y_q1m さんの JavaFX アプリケーションに隠し Control を搭載する でした。
明日は @tomo_taka01 さんです
ごめんなさい。今日も小ネタです。
JavaOne に行ってからというもの、Project Jigsaw が面白くなっていろいろやってます。
ところで、JavaFX は Java SE 9 ではあまり新機能が盛り込まれないようなのです。Feature Complete がちょっと伸びたので、もう少し盛り込むようですが...
で、なんで新機能が少ないかというと、Project Jigsaw への対応が大変だったからということらしいのです。JavaFX 9 については、 id:aoe-tk さんの JavaFX9に追加される機能が増えるかもしれません を見ていただくとして、「じゃあ JavaFX のモジュールはどうなったの?」というところをちょっと調べてみました。
Java SE 9 の java コマンドには -listmods というオプションが追加になって、標準のモジュールの一覧を表示することができます。まずは、これを試してみましょう。
C:\>java -listmods 2>&1 | grep javafx - javafx.base@9.0 javafx.controls@9.0 javafx.deploy@9.0 javafx.fxml@9.0 javafx.graphics@9.0 javafx.media@9.0 javafx.swing@9.0 javafx.web@9.0
8 個のモジュールが JavaFX に関連するようです。
基本となるのが javafx.base で、コントロールは javafx.controls というようになっているのはわかるのですが、javafx.graphics などがよく分かりません。javafx.base が基本というのは分かりますけど、基本というのはどのぐらいの範囲、つまりどういうクラスが含まれているのかなどもよく分かりません。
これを調べるために、簡単なクラスで試してみました。
public class Test extends Application { @Override public void start(Stage stage) throws Exception { stage.show(); } public static void main(String... args) { launch(args); } }
単にステージを表示するだけのクラスです。これが含まれる JAR ファイルが test.jar だとします。で、この JAR ファイル (or クラス) がどのようなモジュールを使用しているかを調べるには、jdeps コマンドを使用します。
jdeps -s test.jar test.jar -> java.base test.jar -> javafx.graphics
オプションの -s はサマリだけを出力させるオプションです。
ステージを表示するだけで、他には何もやっていないのだから javafx.base に依存しているだろうと思ったら、javafx.graphics に依存していました。もちろん、javafx.graphics は javafx.base に依存しているでしょうから、間接的には依存はしているのですが...
-s オプションを外すと、もうちょっと詳しく見ることができます。
jdeps test.jar test.jar -> java.base test.jar -> javafx.graphics <unnamed> (test.jar) -> java.lang -> javafx.application -> javafx.stage
やはり、Application クラスや Stage クラスは javafx.graphics モジュールに含まれるようです。
ちょっとサンプルを改造してみましょう。
public class Test extends Application { @Override public void start(Stage stage) throws Exception { Label label = new Label("Label"); StackPane root = new StackPane(label); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); } public static void main(String... args) { launch(args); } }
こうすると、依存しているモジュールには javafx.control が出てくるはず。
jdeps -s test.jar test.jar -> java.base test.jar -> javafx.controls test.jar -> javafx.graphics
やはり、javafx.controls に依存していました。
しかし、javafx.base や javafx.graphics はよく分からないままです。こういう時は、モジュールを直接調べてみましょう。
一般的にモジュールには JAR ファイルを使用するのですが、標準のモジュールは JAR ファイルではなく、JMOD ファイルになっています。モジュールが JAR ファイルの時は jar コマンドで調べられるのですが、JMOD ファイルの時は jmod コマンドを使用します。どちらもオプションとして -p (--print-module-descriptor) を使用すれば、モジュールの情報を表示してくれます。
さっそくやってみましょう。JMOD ファイルは JDK のディレクトリの jmods ディレクトリにあります。
C:\Program Files\Java\jdk1.9.0\jmods>jmod javafx.base.jmod -p Name: javafx.base@9.0 Requires: jdk.jfr java.base [ MANDATED ] java.desktop Exports: com.sun.javafx to [javafx.controls, javafx.graphics, javafx.swing] com.sun.javafx.beans to [javafx.controls, javafx.graphics, javafx.fxml] com.sun.javafx.collections to [javafx.controls, javafx.graphics, javafx.swing, javafx.media] com.sun.javafx.binding to [javafx.controls, javafx.graphics] com.sun.javafx.event to [javafx.controls, javafx.graphics] com.sun.javafx.logging to [javafx.graphics] com.sun.javafx.property to [javafx.controls] com.sun.javafx.runtime to [javafx.graphics] javafx.beans javafx.beans.binding javafx.beans.property javafx.beans.property.adapter javafx.beans.value javafx.collections javafx.collections.transformation javafx.event javafx.util javafx.util.converter Conceals: com.sun.javafx.property.adapter Hashes: Algorithm: SHA-256 java.desktop: AE4yDbzkIjSeteMHRe9ZMpEkjE/u4PMGSL7WCwpEyOw= jdk.jfr: 6hhBHpCTp8ZkLutorg8GIFCp+D9MrL++mIsTh6grzyE= java.base: Jjip1psj45/C01FcGzXZc83cwqFHAZVVL3wSXJLiMpc=
外に公開しているパッケージは Exports の項に書いてあります。実をいうと、Exports の部分は順番がぐちゃぐちゃだったので、ソートしなおしてあります。
これを見ると、javafx.base は、意外にもグラフィックに関する部分はまったく含んでおらず、プロパティやバインドに関するクラスだけを含んでいるようです。
ただし、Requires の項に、java.desktop が含まれていることに注意が必要です。java.desktop は AWT や Swing が含まれているモジュールです。これに依存しているので、まったくグラフィックに関連がないというわけではないことが分かります。
次に、javafx.graphics です。
C:\Program Files\Java\jdk1.9.0\jmods>jmod javafx.graphics.jmod -p Name: javafx.graphics@9.0 Requires: java.base [ MANDATED ] java.desktop java.xml javafx.base [ PUBLIC ] Exports: com.sun.glass.ui to [javafx.web, javafx.media] com.sun.glass.utils to [javafx.web, javafx.media] com.sun.javafx.application to [javafx.web, javafx.controls, javafx.deploy, javafx.swing] com.sun.javafx.cursor to [javafx.deploy, javafx.swing] com.sun.javafx.css to [javafx.controls, javafx.deploy] com.sun.javafx.css.converters to [javafx.deploy] com.sun.javafx.css.parser to [javafx.deploy] com.sun.javafx.embed to [javafx.deploy, javafx.swing] com.sun.javafx.font to [javafx.web] com.sun.javafx.geom to [javafx.web, javafx.controls, javafx.swing, javafx.media] com.sun.javafx.geom.transform to [javafx.web, javafx.controls, javafx.swing, javafx.media] com.sun.javafx.iio to [javafx.web] com.sun.javafx.jmx to [javafx.web, javafx.swing, javafx.media] com.sun.javafx.menu to [javafx.controls, javafx.deploy] com.sun.javafx.perf to [javafx.deploy] com.sun.javafx.scene to [javafx.web, javafx.controls, javafx.deploy, javafx.swing, javafx.media] com.sun.javafx.scene.input to [javafx.web, javafx.controls, javafx.swing] com.sun.javafx.scene.text to [javafx.web, javafx.controls] com.sun.javafx.scene.traversal to [javafx.web, javafx.controls] com.sun.javafx.sg.prism to [javafx.web, javafx.swing, javafx.media] com.sun.javafx.stage to [javafx.controls, javafx.deploy, javafx.swing] com.sun.javafx.text to [javafx.web, javafx.deploy] com.sun.javafx.tk to [javafx.web, javafx.controls, javafx.deploy, javafx.swing, javafx.media] com.sun.javafx.util to [javafx.web, javafx.controls, javafx.fxml] com.sun.prism to [javafx.web, javafx.media] com.sun.prism.image to [javafx.web] com.sun.prism.paint to [javafx.web] com.sun.scenario.effect to [javafx.web] com.sun.scenario.effect.impl to [javafx.web] com.sun.scenario.effect.impl.prism to [javafx.web] javafx.animation javafx.application javafx.concurrent javafx.css javafx.css.converter javafx.geometry javafx.print javafx.scene javafx.scene.canvas javafx.scene.effect javafx.scene.image javafx.scene.input javafx.scene.layout javafx.scene.paint javafx.scene.shape javafx.scene.text javafx.scene.transform javafx.stage Conceals: <<省略>> Hashes: Algorithm: SHA-256 javafx.base: vKYsvlQtkuWc5pwKzHKlUfIp9lXa4SAjnU1TniODA74= java.xml: 1FV2E7DCyzOAroiUpxIyJMSg+AzeDI5qm1SmeFyqv4U= java.desktop: AE4yDbzkIjSeteMHRe9ZMpEkjE/u4PMGSL7WCwpEyOw= java.base: Jjip1psj45/C01FcGzXZc83cwqFHAZVVL3wSXJLiMpc=
こちらも、ソートしなおしてあります。
Applicationや、Scene、Stage も javafx.graphics に含まれていることが分かります。また、イベント関連、CSS 関連なども含まれています。
ちょっと意外だったのが、Animation や Shape も含まれていることです。こういうクラスたちは、外だしされるかと思ってましたけど、基本のところに含まれるんですね。
私がいつも使っているクラスたちは、ほぼ javafx.graphics で済んでしまうということも分かりました。あんまり、コントロール使わないんですよね ^ ^;;; もちろん、仕事では使ってますけど。
ということで、今日はここまで。