我相信这个问题已经在stackoverflow上问过了。我想提到的是,我尝试了与我的问题相关的解决方案。最接近我的问题的是:在JAR中加载属性文件?。
不幸的是,那里描述的解决方案对我不起作用。而且由于这个问题的年代久远,我想再问一次是要走的路。
继续描述我的问题。
因此,当前我正在使用maven设置一个库项目,并为当前Spring AMQP项目创建扩展。
这里的目标是提供一个JAR文件,该文件可以包含在另一个项目中,以支持通过消息代理进行通信的特定方式。
至此,我正在实现配置选项,以允许用户根据自己的喜好配置消息传递客户端。但是,当我测试此功能的功能时,在可执行JAR中使用库时遇到了问题。
在Eclipse工作区中运行它时,一切似乎都可以正常工作。但是,当我尝试从桌面(作为可运行的JAR)运行它时,似乎在任何地方都找不到属性文件。
只是为了快速概述上述工作区/项目,请执行以下操作:
这两个项目的项目结构都反映了Maven的默认结构:
- src/main/java
- java source files
- src/main/resources
- resource files
- src/test/java
- java test files
- src/test/resources
- test resource files
其中,库文件在src / main / resources文件夹中包含default.properties文件,而chatclient项目则是一个custom.properties文件。
一旦构建了可运行的JAR文件,它就会具有以下结构。
- com
- junit
- META-INF
- org
- resources
- default.resources
- custom.resources
我相信资源文件不应位于此处。而是放在META-INF / maven文件夹中。在尝试了类似的东西之后:
但是似乎没有任何作用。我想这与Maven有关,只要对pom.xml进行简单更改就可以解决该问题。遗憾的是,我对Maven项目设置和pom相关主题的知识非常基础(这是我的第一个使用maven的项目)。而且即使我知道应该在该文档上,我也似乎找不到任何文档(可能是由我引起的问题)。
在我忘记提及它之前。我使用以下方式加载属性文件:
Properties props = new Properties();
prop.load(<custom static class>.class.getResourceAsStream(filename));
return props;
我的库的pom.xml看起来也像这样:
-- Artifact stuff --
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
-- Dependency stuff --
使用该库的项目看起来像这样:
-- Artifact stuff --
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.maxxton</groupId>
<artifactId>async-amqp-messaging</artifactId>
<version>0.2</version>
</dependency>
</dependencies>
-- Other stuff --
我希望有人在这个问题上有一些高级,可以帮助找到解决该问题的方法。如果您需要有关项目文件/结构的其他信息,请告诉我。我很乐意与您分享。
为了进行测试,我创建了一个示例项目,该项目试图以与上述场景相同的方式加载属性文件。即使遵循Maven文档(使用META-INF文件夹),我也无法加载属性。
我希望有人可以帮助我解决此问题,因为Maven网站上描述的常规方法似乎对我不起作用。
好吧,我设法解决了部分问题。由于我添加了maven-assembly-plugin的配置(使用deps构建可运行的JAR),因此我能够在JAR文件中获得正确的结构。我添加的是:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<finalName>project</finalName>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>com.test.project.Application</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
然后,当运行clean compile assembly:single时,我设法获得了正确的结构。
JAR root
- com
- META-INF
- MANIFEST.MF
- default.properties
- custom.properties
虽然这解决了部分问题。文件加载仍然导致NullPointerException。
经过漫长的Maven斗争,我设法以自己想要的方式获得了一切。遵循@Deepak和@Joop Eggen的建议,我进行了一些研究,研究如何将所有依赖项放在jar文件夹中,而不是将其解压缩到“超级” jar中。在尝试了很多东西之后,我偶然发现了这个答案。按照指示,似乎可以创建此结构:
- runnable.jar
- lib
- spring-amqp.jar
- spring-core.jar
...
当遵循@Joop Eggen的建议时,我设法以所需的方式加载了该属性。因此,似乎这个问题已得到解答。目前,我仍在寻找如何授予每个答案的方法,因为我无法将赏金分成两部分。我会继续讲下去。
尽管我同时授予了@Joop Eggen赏金和答案,但这并不意味着@Deepak的答案没有贡献。它确实提供了一些有关最佳做法的重要信息,但还不如公认的答案完整。因此,请在此处找到答案时也给他一些荣誉。
有两种获取资源的方法,
/...
)的整个类路径,...
)或绝对(/...
)路径。后者似乎更直接,可以用作:
getClass().getResource("/...");
ClassInJar.class.getResource("/...");
现在getClass()
只能在非静态对象中使用,并且也很危险:实际的类可能是某个子类,而不是在库jar中。
关于您的应用程序的实际结构。我知道一个Maven目录约定:
src/main/java/...
src/main/resources/...
/ ...进入罐子/战争的地方;软件包目录。
重新组装罐子不好。Class-Path: ...
META-INF / MANIFEST.MF中始终存在该条目。最好遵循基本的Maven约定。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句