Eclipse 中的 Runnable jar 文件问题:无法构造应用程序实例

Problem with Runnable jar file in Eclipse: Unable to construct Application instance

尝试从 eclipse 为我的 java 项目生成 运行nable jar 时出现错误。生成文件后,我运行

java-罐子RunnableAct.jar

这会输出很多错误,例如:

Exception in Application constructor
Exception in thread "main" java.lang.RuntimeException: Unable to construct Application instance: class application.Main$Main2
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:907)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication4(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication10(LauncherImpl.java:819)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait4(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null2(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater3(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Caused by: java.lang.IllegalStateException: Location is not set.
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2434)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
    at application.AppController.RedirectTo(AppController.java:142)
    at application.AppController.<init>(AppController.java:131)
    at application.Main$Main2.<init>(Main.java:46)
    ... 10 more

我的主要 class 看起来像:

public class Main {

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

    public static class Main2 extends Application {

        AppController controller = new AppController();

        @Override
        public void start(Stage stage) throws Exception{

            // redirection to main controller class's main method where intro page is called
            Scene scene = new Scene(controller);
            stage.setScene(scene);
            stage.setOnCloseRequest(close -> System.exit(0));
            stage.show();

        }
    }
}

我在这里找到一些建议后创建了上面的主要方法,否则,第一个版本是:

public class Main extends Application {


    public AppController controller = new AppController();


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


    @Override
    public void start(Stage stage) throws Exception{

        // redirection to main controller class's main method where intro page is called
        Scene scene = new Scene(controller);
        stage.setScene(scene);
        stage.setOnCloseRequest(close -> System.exit(0));
        stage.show();

    }
}

调用 AppController class 时,它会调用以下方法:

public AppController() {    
        RedirectTo("/fxml/Intro.fxml");
    }

    public void RedirectTo(String url) {        
        FXMLLoader loader = new FXMLLoader(getClass().getResource(url));        
        loader.setController(this);
        loader.setRoot(this);
        try {
            loader.load();
        } catch (IOException ex) {
        }   

    }

同时打印:

java.lang.RuntimeException: 无法构造 Application 实例 class application.Main$Main2

或使用其他主要方法:

java.lang.RuntimeException: 无法构造 Application 实例 class application.Main

非常感谢您的帮助,谢谢!

堆栈跟踪中的 "Caused By" 子句:

Caused by: java.lang.IllegalStateException: Location is not set.

表示FXMLLoader无法找到FXML文件。

(本质上,这里发生的是,如果资源不在正确的位置,getClass().getResource(url) 将 return 为空。您提供给 FXMLLoader构造函数设置为location;当你尝试加载FXML时,如果location为null,则抛出异常,表明尚未设置位置。)

如果代码在 IDE 中工作正常,但当您从 jar 文件 运行 时发出此异常,则有两个常见的可能原因:

  1. (此处不适用,但包括其他用户。)您使用的资源规范适用于常规文件系统,但不适用于 jar 文件。 jar文件的资源规范必须严格遵循Java资源命名规范;特别是,... 不允许出现在资源名称中。在当前问题的情况下,"/fxml/Intro.fxml" 是一个有效的资源名称。
  2. jar文件中FXML文件没有部署(或部署到错误的路径)。

解决此问题的一个好方法是列出 jar 文件的内容。您可以使用 jar -tf path/to/jar/file.jar 从命令行执行此操作(将路径替换为您的 jar 文件的实际位置)。在你的例子中,/fxml/Intro.fxml 正在 "folder" fxml 中寻找名为 Intro.fxml 的 jar 条目,它应该位于 jar 文件的根目录中。

如果该条目不存在,您需要确保构建配置正确。这取决于您的构建环境,如今大多数人会推荐 Maven 或 Gradle 等构建工具。对于 vanilla Eclipse 构建,您应确保将包含 FXML 文件的文件夹配置为源文件夹:您可以通过右键单击项目、选择 "Properties"、选择 "Java Build Path" 并选择"Source" 在对话框的选项卡中。