简体   繁体   English

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

[英]Spring Boot add files to classpath from command line execution

I am using Netbeans 8.2 to develop Spring applications. 我正在使用Netbeans 8.2来开发Spring应用程序。 This specific app with which I am having trouble is a Spring Boot 1.5.3 app. 我遇到问题的这个特定应用程序是一个Spring Boot 1.5.3应用程序。 I have a spring xml file and an application.properties that I keep in /config under the root project directory. 我有一个spring xml文件和一个application.properties,我保存在根项目目录下的/ config中。

I am passing the spring xml file to my project via the @ImportResource annotation and a value property like @ImportResource(value="${config.xmlfile}") . 我通过@ImportResource注释和一个值属性(如@ImportResource(value="${config.xmlfile}")将spring xml文件传递给我的项目。

When I click the 'Run Project' button in Netbeans my Spring app starts up and it correctly finds the application.properties file in my /config folder. 当我单击Netbeans中的“运行项目”按钮时,我的Spring应用程序启动并正确找到我的/ config文件夹中的application.properties文件。 However, any classpath references to other files in that folder are lost. 但是,对该文件夹中其他文件的任何类路径引用都将丢失。 For example, setting the config.xml file to classpath:config/file.xml or classpath:file.xml both fail to find the file but file:config/file.xml works. 例如,将config.xml文件设置为classpath:config/file.xmlclasspath:file.xml都无法找到文件,但file:config/file.xml无效。

Similarly, when running from the command line I have the following as my structure: 同样,从命令行运行时,我的结构如下:

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

I am using the spring-boot-maven-plugin to make the jar as follows: 我正在使用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>

and my app-run.sh script executes the following: 我的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

where /bin/java represents the location where I have java installed. 其中/ bin / java表示我安装java的位置。 The classpath set in -cp does not seem to be working here. 在-cp中设置的类路径似乎不起作用。 Similarly to when running through the IDE, setting the config.xml file to classpath:config/file.xml or classpath:file.xml both fail to find the file but file:../config/file.xml works. 与通过IDE运行时类似,将config.xml文件设置为classpath:config / file.xml或classpath:file.xml都无法找到文件,但文件:../ config / file.xml有效。

I would like to be able to set the classpath in both the IDE and from command line so that I can access files in Spring using classpath reference to make things easier. 我希望能够在IDE和命令行中设置类路径,以便我可以使用类路径引用访问Spring中的文件,以简化操作。 I do NOT want to put them all in src/main/resources and have them be packaged in the jar, as I need to edit these after packaging and deployment. 我不想将它们全部放在src/main/resources并将它们打包在jar中,因为我需要在打包和部署后编辑它们。

Does anybody have any ideas or helpful hints? 有没有人有任何想法或有用的提示? Thanks in advance! 提前致谢!

Updated answer: 更新的答案:

You can follow the practice in my original answer, but we recently dropped this for a simpler and cleaner option that is more standard (the "Java" way). 您可以按照我原来的答案进行练习,但我们最近放弃了这个更简单,更清晰的选项,更标准(“Java”方式)。 We made the change because we needed to dynamically load dependent libraries at runtime that were not available at compile time (in their exact version). 我们进行了更改,因为我们需要在运行时动态加载在编译时不可用的依赖库(在它们的确切版本中)。 In our case we wanted to load dependent jars only from separate folder(s) and not from an executable jar. 在我们的例子中,我们只想从单独的文件夹加载依赖的jar,而不是从可执行的jar加载。 We ended up having duplicate dependencies in the executable jars and in separate folder(s), so we decided to drop the executable jar Properties Launcher and instead only load dependencies from separate folders. 我们最终在可执行jar和单独的文件夹中有重复的依赖项,因此我们决定删除可执行jar属性Launcher,而只是从单独的文件夹中加载依赖项。 This is often NOT the best option and should be evaluated for your use case. 这通常不是最佳选择,应根据您的使用情况进行评估。 I prefer reading the standard Java classpath. 我更喜欢阅读标准的Java类路径。

To run a Spring Boot app without an executable jar, we used Maven Assembly to put the dependent jars in a /libs directory and dropped the spring-boot-maven-plugin. 要运行没有可执行jar的Spring Boot应用程序,我们使用Maven Assembly将依赖jar放在/ libs目录中并删除spring-boot-maven-plugin。 The steps and some code for this are below: 步骤和一些代码如下:

  1. Remove the spring-boot-maven-plugin that creates the executable jar in ZIP format 删除以ZIP格式创建可执行jar的spring-boot-maven-plugin
  2. Add the following to your assembly XML 将以下内容添加到程序集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. Run your code from the main class and include the dependent jar folder(s) on the classpath. 从主类运行代码,并在类路径中包含相关的jar文件夹。 Use the standard classpath notation on your OS and not the custom, awkward PropertiesLauncher loader path syntax 在操作系统上使用标准的类路径表示法,而不是自定义的,笨拙的PropertiesLauncher加载程序路径语法

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

An example of an actual call: java -cp $CLASSPATH:./lib/*:./cfg/*:my-app.jar Application.class 实际调用的示例: java -cp $CLASSPATH:./lib/*:./cfg/*:my-app.jar Application.class

In this way you execute the Spring Boot app via standard java execution call, no custom Spring loading syntax. 通过这种方式,您可以通过标准的Java执行调用执行Spring Boot应用程序,而无需自定义Spring加载语法。 You just need to ensure that all of your dependencies are available on the classpath at runtime. 您只需确保在运行时类路径上的所有依赖项都可用。 We found this much easier to maintain and made this the standard for all of our apps. 我们发现这更容易维护,并使其成为我们所有应用程序的标准。

Original answer: 原始答案:

After some researching, and thanks to @TuyenNguyen's helpful answer I was able to get the following working: 经过一番研究,感谢@ TuyenNguyen的有用回答,我得到了以下工作:

I added the following to my spring-boot-maven-plugin so that when I run from the command line it uses the PropertiesLauncher instead of the JarLauncher : 我在spring-boot-maven-plugin中添加了以下内容,以便当我从命令行运行时,它使用PropertiesLauncher而不是JarLauncher

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

See here and here for more about the PropertiesLauncher options. 有关PropertiesLauncher选项的更多信息,请参见此处此处 It allows you to set the classpath, among other things. 它允许您设置类路径等。 See here , here , and here for where I found the answer to this problem. 看到这里这里这里我找到了这个问题的答案。 Using format ZIP makes the PropertiesLauncher be used. 使用ZIP格式可以使用PropertiesLauncher

From there, I was able to use this command to launch the application as I intended: 从那里,我能够使用此命令按照我的意图启动应用程序:

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

Another important note: when specifying the -Dloader.path make sure to use comma-separated values and only directories and files, as described here . 另一个重要的注意事项:指定当-Dloader.path确保使用逗号分隔值,只有目录和文件,描述在这里 Also, be sure to put the -D args before you specify -jar jar or they will not be set. 另外,在指定-jar jar之前一定要放置-D args,否则它们将不会被设置。

If anyone has any suggestions or edits to further improve this answer or the original question in order to help additional users, please let me know or make the edits yourself! 如果有人提出任何建议或编辑以进一步改进此答案或原始问题以帮助其他用户,请告诉我或自行编辑!

If you don't put your files in src/main/resources then you can put it inside any folder that you want, BUT you must set your folder as a resources folder. 如果你没有把你的文件放在src/main/resources那么你可以将它放在你想要的任何文件夹中,但是你必须将你的文件夹设置为资源文件夹。 Because classpath is always point to resources folder. 因为classpath总是指向资源文件夹。 Once you make your folder as a resource folder, it will be packaged into the jar. 将文件夹作为资源文件夹后,它将打包到jar中。 If you want to edit your resource file, just using 7 zip tool to open your jar -> edit files -> save -> it will update your change in the jar. 如果你想编辑你的资源文件,只需使用7个zip工具打开你的jar - >编辑文件 - >保存 - >它会更新你在jar中的变化。

Another solution is create a folder, put all files you want to edit and not packaged in that, then set classpath manually to that folder every time you run, but the way you set above is not correct, try this solution for set classpath correct way. 另一种解决方案是创建一个文件夹,将所有要编辑的文件放入其中,然后将其打包,然后每次运行时手动将classpath设置为该文件夹,但是上面设置的方式不正确,请尝试使用解决方案设置类路径的正确方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM