【问题标题】:How to exclude jars generated by maven war plugin?如何排除 maven war 插件生成的 jars?
【发布时间】:2010-11-05 03:00:52
【问题描述】:

由于传递依赖关系,我的战争被 xml-apis、xerces jars 填充。 我尝试按照 maven-war-plugin 参考页面上的说明进行操作,但它不起作用。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
      <packagingExcludes>WEB-INF/lib/xalan-2.6.0.jar,WEB-INF/lib/xercesImpl-2.6.2.jar,WEB-INF/lib/xml-apis-1.0.b2.jar,WEB-INF/lib/xmlParserAPIs-2.6.2.jar</packagingExcludes>
      <webXml>${basedir}/src/main/webapp/WEB-INF/web.xml</webXml>
      <warName>project1</warName>
      <warSourceDirectory>src/main/webapp</warSourceDirectory>
    </configuration>
</plugin>

我做错了什么? 如果重要的话,我发现我使用的 maven-war-plugin 的版本是 2.1-alpha-1

【问题讨论】:

    标签: java maven-2


    【解决方案1】:

    您可以将这些依赖项标记为已提供:

    <dependency>
      <groupId>xerces</groupId>
      <artifactId>xerces</artifactId>
      <version>2.4.0</version>
      <scope>provided</scope>
    </dependency>
    

    这样 maven 会将它们添加到编译类路径中,但不会打包它们。假定它们存在于您的 servlet 容器中。

    在“范围”下查看有关 maven 范围 here 的更多信息

    编辑 如果你想删除通过传递依赖添加的类,你可以像这样从依赖中排除它们:

    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
            <version>2.5.6</version>
            <exclusions>
                    <exclusion>
                            <groupId>commons-logging</groupId>
                            <artifactId>commons-logging</artifactId>
                    </exclusion>
            </exclusions>
    </dependency>
    

    (取自this answer

    查看更多here

    【讨论】:

    • 问题是 xerces 例如是通过传递依赖引入的。我不想用所有这些无关的填充物填充我的 pom.xml。
    • 之后别忘了用mvn clean package打包
    • 如何在eclipse插件中使用这个?如果我将依赖项标记为已提供,它可能在应用服务器中可见,但 eclipse 无法编译,因为 eclipse 插件没有将提供的依赖项放入 eclipse 类路径。
    【解决方案2】:

    我修好了。

    仔细阅读参考资料,我发现元素 packagingExcludes 应该是 warSourceExcludes

    【讨论】:

    • 你试过我的建议了吗?它将使您免于提及每个 jar 两次(依赖项和排除项)
    • 对于您使用的战争插件版本来说是正确的。在 2.1-alpha-2 中,它已更改为 PackagingExcludes。更多详情见jira.codehaus.org/browse/MWAR-135
    • 在 2.1.1 版本的插件中,它适用于:&lt;packagingExcludes&gt;WEB-INF/lib/xercesImpl-2.9.1.jar,WEB-INF/lib/xml-apis-1.3.04.jar&lt;/packagingExcludes&gt;,正常排除似乎不起作用。我没有尝试将这些部门覆盖为“提供”。
    【解决方案3】:

    关于排除传递依赖,我认为不适用于传递依赖的传递,我认为可能是这种情况。

    例如,添加 hibernate-core -> dom4j -> xml-apis 的依赖,如果在 hibernate-core 附近添加 xml-apis 的排除,仍然添加 xml-apis...

    【讨论】:

      【解决方案4】:

      我无法修改依赖的战争文件。我需要避免来自 lib 的一些旧 jar 文件。这个 POM.xml 配置的 sn-p 对我来说效果很好。我使用 Maven 2.2。

      <build>
          <plugins>
              <!-- put aside some unwanted jars from war...-->
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-war-plugin</artifactId>
                  <version>2.1.1</version>
                  <configuration>
                      <overlays>
                          <overlay>
                              <groupId>com.company.app</groupId>
                              <artifactId>web_app</artifactId>
                              <excludes>
                                  <exclude>WEB-INF/lib/json-lib-2.2.2-jdk13.jar</exclude>                                
                              </excludes>
                          </overlay>
                      </overlays>
                  </configuration>
              </plugin>
              ....
      

      【讨论】:

        【解决方案5】:

        当使用 maven 3(我使用 3.0.2)和 提供的范围 进行编译时,您会遇到传递依赖的问题(您在 WAR 中丢失了 JAR)。 如果您使用旧版本的 maven(我使用的是 2.2.1),则 WAR 包含指定的内容(只有依赖项未提供

        【讨论】:

          【解决方案6】:

          要添加一些说明,您绝对可以排除传递依赖项。例如,如果您对 A 有一个本地依赖项,它对 M 有一个依赖项,而 M 又对 X 有一个依赖项,那么您可以在指定 A 依赖项的地方排除 X。

          例如,假设你依赖'myPackageA',它依赖于Rampart,它依赖于Xerces,那么你可以在你的myPackageA依赖中排除Xerces:

           <groupId>myPackageA.dependsOnRampart.whichDependsOnXerces</groupId>
           <artifactId>someArtifact</artifactId>
           <version>2.1</version>
           <exclusions>
             <exclusion>
               <groupId>org.apache.xerces</groupId>
               <artifactId>xmlParserAPIs</artifactId>
             </exclusion>
             <exclusion>
               <groupId>org.apache.xerces</groupId>
               <artifactId>xml-apis</artifactId>
             </exclusion>
             <exclusion>
               <groupId>org.apache.xerces</groupId>
               <artifactId>xercesImpl</artifactId>
             </exclusion>
             <exclusion>
               <groupId>org.apache.xerces</groupId>
               <artifactId>resolver</artifactId>
             </exclusion>
             <exclusion>
               <groupId>org.apache.xerces</groupId>
               <artifactId>serializer</artifactId>
             </exclusion>
           </exclusions>
          

          之后要检查您的依赖关系,请运行“mvn dependency:tree”,希望您不会看到任何 xerces 依赖关系。

          【讨论】:

            【解决方案7】:

            查看我的回答herepackaging-excludes 条目仅适用于 maven-war-plugin 版本 2.1-alpha-1 and above。因此,您可能需要升级使用的版本,或者您可能更喜欢使用依赖级别注入,因为它可以更精确地排除特定 jar。

            【讨论】:

              【解决方案8】:

              您可以通过在 &lt;packagingExcludes&gt;&lt;/packagingExcludes&gt; 内指定 &lt;/configuration&gt;&lt;configuration&gt; 来做到这一点。

              <project>
                ...
                <build>
                  <plugins>
                    <plugin>
                      <artifactId>maven-war-plugin</artifactId>
                      <version>3.2.0</version>
                      <configuration>
                        <packagingExcludes>
                          WEB-INF/lib/ex1-*.jar,
                          WEB-INF/lib/ex2-logging-*.jar
                        </packagingExcludes>
                      </configuration>
                    </plugin>
                  </plugins>
                </build>
                ...
              </project>
              

              您也可以通过通配符正则表达式来指定。请参阅documentation 了解更多信息。

              【讨论】:

                【解决方案9】:

                正确的解决方案是使用&lt;packagingExcludes&gt; 配置,因为&lt;scope&gt;provided&lt;/scope&gt; 解决方案是一个hack。

                考虑以下多模块项目:

                        A
                      (war)
                      /   \
                     B     C
                   (jar) (jar)
                    /     /
                   D     /
                 (jar)  /
                 / | \ /
                e  f  g
                

                在这个多模块项目中,模块 A 需要模块 {B, C, D},但不是 {e, f, @987654330 @}。但是,BD 模块 确实 需要 {ef g} 和 C 需要 {g}。


                首先,让我们尝试用&lt;scope&gt;provided&lt;/scope&gt; 方法解决这个问题:

                要从 A 中排除 {e, f, g},&lt;scope&gt;provided&lt;/scope&gt; 规范必须存在于 D 的 POM 中。但是等等,B 需要 {e, f, g}。因此,为了解决这个问题,B 的 POM 中也必须存在 {efg} 的依赖声明(使用 &lt;scope&gt;provided&lt;/scope&gt;)。这意味着来自D 的依赖规范复杂性必须被拉入B。同样,由于 C 依赖于 {g},因此 {g} 的依赖声明必须存在于 C 的 POM 中。

                使用&lt;scope&gt;provided&lt;/scope&gt; 解决方案,模块BCD 都必须知道A 不能有{efg} .

                这种方式打破了封装原则,在依赖图复杂的多模块项目中不实用。


                其次,让我们尝试用&lt;packagingExcludes&gt;的方法解决这个问题:

                要从A 中排除{efg},必须在A 的POM 中提供以下内容:

                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <configuration>
                      <packagingExcludes>B*.jar,C*.jar</packagingExcludes>
                    </configuration>
                </plugin>
                

                使用此解决方案,“必须从 A 中排除的内容”的复杂性仅包含在 A 的 POM 中。这使模块BCD 不必担心为了A 而排除传递依赖。

                此方案坚持封装原则。

                【讨论】:

                  猜你喜欢
                  • 2016-10-04
                  • 2017-02-21
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-11-02
                  • 2013-12-21
                  • 2012-06-07
                  • 2014-10-09
                  相关资源
                  最近更新 更多