[英]Executable jar won't find the properties files
我在我的程序中使用此代码加载属性文件:
Properties properties = new Properties();
URL url = new App().getClass().getResource(PROPERTIES_FILE);
properties.load(url.openStream());
代码在 Eclipse 中运行良好。 然后我将程序打包到一个名为 MyProgram.jar 的 JAR 中,并运行它,我在第二行得到一个 NullPointerException。 JAR 不包含属性文件,它们都在同一目录中。 我正在使用 Maven 创建 JAR。 我该如何解决这个问题?
更新:我不想将属性文件添加到 JAR,因为它将在部署时创建。
BalusC 是对的,您需要指示 Maven 在Class-Path:
条目中使用当前目录 ( .
) 生成一个MANIFEST.MF
。
假设您仍在使用 Maven Assembly Plugin 和jar-with-dependencies
描述符来构建您的可执行 JAR,您可以使用以下命令告诉插件这样做:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.stackoverflow.App</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path> <!-- HERE IS THE IMPORTANT BIT -->
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- append to the packaging phase. -->
<goals>
<goal>single</goal> <!-- goals == mojos -->
</goals>
</execution>
</executions>
</plugin>
有两种解决方法:
不要将 JAR 用作可执行文件 JAR,而是用作库。
java -cp .;filename.jar com.example.YourClassWithMain
获取 JAR 文件的根位置并从中获取属性文件。
URL root = getClass().getProtectionDomain().getCodeSource().getLocation(); URL propertiesFile = new URL(root, "filename.properties"); Properties properties = new Properties(); properties.load(propertiesFile.openStream());
两者都不是推荐的方法! 推荐的方法是在 JAR 的/META-INF/MANIFEST.MF
文件中包含以下条目:
Class-Path: .
然后它将以通常的方式作为类路径资源可用。 您真的必须以某种方式指示 Maven 生成这样的MANIFEST.MF
文件。
编辑:这是为了回应您的评论:
您需要确保属性文件位于类路径上,并且具有启动 jar 文件的 java 调用的正确根。 如果你的路径是
东西/东西.properties
并且运行时位置是
/opt/myapp/etc/stuff/things.properties
并且jar文件在
/opt/myapp/bin/myjar
那么你需要启动
/path/to/java -cp "/opt/myapp/etc:/opt/myapp/bin/myjar.jar" my.pkg.KavaMain
在开发环境中使用这种配置可能会令人厌烦,幸运的是, maven exec 插件可以为您提供正确的启动场景。
原答案:
您想阅读有关Maven 资源插件的信息。
基本上你想添加这样的东西:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*properties</include>
</includes>
</resource>
</resources>
</configuration>
<plugin>
到您的 pom.xml 假设您的属性文件与您的 java 源代码在一起——实际上它应该在 src/main/resources 中。
我有一个类似的问题,这个线程是一个很大的帮助! 仅供参考,我修改了我的 Ant 构建文件以进行清单制作,然后在 JAR 处理我的服务器端代码时指定该清单:
<!-- Create a custom MANIFEST.MF file, setting the classpath. -->
<delete file="${project.base.dir}/resources/MANIFEST.MF" failonerror="false"/>
<manifest file="${project.base.dir}/resources/MANIFEST.MF">
<attribute name="Class-Path" value="." />
</manifest>
<!-- JAR the server-side code, using the custom manifest from above. -->
<jar destfile="services/${name}.aar" manifest="${project.base.dir}/resources/MANIFEST.MF">
[....]
感谢所有这些代码为我解决了这个 url 获取我们可运行的 jar 位置如此容易我必须读取我的属性文件所以将您的属性文件放在您的可运行 jar 文件位置
URL root = getClass().getProtectionDomain().getCodeSource().getLocation();
URL propertiesFile = new URL(root, "filename.properties");
Properties properties = new Properties();
properties.load(propertiesFile.openStream());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.