从命令行启动应用程序时,如何将 Spring Boot 应用程序 jar 中的文件作为 -D 属性值引用?

Posted

技术标签:

【中文标题】从命令行启动应用程序时,如何将 Spring Boot 应用程序 jar 中的文件作为 -D 属性值引用?【英文标题】:How to refer to a file inside spring boot application jar as a -D property value while starting the app from command line? 【发布时间】:2020-02-17 17:55:13 【问题描述】:

我有一个简单的 Spring Boot 应用程序,需要将 java.security.krb5.conf 属性值设置为自定义 krb5.conf 文件。我已将文件添加到 src/main/resources 文件夹中,并且 maven 将其打包到 jar 中。

要启动应用程序,我运行 java -jar -Djava.security.krb5.conf=<localPath>/krb5.conf my-jar.jar

目前我必须将<localPath> 作为我机器上文件的路径。有没有办法引用 jar 中的文件,这样我就可以在任何机器上运行,而无需先在机器上创建文件文件?

到目前为止我尝试过的事情:

-Djava.security.krb5.conf=classpath:krb5.conf(也是./krb5.conf)。没用 我看到“如何从类路径读取文件”的大多数示例都参考 getClass.getResource(文件名)。所以我尝试做 getClass.getResource (filename).getPath() 以便我可以在主类中启动应用程序时将其设置为 java.security.krb5.conf 系统属性,而不是从命令行传递。但是 getPath 显示的字符串类似于/<diskPath>/my-jar.jar!/BOOT-INF/classes!/krb5.conf,当我尝试读取文件进行测试时,此路径不起作用。 在调用 SprinApplication.run 之前,在 main 方法中即时创建文件副本到正在运行的目录。这就是我现在正在做的事情。
    try(
       InputStream in = new ClassPathResource("krb5.conf").getInputStream();
       OutputStream out = new FileOutputStream( new File("krb5copy.conf"));) 
       IOUtils.copy(in, out);
    
    System.setProperty("java.security.krb5.conf","krb5copy.conf");

如果这个问题有解决方案,我可以看到其他用例,例如将 jar 中包含的 trustore 文件提供为 javax.net.ssl.trustStore 等。

【问题讨论】:

【参考方案1】:

给出 -Djava.security.krb5.conf=classpth:krb5.conf(也是 ./krb5.conf)。 没用

实际上,它不是“classpth”,而是“classpath”。并在其后加上一个斜线。

-Djava.security.krb5.conf=classpath/:krb5.conf 应该可以工作。

【讨论】:

添加问题时输入错误。我最初尝试使用 'classpath:',现在使用 'classpath/:' 正如你所建议的那样。那是行不通的【参考方案2】:

读取krb5.conf 配置文件的代码使用FileInputStream,它需要文件的路径并且不“理解”classpath: 前缀。

下面的想法是在类路径中定位文件并从中获取文件的路径:

ClassPathResource resource = new ClassPathResource("krb5.conf");
try

   String fileSpec = resource.getURL().getFile();
   System.setProperty("java.security.krb5.conf", fileSpec);

catch (IOException e)

   // TODO handle the exception
   e.printStackTrace();

编辑:当打包为 SpringBoot fat JAR 时,尝试使用FileInputStream 读取文件会导致java.io.FileNotFoundException: file:/<path-to-jar/<jar-name>.jar!/BOOT-INF/classes!/krb5.conf (No such file or directory) :-(

【讨论】:

以上是关于从命令行启动应用程序时,如何将 Spring Boot 应用程序 jar 中的文件作为 -D 属性值引用?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot配置文件放在jar外部

Spring Boot配置文件放在jar外部

Spring Boot 在命令行指定主类启动程序

如何通过命令行启动 spring-boot 应用程序?

如何使用STS运行Spring启动应用程序

无法使用命令行参数启动 Spring Boot 应用程序