一尘不染

Spring Boot从命令行执行将文件添加到类路径

spring-boot

我正在使用Netbeans 8.2开发Spring应用程序。我遇到麻烦的这个特定应用是Spring Boot 1.5.3应用。我有一个Spring
xml文件和一个application.properties,该文件保存在根项目目录下的/ config中。

我正在通过@ImportResource注释和value属性(例如)将spring
xml文件传递到我的项目@ImportResource(value="${config.xmlfile}")

当我单击Netbeans中的“运行项目”按钮时,我的Spring应用程序启动,并且可以正确地在我的/
config文件夹中找到application.properties文件。但是,对该文件夹中其他文件的所有类路径引用都会丢失。例如,将config.xml文件设置为classpath:config/file.xmlclasspath:file.xml都不能找到该文件但file:config/file.xml可以。

同样,从命令行运行时,我的结构如下:

app/
|-- bin
|   `-- app-run.sh
|-- config
|   |-- application.properties
|   |-- log4j2.xml
|   |-- file.xml
`-- app-exec.jar

我使用spring-boot-maven-plugin来制作jar,如下所示:

<plugin>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-maven-plugin</artifactId>
     <version>${spring.boot.version}</version>
     <executions>
          <execution>
               <goals>
                    <goal>repackage</goal>
               </goals>
               <configuration>
                    <classifier>exec</classifier>
               </configuration>
          </execution>
     </executions>
</plugin>

我的app-run.sh脚本执行以下操作:

exec /bin/java -cp :.:../config/*:../app-exec.jar 
-Dlogging.config=../config/log4j2.xml 
-Dspring.config.location=../config/application.properties 
-jar ../app-exec.jar

/ bin /
java代表我安装Java的位置。在-cp中设置的classpath在这里似乎不起作用。与通过IDE运行时类似,将config.xml文件设置为classpath:config
/ file.xml或classpath:file.xml都无法找到该文件,但是file:../ config / file.xml可以工作。

我希望能够在IDE和命令行中设置类路径,以便我可以使用类路径引用访问Spring中的文件,从而使事情变得更容易。我不想将它们全部放入src/main/resources并打包在jar中,因为我需要在打包和部署后对其进行编辑。

有人有任何想法或有用的提示吗?提前致谢!


阅读 426

收藏
2020-05-30

共1个答案

一尘不染

更新的答案:

您可以按照我的原始答案中的方法进行操作,但是最近我们放弃了此方法,以便使用更简单,更干净的选项,该选项更加标准(“
Java”方式)。之所以进行更改,是因为我们需要在运行时动态加载依赖库,而这些库在编译时不可用(确切版本)。在我们的案例中,我们只想从单独的文件夹而不是从可执行jar加载依赖的jar。我们最终在可执行jar和单独的文件夹中有重复的依赖项,因此我们决定删除可执行jar的Properties
Launcher,而是仅从单独的文件夹加载依赖项。这通常 不是 最佳选择,应该针对您的用例进行评估。我更喜欢阅读标准的Java类路径。

为了在没有可执行jar的情况下运行Spring Boot应用程序,我们使用Maven Assembly将相关的jar放在/
libs目录中,并删除了spring-boot-maven-plugin。步骤和一些代码如下:

  1. 删除以ZIP格式创建可执行jar的spring-boot-maven-plugin
  2. 将以下内容添加到您的程序集XML中

<dependencySets> <dependencySet> <outputDirectory>where you want the libs to go</outputDirectory> <useProjectArtifact>whether you want to include the project artifact here</useProjectArtifact> </dependencySet> </dependencySets>

  1. 从主类运行您的代码,并在类路径上包含相关的jar文件夹。在操作系统上使用标准的类路径符号,而不要使用自定义的,笨拙的PropertiesLauncher加载程序路径语法

java -cp <standard-classpath> <main-class>

实际通话的示例: java -cp $CLASSPATH:./lib/*:./cfg/*:my-app.jar Application.class

这样,您就可以通过标准的Java执行调用来执行Spring
Boot应用程序,而无需自定义Spring加载语法。您只需要确保在运行时在类路径上可以使用所有依赖项。我们发现这更容易维护,并使其成为我们所有应用程序的标准。

原始答案:

经过一些研究,并感谢@TuyenNguyen的有用回答,我得以完成以下工作:

我在spring-boot-maven-
plugin中添加了以下内容,以便从命令行运行时使用PropertiesLauncher而不是JarLauncher

<configuration>
     <mainClass>${mainClass}</mainClass>
     <layout>ZIP</layout> //THIS IS THE IMPORTANT PART
</configuration>

有关选项的更多信息,请参见此处此处PropertiesLauncher。它使您可以设置类路径。见这里这里这里的,我找到了答案,这个问题。使用ZIP格式PropertiesLauncher可以使用。

从那里,我能够使用此命令按预期启动应用程序:

java -Dloader.path=../config,../ -Dloader.config.location=classpath:application.properties -jar ../app-exec.jar

另一个重要的注意事项:指定时-Dloader.path务必以致用逗号分隔值,只有目录和文件,描述在这里。另外,请确保在指定-jar jar之前放置-D参数,否则将不会设置它们。

如果有人有任何建议或修改内容以进一步改善此答案或原始问题,以帮助其他用户,请让我知道或进行修改!

2020-05-30