メインクラスがJPMSにどのように影響するかを理解します

セバスチャン・S:

私は、Applicationクラスの場合は完璧に動作非常に基本的なJavaFXアプリケーション持っていない主なクラス:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;

public class Main {

    public static void main(String[] args) {
        Application.launch(App.class, args);
    }

}

public class App extends Application {

    @Override
    public void start(Stage primaryStage) {
        FXMLLoader loader = new FXMLLoader(); // works
    }

}

私は(を含むほとんどのチュートリアルで推奨される方法である2一緒にマージするときしかし、OpenJFXの公式ドキュメントを)、モジュールシステムがスローされますIllegalAccessError(少なくとも、OpenJDKの11.0.2には):

public class MainApp extends Application {

    @Override
    public void start(Stage primaryStage) {
        FXMLLoader loader = new FXMLLoader(); // throws IllegalAccessError
    }

    public static void main(String[] args) {
        launch(MainApp.class, args);
    }

}

例外は次のとおりです。

java.lang.IllegalAccessError:クラスcom.sun.javafx.fxml.FXMLLoaderHelper(名前のモジュールで@0x642c1a1b)できないアクセスクラスcom.sun.javafx.util.Utils(モジュール内のjavafx.graphics)モジュールがあるためjavafx.graphicsエクスポートしませんcom.sun.javafx.util無名のモジュールに@0x642c1a1b

奇妙なことは、私がいること、あるいなかった積極的なモジュールシステムを使用しています。私は追加しませんでしたmodule-info.java私のプロジェクトに。だから私はすべてが任意の無名のモジュールにエクスポートされます必要がありますと仮定しましたか?しかし、それにもポイントではありません。

主な質問は:なぜ、同じコード振る舞いが異なり、二つのクラスに分散しない場合はどうなりますか?どちらの場合にもFXMLLoader用途com.sun.javafx.fxml.FXMLLoaderHelperでの使用をオンにし、com.sun.javafx.util.Utilsだから私は両方のケースでまたはなしで例外を取得する必要がありますどちらか。違いはなんですか?

ホセ・ペリーダ:

そこすでにご質問には、部分的に適用することができることを掲載いくつかの答えがありますが、ここでそれらを収集し、完全な答えにそれらを提示すると便利かもしれません。

Applicationクラス

答えでのJavaFXランタイムコンポーネントが欠落しているMavenのシェード私はあなたが使用した場合、理由を説明Applicationメインクラスとしてクラスを、あなたはモジュールシステムを使用することが期待されているが。

要約すれば:

あなたが読むことができるよう、ここで

このエラーは、から来ているsun.launcher.LauncherHelperjava.baseモジュール(内リンク)。

メインアプリが拡張する場合Applicationとがあるmain方法を、LauncherHelperするかどうかをチェックしますjavafx.graphicsという名前のモジュールとして存在するモジュール:

Optional<Module> om = ModuleLayer.boot().findModule(JAVAFX_GRAPHICS_MODULE_NAME);
if (!om.isPresent()) {
    abort(null, "java.launcher.cls.error5");
}

そのモジュールが存在しない場合は、打ち上げが中止されます。

すべてのJavaFX 11ジャーを持っているmodule-info.classので、定義によって、これらはモジュールパスに追加されることが期待される、ファイルを。

あなたが経由で実行しない場合でも、Applicationクラス、そのチェックは行われません。

メインクラス

この他の回答のMaven&Eclipseの間で異なる挙動はJavaFXの11アプリが起動し、使用するとき、それはモジュラーシステムなしで動作する理由を説明しLauncherたMavenで(メインクラスは、アプリケーションを拡張していない)クラスをexec:javaプラグイン。

要約すれば:

  • ランチャーを使用すると、上記克服するために必要されるsun.launcher.LauncherHelper問題を。
  • 単離されたスレッドにすべての依存関係をロードするクラスパスにMavenのプラグインの実行、のようなので、この場合のIntelliJを行います。

コマンドラインを確認する場合は、実行するとMain.main()

/path/to/jdk-11.0.2.jdk/Contents/Home/bin/java \
    "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=60556:/Applications/IntelliJ IDEA.app/Contents/bin"  \
    -Dfile.encoding=UTF-8  \
    -classpath /path/to/so-question-54756176-master/target/classes:/path/to/.m2/repository/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2.jar:.../path/to/.m2/repository/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2-mac.jar  \
    Main

JavaFXのSDKからのすべてのJavaFX jarがクラスパスに追加され、あなたは古典を実行していますjava -cp ... Main

行方不明javafx.fxml

これらの他の答えのIntelliJ IDEA -エラー:JavaFXのランタイムコンポーネントが不足している、そしてこのアプリケーションを実行するために必要とされるが、モジュールシステム上で実行したときにあなたが得るが、あなたは追加しないエラーを説明javafx.fxmlする--add-modulesオプションを選択します。

Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module @0x5fce9dc5) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util to unnamed module @0x5fce9dc5
    at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38)
    at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056)

あなたのエラーは、FXMLを使用しているが、それは反射を経由してアクセスしようとしているので、それは、モジュールパスで解決することはできません、あなたがいることを開いていなかったので、それが失敗したことを言うjavafx.graphicsあなたの無名のモジュールに。

だから今、あなたは要求されます:私は設定しませんでしたjavafx.graphics最初の場所で!

さて、あなたはありませんでしたが、IntelliJのはあなたのためにそれをやりました!

あなたが実行したときに、コマンドラインを確認してくださいMainApp.main()

/path/to/jdk-11.0.2.jdk/Contents/Home/bin/java \
    --add-modules javafx.base,javafx.graphics \
    --add-reads javafx.base=ALL-UNNAMED \
    --add-reads javafx.graphics=ALL-UNNAMED \
    "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=60430:/Applications/IntelliJ IDEA.app/Contents/bin" \
    -Dfile.encoding=UTF-8 \
    -classpath /path/to/so-question-54756176-master/target/classes:/path/to/.m2/repository/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2.jar:.../.m2/repository/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2-mac.jar \
    MainApp

あなたは、デフォルトではそのIntelliJのを見ることができます追加javafx.baseしてjavafx.graphicsだから、唯一javafx.fxml欠けている(そして、あなたはもちろん、モジュールのパスを追加する必要があります)。

あなたが指摘したように推奨ソリューションは、であるドキュメント

どちらのコマンドラインで、使用して--module-pathあなたのJavaFX SDK libフォルダへのパスを含めるために、そして--add-modules含まれるようにjavafx.fxml(あなたがコントロールを持っていない場合)この場合には。

IntelliJのVM引数

またはMavenプラグインを使用。いくつかの時点で、あなたがアプリケーションを実行するためのプラグインを使用する必要がありますので、あなたのIDEを残すことがあります。

Mavenの幹部

Mavenの上の最後の注意execプラグインは、場合にあなたはそれを使用します。

どのようなプラグインがするまで、より多くの推奨Mavenのソリューションですexec:javaモジュラーシステムのための固定(良いニュースは、これがされていることです行わ 我々が話すよう)、使用することになりますexec:exec。この中で説明したように、代わりに問題あなたは両方のVMを指定することができますので、引数を指定します。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=173337&siteId=1