与Jlink打包的应用程序找不到属性文件

时间:2018-12-20 14:29:18

标签: java properties-file jlink

我正在将一个应用程序从Oracle Java 8迁移到openJDK11 + openJFX11。 在Java 8版本中,我使用以下代码加载了属性文件(CryoStats是包含代码的类):

try {
    jarLocation = CryoStats.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
    confLocation = jarLocation.substring(0, jarLocation.lastIndexOf("/")) + "/config/";
try (FileInputStream input = new FileInputStream(confLocation + "CryoStats.properties");) {
            properties.load(input);
            HORUS_HOST = properties.getProperty("HORUS_HOST");
            HORUS_USERNAME = properties.getProperty("HORUS_USERNAME");
            HORUS_PASSWORD = properties.getProperty("HORUS_PASSWORD");
            CONNECTION_TIMEOUT = Integer.parseInt(properties.getProperty("CONNECTION_TIMEOUT"));
            SOCKET_TIMEOUT = Integer.parseInt(properties.getProperty("SOCKET_TIMEOUT"));
            System.out.println("CryoStats.properties loaded.");
        } catch (FileNotFoundException ex) {
            System.out.println("Error loading properties file");
            System.out.println(ex.getMessage());
        } catch (IOException ex) {
            System.out.println("Error loading properties file");
            System.out.println(ex.getMessage());
        }
} catch (URISyntaxException ex) {
        System.out.println(ex.getMessage());
    }

在Netbeans构建配置中,我有一个任务将“ config”文件夹复制到“ dist”文件夹,因此包括:我的jar文件,“ lib”文件夹,“ config”文件夹。 该代码在Netbeans中和运行时均有效。

我需要让用户可以编辑属性文件,因此我需要将其保存在jar之外。

我现在已经将代码迁移到Eclipse项目,并且针对openJDK11和openJFX11进行编译。如果我在Eclipse中运行项目,它将加载属性文件。但是,如果我使用jlink创建模块的运行时映像,它将找不到属性文件,并且jarLocation的值为:

jarLocation = /cryostats

据我所知,发生这种情况是因为在完全模块化的Java应用程序中没有类路径的概念,因此,我使用了一种变通方法

confLocation = System.getProperty("user.dir") + "/config/";

,在执行jlink之后,我已将“ config”文件夹手动复制到“ bin”文件夹。当我启动该应用程序时,此方法有效,但在Eclipse中无法使用,这是一个粗陋的解决方案。

是否有一种方法可以使用户在jlink生成的运行时映像中同时访问属性文件,而同时Eclipse可以访问该文件?

1 个答案:

答案 0 :(得分:0)

假设类来自.jar文件(该文件是平台文件系统中的物理文件),这从来都是不正确的。 (也是getCodeSource() can return null)。

Windows,OS X和Linux都有用​​于存储用户配置文件的标准位置。参见Find place for dedicated application folder。为了简化来自该链接的信息:

  • Windows:System.getProperty("user.home") + "\\AppData\\Roaming\\CryoStats"
  • OS X:System.getProperty("user.home") + "/Library/Application Support/CryoStats"
  • Linux:System.getProperty("user.home") + "/.config/CryoStats"

(不要直接使用这些路径;实际上比这更复杂。请阅读链接以获取完整说明。)

从不使用System.getProperty("user.dir")(这是当前目录),它可以是任何东西,包括系统的根目录。另一方面,user.home系统属性指向一个稳定的位置,即用户的主目录。

我对应用程序配置所做的是:我将 default 配置包含在程序内部,作为只读资源。程序退出时,它将可能由用户修改的配置保存到系统的标准配置位置。