Maven WAR 插件以及如何管理依赖项

发布于 2024-12-07 20:08:40 字数 1056 浏览 1 评论 0原文

好吧,这可能是一个熟悉的问题,但是我仍然感到困惑,并且我正在努力寻找真正澄清细节的答案。

场景 我有几个 Maven 项目,其中大多数创建 JAR 工件,其中一个负责创建 WAR 工件。 WAR 工件依赖于具有编译范围的 JAR 工件,以便这些 JAR 包含在 WEB-INF/lib 文件夹中。

混乱 我仍然不清楚这个插件如何响应 WARs lib 文件夹中包含哪些依赖项和传递依赖项的范围。我的理解是,编译将导致包含 JAR 及其依赖项,这些依赖项也使用编译范围声明(等等递归地),但提供后就停止了。具有所提供范围的依赖项将不会被包含在内。

问题 举一个具体的例子,WAR 项目 war-a 依赖于一个具有编译范围的内部 JAR 项目 jar-a。由于范围的原因,jar-a 将包含在 WARs lib 文件夹中。现在,jar-a 依赖于具有编译范围的第 3 方库 log4j。由于其范围,log4j JAR 也包含在 lib 文件夹中。但是... log4j 的依赖项也是如此,例如邮件等。我想要 log4j 但我不想要它的依赖项。如果我使用provided配置log4j,它的依赖项将不会被包含在内,但它本身也不会被包含在内。

我已经考虑过这些选项,例如使用排除项,但是当有 40 多个内部 JAR 项目时,POM 文件中就会有很多排除项。此外,要使用排除,我需要了解第三方依赖项的具体知识,这感觉没有必要。

任何人都可以澄清、扩展、回答以上任何一个吗?任何意见都将受到高度赞赏。

更新 除上述内容外,我一直坚持一个决定。我是否应该允许将所需的第 3 方 JAR 列表捆绑在 WAR 中,通过我们拥有的各种内部 Maven JAR 项目的编译范围依赖关系来解决。或者我应该声明内部 Maven JAR 项目中提供的所有第 3 方依赖项,然后在 Maven WAR 项目上指定一个包含编译范围的明确集合。

我更喜欢前一种方法,因为额外的第 3 方依赖项将通过传递依赖项路径自动添加到 WAR 工件中。然而,第二种方法提供了准确了解将包含哪些第三方库的确定性。

Okay, this may well be a familiar question, however I still remain confused and I'm struggling to find an answer that really clarifies the details.

The scenario
I have several Maven projects, the majority create JAR artefacts and one is responsible for creating the WAR artefact. The WAR artefact has dependencies on the JAR artefacts with a scope of compile, in order that these JARs are included within the WEB-INF/lib folder.

The confusion
I'm still unclear how this plugin responds to scopes as to which dependencies and transitive dependencies get included within the WARs lib folder. My understand is that compile will result in a JAR being included along with its dependencies that are also declared with a compile scope (and so on recursively), but the buck stops with provided. A dependency with the provided scope will not get included.

The issue
To take a specific example, the WAR project war-a has a dependency on an internal JAR project jar-a with a scope of compile. jar-a will be included with the WARs lib folder because of the scope. Now jar-a has a dependency on the 3rd party library log4j with a scope of compile. The log4j JAR also gets included in the lib folder because of its scope. But... so does log4j's dependencies, such as mail, etc. I want log4j but I dont want its dependencies. If I configure log4j with provided, its dependencies wont be included, but neither will itself.

I've considered the options, such as using exclusions, but when there are 40+ internal JAR projects, that's a lot of exclusions in POM files. Also, to use exclusions requires me to know specific knowledge of a 3rd parties dependencies, which feels unnecessary.

Can anyone clarify, expand, answer any of the above? Any input will be most appreciated.

Update Further to the above, I'm stuck with a decision. Should I allow the list of required 3rd party JARs to be bundled within the WAR, be resolved via the compile scope dependencies of the various internal Maven JAR projects we have. Or should I declare all 3rd party dependencies as provided within the internal Maven JAR projects, then specify a clear set with the compile scope on the Maven WAR project.

