【问题标题】:Enforce maven use resource file in main jar instead of those in dependency jars强制 maven 在主 jar 中使用资源文件而不是依赖 jar 中的资源文件
【发布时间】:2013-12-12 21:42:44
【问题描述】:

编辑:

结构:

A.jar(或 A.war)
|
|_ src/main/resources/config.properties - (标记为 p1)
|
|_ 依赖的 jars
|
|_B.jar
|
|_src/main/resources/config.properties - (标记为 p2)

  • 当我运行 A.jar(或 A.war,因为 B.jar 可以由 Web 应用程序或 Java 进程调用)时,我希望 B.jar 中的代码始终使用 p1 em>;
  • 当我单独运行 B.jar 时,我希望 B.jar 中的代码使用 p2

另一种描述方式是主jar/war(这里是A.jar/war)中的同名资源文件将始终在依赖jar(B.jar)中覆盖它。

我查看了maven-shaded-plugin的源代码,似乎不能保证main jar/war中的资源文件会被使用。有人有什么主意吗?或者任何插件都可以完成这项工作?谢谢!

【问题讨论】:

  • 欢迎来到 Stack Overflow。我认为您可能会从充实您的问题并使其更清晰易懂中受益;在目前的状态下,你问的不是很清楚。

标签: maven plugins dependencies overriding


【解决方案1】:

在一定程度上,这将取决于 B.jar 如何加载其属性。如果 B.jar 使用该机制加载其属性:

getClass().getResourceAsStream("/config.properties");

然后Java's hierarchical classloading behaviour 会在你期望的地方找到config.properties

  • 当 B.jar 作为 A.war 的一部分包含时,将找到 p1
  • 当 B.jar 独立运行时,会找到 p2

我创建了一个小型测试应用程序(包含 jar 的战争),它在执行战争和单独执行 jar 时确认上述行为。

如果项目 A 不是战争,而是本身是一个独立的 jar (A.jar),那么您最好使用 Maven shade plugin 创建一个大的 A.jar。该插件将在 A.jar 中包含 B.jar 的内容。

利用插件的过滤机制,可以保证p1会被使用。您可以告诉插件从 B.jar 中排除 config.properties

<configuration>
    <filters>
        <filter>
            <artifact>groupIdForB.jar:artifactIdForB.jar</artifact>
            <excludes>
                <exclude>config.properties</exclude>
            </excludes>
        </filter>
    </filters>
</configuration>

通过如上所述排除 p2,您将在大 A.jar 中得到 p1

【讨论】:

  • 您好,属性确实使用 getClass().getResourceAsStream("/config.properties");正如你所说,战争案是预料之中的。对于 jar 案例,如果我有一个包含此文件的依赖项 jar 列表,我是否必须对每个依赖项执行排除?无论如何只保留主jar中的一个而忽略依赖jar中的那些?谢谢!
  • Maven shade 插件支持在&lt;artifact&gt; 标签中使用通配符语法 - 所以如果依赖 jars 有一个共同的 groupId 那么你应该能够做类似`groupId:* 工件>。这应该将过滤器应用于所有依赖项 jar,只在封闭的主 jar 中留下 config.properties。关于此here 的更多信息
猜你喜欢
  • 2018-02-25
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
  • 2011-06-27
  • 2019-06-04
  • 1970-01-01
  • 1970-01-01
  • 2012-03-07
相关资源
最近更新 更多