Spring Boot从命令行执行将文件添加到classpath

时间:2017-06-20 20:41:50

标签: java maven spring-boot netbeans spring-boot-maven-plugin

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

我通过@ImportResource注释和@ImportResource(value="${config.xmlfile}")等值属性将spring xml文件传递给我的项目。

点击'运行项目' 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中设置的类路径似乎不起作用。与通过IDE运行时类似,将config.xml文件设置为classpath:config / file.xml或classpath:file.xml都无法找到文件但文件:../ config / file.xml无效。

我希望能够在IDE和命令行中设置类路径,以便我可以使用类路径引用访问Spring中的文件,以简化操作。我不想将它们全部放在src/main/resources中并将它们打包在jar中,因为我需要在打包和部署后编辑它们。

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

2 个答案:

答案 0 :(得分:7)

更新回答:

你可以按照原来的答案进行练习,但我们最近放弃了这个更简单,更清晰的选项,更为标准(&#34; Java&#34;方式)。我们进行了更改,因为我们需要在运行时动态加载在编译时不可用的依赖库(在它们的确切版本中)。在我们的例子中,我们只想从单独的文件夹加载依赖的jar,而不是从可执行的jar加载。我们最终在可执行jar和单独的文件夹中有重复的依赖项,因此我们决定删除可执行jar属性Launcher,而只是从单独的文件夹中加载依赖项。这通常是 NOT 最佳选项,应针对您的用例进行评估。我更喜欢阅读标准的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>

  3. 从主类运行代码,并在类路径中包含相关的jar文件夹。在操作系统上使用标准的类路径表示法,而不是自定义的,尴尬的PropertiesLauncher加载程序路径语法

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

  4. 实际通话的一个例子:     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选项的详情,请参阅herehere。它允许您设置类路径等。 有关此问题的答案,请参阅hereherehere。使用ZIP格式可以使用PropertiesLauncher

    从那里,我能够使用此命令按照我的意图启动应用程序:

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

    另一个重要注意事项:指定-Dloader.path时,请确保使用逗号分隔值,仅使用目录和文件,如here所述。另外,在指定-jar jar之前一定要放置-D args,否则它们将不会被设置。

    如果有人提出任何建议或修改以进一步改进此答案或原始问题以帮助其他用户,请自行通知我或进行修改!

答案 1 :(得分:1)

如果您未将文件放在src/main/resources中,则可以将其放在任何所需的文件夹中,但必须将文件夹设置为资源文件夹。因为classpath始终指向资源文件夹。将文件夹作为资源文件夹后,它将打包到jar中。如果您想编辑资源文件,只需使用7 zip tool打开您的jar - &gt;编辑文件 - &gt;保存 - &gt;它将更新你在jar中的变化。

另一个解决方案是创建一个文件夹,放入你想编辑的所有文件而不打包,然后每次运行时手动将classpath设置为该文件夹,但是你上面设置的方式不正确,试试{{3}用于设置类路径正确方法的解决方案。

相关问题