JavaSE7でのJavaFXの実行時エラーについて調べてみた

NetBeans7.4を使って、JavaFXプロジェクト(プラットフォームにJavaSE7)を作成。コンパイルできるのに、実行時に「java.lang.ClassNotFoundException: javafx.application.Application」エラーになるのでちょっと調べてみたことをメモ。

  • NetBeansでの実行時エラー画面

コマンドラインで「javac」を使ってコンパイルした場合は、コンパイルエラーになることを確認。

NetBeansコンパイルエラーにならない理由を調べる。

JavaSE7をプラットフォームに指定するとコンパイル時のライブラリーに「javafx.classpath.extension」が追加されている?

  • project.properties

javafx.classpath.extension」がどこを指しているのかは、「AppName/nbproject」配下の「project.properties」で以下のように設定されていた

...
javac.classpath=\
    ${javafx.classpath.extension}
...
javafx.classpath.extension=\
    ${platforms.JDK_1.7.home}/jre/lib/jfxrt.jar:\
    ${platforms.JDK_1.7.home}/jre/lib/javaws.jar:\
    ${platforms.JDK_1.7.home}/jre/lib/deploy.jar:\
    ${platforms.JDK_1.7.home}/jre/lib/plugin.jar

JavaSE8をプラットフォームに指定するとコンパイル時のライブラリーに「javafx.classpath.extension」の指定はない?

JavaSE7とJavaSE8の違いを調べてみる。

以下の実装をJavaSE7とJavaSE8を使って実行。
ブートストラップクラス、拡張機能クラス、ユーザクラスを表示

import java.net.URL;

public class Test {
    public Test() {
        String pathProp = System.getProperty("sun.boot.class.path");
        String[] paths = pathProp.split(":");
        for (String path : paths) {
            System.out.println(String.format("path:%s", path));
        }
        System.out.println("**********");
        String extPathProp = System.getProperty("java.ext.dirs");
        String[] extPaths = extPathProp.split(":");
        for (String path : extPaths) {
            System.out.println(String.format("java.ext.dir:%s", path));
        }
        System.out.println("**********");
        String classPathProp = System.getProperty("java.class.path");
        String[] classPaths = classPathProp.split(":");
        for (String path : classPaths) {
            System.out.println(String.format("class.path:%s", path));
        }
        System.out.println("**********");
        ClassLoader loader = getClass().getClassLoader();
        URL url = loader.getResource("javafx/application/Application.class");   // <--- JavaSE7ではここでエラー
        System.out.println(String.format("Application URL:%s", url.toString()));
    }
    public static void main(String... args) {
        new Test();
    }
}
  • JavaSE7での実行結果
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/resources.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/rt.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/sunrsasign.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jsse.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jce.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/charsets.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfr.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/classes
**********
java.ext.dir:/Users/tomo/Library/Java/Extensions
java.ext.dir:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/ext
java.ext.dir:/Library/Java/Extensions
java.ext.dir:/Network/Library/Java/Extensions
java.ext.dir:/System/Library/Java/Extensions
java.ext.dir:/usr/lib/java
**********
class.path:.
**********
Exception in thread "main" java.lang.NullPointerException      // <---「javafx.application.Application.class」がloadできない?
	at Test.<init>(Test.java:25)
	at Test.main(Test.java:28)
  • JavaSE8での実行結果
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/resources.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/rt.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/sunrsasign.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/jsse.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/jce.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/charsets.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/jfr.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/classes
**********
java.ext.dir:/Users/tomo/Library/Java/Extensions
java.ext.dir:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext
java.ext.dir:/Library/Java/Extensions
java.ext.dir:/Network/Library/Java/Extensions
java.ext.dir:/System/Library/Java/Extensions
java.ext.dir:/usr/lib/java
**********
class.path:.
**********
Application URL:jar:file:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext/jfxrt.jar!/javafx/application/Application.class
  • jfxrt.jarの場所

JavaSE7では「jfxrt.jar」は「jre/lib」配下にあるのに「sun.boot.class.path」に含まれていない

version location
JavaSE7 /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib
JavaSE8 /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext
javac -cp /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfxrt.jar:. Test.java
java -cp /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfxrt.jar:. Test
  • JavaSE7での実行結果(jfxrt.jarをクラスパスに指定した場合)

当然ですが、「NullPointerException」は解消

path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/resources.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/rt.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/sunrsasign.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jsse.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jce.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/charsets.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfr.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/classes
**********
java.ext.dir:/Users/tomo/Library/Java/Extensions
java.ext.dir:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/ext
java.ext.dir:/Library/Java/Extensions
java.ext.dir:/Network/Library/Java/Extensions
java.ext.dir:/System/Library/Java/Extensions
java.ext.dir:/usr/lib/java
**********
class.path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfxrt.jar
class.path:.
**********
Application URL:jar:file:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfxrt.jar!/javafx/application/Application.class

最後に

今更ながら、まだまだ勉強不足でクラスロードのことなど、問題に直面して初めて調べてみて、、、(汗)
NetBeansでのbuildはまだ調べてないです、、、