Класс SwingNode в openjfx вызывает проблемы - PullRequest
0 голосов
/ 26 апреля 2019

Я хотел перенести приложение JavaFX на JDK 11 & OpenJFX и заметил, что SwingNode вызывает проблемы. Я решил создать новый проект и посмотреть, что происходит. Интересно, что когда я перехожу на JDK 8, все в порядке. В более новой версии появляются ошибки. Я не знаю, с чем это связано.

package sample;

import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();

        // problem
        final SwingNode swingNode = new SwingNode();
    }


    public static void main(String[] args) {
        launch(args);
    }
}
Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.IllegalAccessError: superclass access check failed: class com.sun.javafx.embed.swing.SwingNodeHelper (in unnamed module @0x412b4fb) cannot access class com.sun.javafx.scene.NodeHelper (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.scene to unnamed module @0x412b4fb
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:802)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:700)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at javafx.embed.swing.SwingNode.<clinit>(SwingNode.java:143)
    at sample.Main.start(Main.java:20)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    ... 1 more
Exception running application sample.Main

Опции VM: --module-path $ {PATH_TO_FX} --add-modules = javafx.controls, javafx.fxml

1 Ответ

1 голос
/ 27 апреля 2019

Важной частью этой трассировки стека является последняя Caused by:, которая:

Caused by: java.lang.IllegalAccessError: superclass access check failed: class com.sun.javafx.embed.swing.SwingNodeHelper (in unnamed module @0x412b4fb) cannot access class com.sun.javafx.scene.NodeHelper (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.scene to unnamed module @0x412b4fb

Это говорит о том, что в «неназванном модуле» есть класс с именем SwingNodeHelper, который расширяет класс с именем NodeHelper, присутствующий в модуле javafx.graphics. Однако модуль javafx.graphics не экспортирует этот суперкласс (точнее, пакет, к которому принадлежит суперкласс) в «неназванный модуль». Это приводит к IllegalAccessError при попытке загрузить класс SwingNodeHelper.

«Безымянный модуль» - это специальный Module (по одному на ClassLoader), который содержит классы на classpath . Классы SwingNode и связанные SwingNodeHelper являются частью модуля javafx.swing. Эти знания в сочетании с данной ошибкой говорят нам, что модуль javafx.swing используется из classpath , когда его необходимо использовать из modulepath . Исправление, как сказал Хосе Переда в комментарии , состоит в том, чтобы включить модуль javafx.swing в вашу команду --add-modules.

Причина, по которой это работает, заключается в том, что javafx.graphics modules делает экспорт необходимого пакета в модуль javafx.swing - но все должно быть в modulepath , чтобы работать должным образом.

Когда или если вы делаете свой код модульным, вы можете отказаться от команды --add-modules и просто перечислить соответствующие директивы requires в своем файле module-info.java.

module <your-module-name> {
    requires javafx.swing;
    // other directives...
}

Похожие вопросы:

...