Java 可执行jar-won';找不到属性文件
我在程序中使用以下代码加载属性文件:Java 可执行jar-won';找不到属性文件,java,eclipse,jar,maven,Java,Eclipse,Jar,Maven,我在程序中使用以下代码加载属性文件: Properties properties = new Properties(); URL url = new App().getClass().getResource(PROPERTIES_FILE); properties.load(url.openStream()); 代码在Eclipse中运行良好。然后我将程序打包到一个名为MyProgram.JAR的JAR中,并运行它,在第二行得到一个NullPointerException。JAR不包含属性文件
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中,因为它将在部署时创建。编辑:这是对您的评论的回应: 您需要确保属性文件位于类路径上,具有启动jar文件的java调用的正确根。如果你的道路是 东西 并且运行时位置是 /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 在开发环境中使用这种配置可能会让人厌烦,幸运的是,有一种方法可以让您获得正确的启动场景 原始答复: 你想了解一下 基本上,您希望添加如下内容:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*properties</include>
</includes>
</resource>
</resources>
</configuration>
<plugin>
maven jar插件
src/main/java
**/*性质
假设您的propertis文件与java源代码在一起,那么它应该位于src/main/resources中。有两种解决方法:
java -cp .;filename.jar com.example.YourClassWithMain
URL root = getClass().getProtectionDomain().getCodeSource().getLocation();
URL propertiesFile = new URL(root, "filename.properties");
Properties properties = new Properties();
properties.load(propertiesFile.openStream());
/META-INF/MANIFEST.MF
文件中包含以下条目:
Class-Path: .
然后,它将以通常的方式作为类路径资源提供。您必须以某种方式指示Maven生成这样的
MANIFEST.MF
文件。BalusC是对的,您需要指示Maven在类路径:
条目中使用当前目录(
)生成MANIFEST.MF
)
假设您仍在使用Maven Assembly插件和带有依赖项的jar
描述符来构建可执行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>
maven汇编插件
2.2
带有依赖项的jar
com.stackoverflow.App
.
组装
包裹
单身
我也遇到了类似的问题,这个帖子帮了大忙!仅供参考,我修改了我的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=新URL(根,“filename.properties”);
属性=新属性();
load(propertiesFile.openStream());
旁注:既然您只是将其用作流,那么您使用getResource()
而不是getResourceAsStream()
有什么原因吗?没有,我没有任何特殊原因。您如何运行jar?如果通过java-jar,你能试试java-cp./MyProgram.jar,看看它是否有效吗?@Tomer:这是一种解决方法,不是解决方案。尽管如此,它还是不起作用。您没有在类路径中获取JAR的根文件夹。@Hai:为什么要删除maven
标记?你评论了我的回答“你知道如何通过maven添加它吗?”。所以你使用maven,因为它做的事情不同,最终的答案取决于这一点。我不知道怎么做,所以我删除了答案并重新标记了问题,以提高出席率。Maven是唯一能够可靠地回答这个问题的人。谢谢,但我不想将属性文件添加到JAR中。它将在部署时更改。根据您的编辑:使用-jar
参数时忽略-cp
参数。它必须进入MANIFEST.MF
文件:)@BalusC righto,修正了。如果MANIFEST.MF可以在运行时移动,则无法进入该MANIFEST.MF。逗号filename.jar。也许这就是它不起作用的原因。感谢您的帮助。避免使用类路径有一个原因,即如果在读取之间内容发生变化。资源加载器缓存第一个内容如果您没有使用maven assembly插件,请告诉我,我会更新我的答案。使用执行
部分,我不必单独运行mvn assembly:assembly
,对吗?顺便说一句,谢谢你回答我关于Maven的所有问题。@HaiMinhNguyen:事实上,上述执行
在包
阶段绑定了单个
目标。因此,运行mvn包
确实会创建程序集。哦,不客气。是的,这是您应该采取的方法,Hai Minh Nguyen。您好,我尝试使用上述方法创建一个具有依赖项的jar,它可以加载位于同一目录中的属性文件,但不起作用。我使用“java-jarmyjar.jar”运行我的jar。我尝试使用Class.getResource()Class.ClassLoader.getResource()和Class.getResource()检索属性文件,在文件名中使用或不使用前导斜杠,但这些都不起作用。如果我打印java.class.path的内容,我只会得到我的jar文件(不是“.”