java Spring Boot 从命令行执行将文件添加到类路径
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44662626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Boot add files to classpath from command line execution
提问by wrslatz
I am using Netbeans 8.2 to develop Spring applications. This specific app with which I am having trouble is a Spring Boot 1.5.3 app. I have a spring xml file and an application.properties that I keep in /config under the root project directory.
我正在使用 Netbeans 8.2 来开发 Spring 应用程序。我遇到问题的这个特定应用程序是 Spring Boot 1.5.3 应用程序。我有一个 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}")
.
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. 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.
当我单击 Netbeans 中的“运行项目”按钮时,我的 Spring 应用程序启动并正确地在我的 /config 文件夹中找到了 application.properties 文件。但是,对该文件夹中其他文件的任何类路径引用都将丢失。例如,将 config.xml 文件设置为classpath:config/file.xml
或classpath: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
制作罐子,如下所示:
<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. The classpath set in -cp does not seem to be working here. 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.
其中 /bin/java 代表我安装 java 的位置。-cp 中设置的类路径在这里似乎不起作用。与通过 IDE 运行时类似,将 config.xml 文件设置为 classpath:config/file.xml 或 classpath:file.xml 都无法找到该文件,但 file:../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. 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.
我希望能够在 IDE 和命令行中设置类路径,以便我可以使用类路径引用访问 Spring 中的文件,从而使事情变得更容易。我不想将它们全部放入src/main/resources
并将它们打包在 jar 中,因为我需要在打包和部署后编辑它们。
Does anybody have any ideas or helpful hints? Thanks in advance!
有人有任何想法或有用的提示吗?提前致谢!
回答by wrslatz
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). 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. 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. This is often NOTthe best option and should be evaluated for your use case. I prefer reading the standard Java classpath.
您可以按照我的原始答案中的做法进行操作,但我们最近放弃了这一点,以实现更标准的更简单、更简洁的选项(“Java”方式)。我们进行了更改,因为我们需要在运行时动态加载在编译时不可用的依赖库(在它们的确切版本中)。在我们的例子中,我们只想从单独的文件夹而不是从可执行的 jar 加载依赖的 jar。我们最终在可执行 jars 和单独的文件夹中存在重复的依赖项,因此我们决定删除可执行 jar 属性启动器,而只从单独的文件夹加载依赖项。这通常不是最佳选择,应针对您的用例进行评估。我更喜欢阅读标准的 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. The steps and some code for this are below:
为了在没有可执行 jar 的情况下运行 Spring Boot 应用程序,我们使用 Maven Assembly 将依赖的 jar 放在 /libs 目录中,并删除了 spring-boot-maven-plugin。步骤和一些代码如下:
- Remove the spring-boot-maven-plugin that creates the executable jar in ZIP format
Add the following to your assembly 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>
Run your code from the main class and include the dependent jar folder(s) on the classpath. Use the standard classpath notation on your OS and not the custom, awkward PropertiesLauncher loader path syntax
java -cp <standard-classpath> <main-class>
- 删除以 ZIP 格式创建可执行 jar 的 spring-boot-maven-plugin
将以下内容添加到您的程序集 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>
从主类运行您的代码,并在类路径中包含依赖的 jar 文件夹。在您的操作系统上使用标准的类路径表示法,而不是自定义的、笨拙的 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. 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.
通过这种方式,您可以通过标准的 java 执行调用来执行 Spring Boot 应用程序,无需自定义 Spring 加载语法。您只需要确保所有依赖项在运行时都在类路径上可用。我们发现这更易于维护,并使其成为我们所有应用程序的标准。
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 hereand herefor more about the PropertiesLauncher
options. It allows you to set the classpath, among other things.
See here, here, and herefor where I found the answer to this problem. Using format ZIP makes the PropertiesLauncher
be used.
有关选项的更多信息,请参见此处和此处PropertiesLauncher
。它允许您设置类路径等。请参阅此处、此处和此处了解我在哪里找到此问题的答案。使用格式 ZIPPropertiesLauncher
可以使用。
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. Also, be sure to put the -D args before you specify -jar jar or they will not be set.
另一个重要的注意事项:指定时-Dloader.path
务必以致用逗号分隔值,只有目录和文件,描述在这里。另外,请确保在指定 -jar jar 之前放置 -D 参数,否则它们将不会被设置。
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!
如果有人有任何建议或编辑以进一步改进此答案或原始问题以帮助其他用户,请告诉我或自己进行编辑!
回答by TuyenNTA
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. Because classpath
is always point to resources folder. Once you make your folder as a resource folder, it will be packaged into the jar. If you want to edit your resource file, just using 7 zip toolto open your jar -> edit files -> save -> it will update your change in the jar.
如果你不把文件src/main/resources
放进去,那么你可以把它放在任何你想要的文件夹中,但你必须将你的文件夹设置为资源文件夹。因为classpath
总是指向资源文件夹。将文件夹设为资源文件夹后,它将被打包到 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 thissolution for set classpath correct way.
另一种解决方案是创建一个文件夹,将所有要编辑的文件而不是打包的文件放在那里,然后每次运行时手动将classpath设置到该文件夹,但是你上面设置的方式不正确,试试这个解决方案设置类路径正确的方式.