I prefer the former approach as additional 3rd party dependencies will be automatically added to the WAR artefact via the transitive dependency paths. Yet the second approach provides the certainty of knowing exactly what 3rd party libraries will be included.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨落画卷 2024-12-14 20:08:41

文档中讨论的主题在某种程度上是一个回答我的问题。它讨论了 标记的使用。

该标签可以在父 POM 文件中声明,并允许您指定依赖项以及排除项的详细信息。然后,任何从父 POM 继承的 POM 都可以照常声明依赖项,但它将继承父 POM 的任何配置,除非被覆盖。

例如,以父 POM 依赖关系配置为例:

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.15</version>
        <exclusions>
          <exclusion>
            <groupId>log4j</groupId>
            <artifactId>mail</artifactId>
          </exclusion>
        </exclusions>
        <scope>compile</scope>
      </dependency>   
    </dependencies>     
  </dependencyManagement>

子 POM 内的依赖关系现在变得更加简单:

  <dependencies>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
    </dependency>
  </dependencies>

这里子 POM 继承版本、排除和范围配置。这并不能解决我提到的所有问题,例如需要了解第 3 方库的依赖项,但它确实提供了一个位置来配置和管理这些更详细的细节。

The subject discussed in this documentation is somewhat an answer to my question. It discusses the use of the <dependencyManagement> tag.

This tag can be declared within a parent POM file and allows you to specify the details of dependencies, as well as exclusions. Then any POM that inherits from the parent POM can declare a dependency as usual, but it will inherit any configuration from the parent, unless overridden.

For instance, take the parent POM dependency configuration:

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.15</version>
        <exclusions>
          <exclusion>
            <groupId>log4j</groupId>
            <artifactId>mail</artifactId>
          </exclusion>
        </exclusions>
        <scope>compile</scope>
      </dependency>   
    </dependencies>     
  </dependencyManagement>

The dependency within the child POM is now made far simpler:

  <dependencies>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
    </dependency>
  </dependencies>

Here the child POM inherits the version, exclusions and scope configuration. This doesn't resolve all the concerns I've mentioned, such as the need to know about the 3rd party library's dependencies, but it does provide a single place for configuring and managing these finer details.

可爱暴击 2024-12-14 20:08:40

jar-a 项目的 pom.xml 中,使用 exclusions 标记排除 mail 依赖项:

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.x</version>
    <exclusions>
        <exclusion>
            <groupId>log4j</groupId> 
            <artifactId>mail</artifactId>
        </exclusion>
    </exclusions>
</dependency>

如果您的3rd party lib 依赖于不必要的库,这是你能做的最好的事情。如果它们是开源项目,您可以提交一个补丁来删除不必要的库。

关于“未来的证明”:如果您想要可重复的构建,您应该为依赖项声明确切的版本号,例如 [1.0] ,这不会让 Maven 在新版本出现时更新它们。通过这种方式,第三方库永远不会更改其依赖项,因为您不会更新到依赖于其他库的新版本。当然,当您将第 3 方库更新到新版本时,您也应该检查依赖关系。

另一方面,您的功能测试应该报告新的库版本何时破坏您的应用程序。

我发现使用 40 多个 POM 不太容易,但它仍然比以前必须手动下载每个依赖项更容易。

http://maven.apache.org/guides/introduction /introduction-to-dependency-mechanism.html#Transitive_Dependencies

In the pom.xml of the jar-a project exclude the mail dependency with the exclusions tag:

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.x</version>
    <exclusions>
        <exclusion>
            <groupId>log4j</groupId> 
            <artifactId>mail</artifactId>
        </exclusion>
    </exclusions>
</dependency>

If your 3rd party lib depends on an unnecessary library that is the best thing you can do. If they are open source projects you can submit a patch which removes the unnecessary libs.

About the 'future proofing': If you would like a repeatable build you should declare exact version numbers for your dependencies like [1.0] which doesn't let maven to update them whenever a new version come out. In this way a 3rd party library never changes its dependencies because you don't update to a new version which depends on other libs. Of course you should check the dependencies too when you update a 3rd party lib to a new version.

On the other hand your functional tests should report when a new library version broke your application.

I see that it's not too easy with 40+ POMs but it still easier than the old times when you had to download every dependency by hand.

http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Transitive_Dependencies

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文