NetBeans 7.2の新規プロジェクト「JavaFX アプリケーション」で作成したプログラムは、JavaFX ライブラリのJARファイルをクラスパスに指定することなく実行できます。
試しに、NetBeansで[ファイル]メニュー>[新規プロジェクト...]で、カテゴリ欄で[JavaFX]を選択、プロジェクト欄で[JavaFXアプリケーション]を選択し、[次へ]ボタンを押します。
これで作成したプロジェクトは、雛形のソースコードとして画面上にボタンが1つ表示するものが生成されています。これをビルドして実行します。NetBeans上であればプロジェクトの設定にJavaFXライブラリ関係が含まれるので実行できるのは当然です。
しかし、このプロジェクトでビルドしたプログラムのJARファイルを、コマンドラインでJavaFX関係のJARファイルをクラスパスに指定しなくても起動できます。
C:\work\JavaFXApplication5> java -jar dist\JavaFXApplication5.jar :
Windowsのエクスプローラ上でJavaFXApplication5.jarファイルをダブルクリックしても起動します。
JavaFXのライブラリをどこから読んでいるのでしょうか?
まず考えられるのは、アプリケーションJARファイルのマニフェストに、JavaFX関係のライブラリが指定されているのではないか、です。
Class-Path:属性に、実行に必要なJARファイルへの相対パスを記載しておくと、別途クラスパスに指定しなくても記載したJARファイルが利用可能になります。
マニフェストを見てみましょう。
Manifest-Version: 1.0 JavaFX-Version: 2.2 implementation-vendor: torutk implementation-title: JavaFXApplication5 implementation-version: 1.0 JavaFX-Application-Class: javafxapplication5.JavaFXApplication5 JavaFX-Class-Path: Created-By: JavaFX Packager Main-Class: com/javafx/main/Main
うーむ、Class-Path:属性はありませんね。想定が外れました。
と、ここで気になるのは、Main-Class:属性です。実行可能JARファイルでは、mainメソッドを持つクラスをMain-Class:属性に記載しますが、
Main-Class: com/javafx/main/Main
このようなクラスは、今作成したJavaFXプロジェクトにはありません。
ここで、生成されたアプリケーションJARファイルの中に含まれるファイル一覧を見てみます。
C:\work\JavaFXApplication5> jar tf dist\JavaFXApplication5.jar META-INF/ META-INF/MANIFEST.MF javafxapplication5/ javafxapplication5/JavaFXApplication5$1.class javafxapplication5/JavaFXApplication5.class com/ com/javafx/ com/javafx/main/ com/javafx/main/Main$1.class com/javafx/main/Main$2.class com/javafx/main/Main.class com/javafx/main/NoJavaFXFallback.class C:\work\JavaFXApplication5>
なんと、com/javafx/main/Main.class などいくつかアプリケーションプロジェクトのソースファイルにはないクラスが追加されています。
どうやら、NetBeans 7.2のJavaFXアプリケーションプロジェクトで作成するアプリケーションでは、実行時に最初に呼ばれるmainメソッドは、アプリケーション(この例ではJavaFXApplication5クラス)のmainメソッドではなく、com.javafx.main.Mainクラスのmainメソッドになります。
このcom.javafx.main.MainクラスはJDK 7に含まれているものかNetBeansが独自に提供するものかを調べてみました。すると、
[JDK 7インストールディレクトリ]\lib\ant-javafx.jar の中に存在していました。
このMainクラスの中を調べると、JDK 7u6のようにJavaFXライブラリを同梱(cobundled)している場合、[システムプロパティjava.home]\libにある以下のJARファイルを指定しURLClassLoaderを生成しています。
- jfxrt.jar
- deploy.jar
- plugin.jar
- javaws.jar
これで、JavaFX関係のJARファイルをクラスパスに指定しなくても実行できるわけが分かりました。
このMainクラスを調べてみると、システムプロパティ javafx.verboseがtureのときに、いろいろメッセージを表示するコードがありました。
- Djavafx.verbose=true を指定して実行してみます。
C:\work\JavaFXApplication5> java -Djavafx.verbose=true -jar dist\JavaFXApplication5.jar java.version = 1.7.0_06 java.runtime.version = 1.7.0_06-b24 appName = javafxapplication5.JavaFXApplication5 Unable to find preloader class name preloaderName = null embeddedArgs = [] commandLineArgs = [] 1) Try existing classpath... ===== URL list file:/C:/work/JavaFXApplication5/dist/JavaFXApplication5.jar 2) Try javafx.runtime.path property... 3) Look for cobundled JavaFX ... [java.home=C:\Program Files\Java\jdk1.7.0\jre ===== URL list file:/C:/work/JavaFXApplication5/dist/JavaFXApplication5.jar file:/C:/Program%20Files/Java/jdk1.7.0/jre/lib/jfxrt.jar file:/C:/Program%20Files/Java/jdk1.7.0/jre/lib/deploy.jar file:/C:/Program%20Files/Java/jdk1.7.0/jre/lib/plugin.jar file:/C:/Program%20Files/Java/jdk1.7.0/jre/lib/javaws.jar Try calling Class.forName(javafxapplication5.JavaFXApplication5) using classLoad er = java.net.URLClassLoader@7bc221b2 found class: class javafxapplication5.JavaFXApplication5 launchApp: Try calling com.sun.javafx.application.LauncherImpl.launchApplication Autoconfig of proxy is completed. JavaFX: using com.sun.javafx.tk.quantum.QuantumToolkit C:\work\JavaFXApplication5>
ひとまず、ここまで。