首页 > 解决方案 > Eclipse 中可运行 jar 文件的问题:无法构造应用程序实例

问题描述

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

java -jar 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$launchApplication$154(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$launchApplication1$160(LauncherImpl.java:819)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(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

我的主要课程如下所示:

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 类时,它会调用以下方法:

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.Main$Main2

或使用其他主要方法:

java.lang.RuntimeException:无法构造应用程序实例类application.Main

我真的很感激你的帮助,谢谢!

标签: javajavafxexecutable-jar

解决方案


堆栈跟踪中的“Caused By”子句:

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

表示FXMLLoader无法找到 FXML 文件。

(本质上,这里发生的情况是,如果资源不在正确的位置,getClass().getResource(url)将返回 null。URL您提供给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正在寻找一个Intro.fxml在 "folder" 中调用的 jar 条目,该条目fxml应该位于 jar 文件的根目录中。

如果该条目不存在,则需要确保正确配置了构建。这取决于您的构建环境,现在大多数人会推荐构建工具,例如 Maven 或 Gradle。对于普通的 Eclipse 构建,您应该确保将包含 FXML 文件的文件夹配置为源文件夹:您可以通过右键单击项目、选择“属性”、选择“Java 构建路径”并选择“源”来执行此操作" 在对话框的选项卡中。


推荐阅读