有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我正在将一个应用程序从OracleJava8迁移到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) 个答案

  1. # 1 楼答案

    假设类来自一个特定的领域从来都是不正确的。jar文件,它是平台文件系统中的物理文件。(还有,getCodeSource() can return null

    Windows、OS X和Linux都有存储用户配置文件的标准位置。见Find place for dedicated application folder。要过度简化该链接中的信息,请执行以下操作:

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

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

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

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