Maven和Eclipse:在Maven库项目中加载默认属性,并在可运行的Jar中使用它

罗宾·赫曼斯:

我相信这个问题已经在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文件夹中。在尝试了类似的东西之后:

  • 将META-INF文件夹添加到我的src / main / resources文件夹中,然后将属性文件放在那里。
  • 添加带有Class-Path:的MANIFEST文件在里面。
  • 在代码中以多种方式加载文件。

但是似乎没有任何作用。我想这与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 --

我希望有人在这个问题上有一些高级,可以帮助找到解决该问题的方法。如果您需要有关项目文件/结构的其他信息,请告诉我。我很乐意与您分享。

更新(28-04-2015 {1})

为了进行测试,我创建了一个示例项目,该项目试图以与上述场景相同的方式加载属性文件。即使遵循Maven文档(使用META-INF文件夹),我也无法加载属性。

为了这个问题,我在这里上传了测试工作区

我希望有人可以帮助我解决此问题,因为Maven网站上描述的常规方法似乎对我不起作用。

更新(28-04-2015 {2})

好吧,我设法解决了部分问题。由于我添加了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。

最终更新(04-05-2015)

经过漫长的Maven斗争,我设法以自己想要的方式获得了一切。遵循@Deepak和@Joop Eggen的建议,我进行了一些研究,研究如何将所有依赖项放在jar文件夹中,而不是将其解压缩到“超级” jar中。在尝试了很多东西之后,我偶然发现了这个答案按照指示,似乎可以创建此结构:

- runnable.jar
- lib
    - spring-amqp.jar
    - spring-core.jar
    ...

当遵循@Joop Eggen的建议时,我设法以所需的方式加载了该属性。因此,似乎这个问题已得到解答。目前,我仍在寻找如何授予每个答案的方法,因为我无法将赏金分成两部分。我会继续讲下去。

边注

尽管我同时授予了@Joop Eggen赏金和答案,但这并不意味着@Deepak的答案没有贡献。它确实提供了一些有关最佳做法的重要信息,但还不如公认的答案完整。因此,请在此处找到答案时也给他一些荣誉。

乔普·艾根(Joop Eggen):

有两种获取资源的方法,

  • 使用ClassLoader针对使用绝对路径(不带/...的整个类路径
  • 与一个类一起,使用该类的jar中的相对(...)或绝对(/...)路径。

后者似乎更直接,可以用作:

getClass().getResource("/...");
ClassInJar.class.getResource("/...");

现在getClass()只能在非静态对象中使用,并且也很危险:实际的类可能是某个子类,而不是在库jar中。


关于您的应用程序的实际结构。我知道一个Maven目录约定:

src/main/java/...
src/main/resources/...

/ ...进入罐子/战争的地方;软件包目录。

重新组装罐子不好。Class-Path: ...META-INF / MANIFEST.MF中始终存在该条目。最好遵循基本的Maven约定。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

添加库项目并在主项目中使用它

如何使用休眠配置为Maven Eclipse项目制作可运行的jar文件

使用SBT将工件发布到本地Maven存储库并在Gradle项目中使用

使用Maven 2构建可运行的jar

打印到Eclipse Maven项目中使用过的jar文件

无法为非常简单的 Eclipse Maven 项目生成可运行的 JAR

如何在Maven项目中使用ASM库

在本机Wicket项目中使用Maven存储库

如何在Moqui项目中加载外部jar库?

IntelliJ未在Maven项目中加载传递依赖项

是否在Eclipse动态Web项目中加载属性?

我可以选择我在Maven依赖环境中使用的唯一软件包来导出Eclipse中的可运行jar吗?

如何使用Maven + JavaFX创建可运行的JAR文件

我可以创建Windows Phone 8.0类库项目并在Windows Phone 8.1项目中使用它吗

在 Maven 项目中使用 spring boot

在Maven项目中使用HiveContext

如何在普通的Java项目中使用Maven项目jar

maven项目中如何使用maven运行参数?

如何在Maven项目中将jar文件用作库

如何从Maven项目中的外部jar读取属性文件

使用Maven将JAR文件添加到Eclipse中的项目中

如何在共享项目中从Maven本地存储库中获取一个Eclipse项目来引用源jar?

如何在另一个Maven项目中使用一个Maven项目的属性

从属性文件中加载数据,以供Liquibase在Maven构建中使用

Eclipse挂在大型Maven项目中的“验证启动属性”上

如何在eclipse中使用Maven Jetty Plug-in运行多个maven项目

在Eclipse的spring-boot项目中使用Maven的“无法找到主类”

无法使用Maven将gRPC,Protobuf和BoringSSL转换为JAR来构建可运行的Java应用

Maven库在具有不同依赖关系的更多项目中使用