为什么相对路径在JAR文件中的JAVA中不起作用?

时间:2017-08-18 21:09:45

标签: java javafx

我有一个简单的JavaFX项目。它包括:

  • 的src /应用程序/ Main.java
  • 的src /应用/控制器/ MainController.java
  • 的src /应用/控制器/ SecondaryWindowController.java
  • 的src /应用程序/视图/ Main.fxml
  • 的src /应用程序/视图/ SecondaryWindow.fxml

控制器 MainController.java 有方法(按键处理程序):

public void openWindow(ActionEvent event) {
    Pane root = null;
    try {
        System.out.println("URL: " + getClass().getResource("../view/SecondaryWindow.fxml"));
        FXMLLoader loader = new FXMLLoader(getClass().getResource("../view/SecondaryWindow.fxml") );
        root = loader.load();
    }
    catch(Exception e) {
        e.getMessage();
        e.printStackTrace();
    }
    if (root != null) {
        Scene scene = new Scene(root,400,100);
        Stage secStage = new Stage();
        secStage.setTitle("Secondary Window");
        secStage.setScene(scene);
        secStage.show();
    }
}

代码 getClass()。getResource(“../ view / SecondaryWindow.fxml”)如果我从编译文件运行项目,则返回右侧URL。但是如果我从JAR文件运行项目,它会返回 null

我使用以下方法编译文件:

javac -d bin src\app\Main.java
javac -d bin src\app\controller\*.java
XCOPY src\app\view\*.fxml bin\app\view /s /e /d /y

使用以下命令运行编译文件:

java -classpath bin app.Main

目录 bin 具有类似的文件结构:

  • 仓/应用/ Main.class
  • 仓/应用/控制器/ MainController.class
  • 仓/应用/控制器/ SecondaryWindowController.class
  • 仓/应用/视图/ Main.fxml
  • 仓/应用/视图/ SecondaryWindow.fxml

我使用:

创建JAR文件
jar cvfm SimpleFXMLApp.jar manifest.mf -C bin app

MANIFEST.MF在

Manifest-Version: 1.0
Created-By: Denys Selivanov
Main-Class: app.Main

为什么相对路径在 JAR-file getClass()中无效.getResource(“../ view / SecondaryWindow.fxml”)返回 null ? 如何修复?

问题的解决之一是将控制器和视图文件保存在一个目录中并使用相对路径“SecondaryWindows.fxml”,但我想保留项目的结构文件。

您可以下载我的项目here。此链接将在30天内访问。

1 个答案:

答案 0 :(得分:2)

我看到投票结束表示它与this Q&A重复,但我不认为它解释了..的细节,所以你走了:

..适用于文件系统上的资源,因为..是文件系统上的实际条目,指向父目录。但是在罐子里面并不存在,所以它不会指向"父包装"当你的课程&资源包装在一个罐子里。

解决方案:如果您可以接受从控制器类到Main类的依赖关系,则可以改为:

Main.class.getResource("view/SecondaryWindow.fxml")

在任何情况下,您都需要在包层次结构中引用一个足够高的类,或者在您的情况下使用根包(getClass().getClassLoader().getResource("app/view/SecondaryWindow.fxml")的绝对路径)。