如何在maven-war-plugin中正确设置清单类路径

Pat*_*ner 16 ear maven java-ee-6

我已经使用maven-ear-plugin和maven-war-plugin以及maven-ejb-plugin成功部署并运行打包为EAR的应用程序到Jboss AS7.

.
|-- META-INF
|   |-- application.xml
|   |-- MANIFEST.MF
|   `-- maven
|       `-- com.patrac
|           `-- Patrac-ear
|               |-- pom.properties
|               `-- pom.xml
|-- Patrac-ejb-1.0-SNAPSHOT.jar
`-- Patrac-web-1.0-SNAPSHOT.war
Run Code Online (Sandbox Code Playgroud)

在应用程序源代码目录中,poms位于以下位置:

.
|
|-- Patrac-ear
|   `-- pom.xml
|-- Patrac-ejb
|  `-- pom.xml
|-- Patrac-web
|   `-- pom.xml
`-- pom.xml
Run Code Online (Sandbox Code Playgroud)

在部署应用程序时,我无法弄清楚如何停止一些恼人的警告消息:

12:32:03,958 WARN  [org.jboss.as.server.deployment] (MSC service thread 1-2) Class Path entry richfaces-components-ui-4.0.0.Final.jar in "/content/Patrac.ear/Patrac-web-1.0-SNAPSHOT.war"  does not point to a valid jar for a Class-Path reference.
12:32:03,970 WARN  [org.jboss.as.server.deployment] (MSC service thread 1-2) Class Path entry richfaces-components-api-4.0.0.Final.jar in "/content/Patrac.ear/Patrac-web-1.0-SNAPSHOT.war"  does not point to a valid jar for a Class-Path reference.
12:32:03,984 WARN  [org.jboss.as.server.deployment] (MSC service thread 1-2) Class Path entry richfaces-core-api-4.0.0.Final.jar in "/content/Patrac.ear/Patrac-web-1.0-SNAPSHOT.war"  does not point to a valid jar for a Class-Path reference.
12:32:03,989 WARN  [org.jboss.as.server.deployment] (MSC service thread 1-2) Class Path entry richfaces-core-impl-4.0.0.Final.jar in "/content/Patrac.ear/Patrac-web-1.0-SNAPSHOT.war"  does not point to a valid jar for a Class-Path reference.
Run Code Online (Sandbox Code Playgroud)

Patrac-web-1.0-SNAPSHOT.war!META-INF/MANIFEST.MF看起来像这样:

Manifest-Version: 1.0
Built-By: pgarner
Build-Jdk: 1.7.0_02
Class-Path: Patrac-ejb-1.0-SNAPSHOT.jar richfaces-components-ui-4.0.0.
 Final.jar richfaces-components-api-4.0.0.Final.jar richfaces-core-api
 -4.0.0.Final.jar richfaces-core-impl-4.0.0.Final.jar cssparser-0.9.5.
 jar sac-1.3.jar guava-r08.jar
Created-By: Apache Maven
Archiver-Version: Plexus Archiver
Run Code Online (Sandbox Code Playgroud)

为了便于携带,需要为EJB模块提供ejb类路径条目,并且richfaces,cssparser和guava类路径条目不应该在WAR的清单中.

问题是我的WAR依赖于所有JAR(其中一些存在于WEB-INF/lib(RichFaces)中)和一个JAR Patrac-ejb-1.0-SNAPSHOT.jar(位于EAR的根目录中).需要在Patrac-web/pom.xml中输入每个依赖项,但不是每个依赖项都应该出现在清单中.

Maven将JAR放在正确的位置,但它将所有JAR的Class-Path条目放入清单中.它不应该这样做.它只应该输入一个条目Patrac-ejb-1.0-SNAPSHOT.jar.

  <!--
    According to Java EE 6 spec, the application is portable if
    Patrac-web.war's META-INF/MANIFEST.MF contains a Class-Path entry
    for Patrac-ejb-1.0-SNAPSHOT.jar.

    <optional>true</optional> is the flag that maven-war-plugin uses
    to put the entry in MANIFEST.MF without copying Patrac-ejb-1.0-SNAPSHOT.jar
    into WEB-INF/lib.  This is what I want.

    <scope>provided</scope> would cause maven-war-plugin to NEITHER
    put the entry in MANIFEST.MF nor copy Patrac-ejb.jar into WEB-INF/lib,
    which would not be good.

    No tag at all would cause maven-war-plugin to BOTH put the entry in
    MANIFEST.MF and copy Patrac-ejb.jar into WEB-INF/lib, which would
    also not be good.
  -->
  <dependency>
     <groupId>com.patrac</groupId>
     <artifactId>Patrac-ejb</artifactId>
     <type>ejb</type>
     <optional>true</optional>
  </dependency>

  <!--
   These two dependencies are used to copy
  the other JAR files into WEB-INF/lib and there
  should not be any class-path entries for such
  JARs in MANIFEST.MF, in order to avoid the
  error messages.
  -->
    <dependency>
        <groupId>org.richfaces.ui</groupId>
        <artifactId>richfaces-components-ui</artifactId>
    </dependency>
    <dependency>
        <groupId>org.richfaces.core</groupId>
        <artifactId>richfaces-core-impl</artifactId>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

我正在使用最新的maven-war-plugin版本,2.2.如何告诉maven-war-plugin将"非ejb"JAR放入WEB-INF/lib而不在MANIFEST.MF中放入类路径条目?

任何建议或指示都非常感谢.

参考文献:

Pat*_*ner 21

Maven WAR插件使用的Maven归档程序提供了在WAR清单中生成Class-Path条目的方法,但不幸的是归档程序采用了全有或全无的方法.一旦传递到归档配置,归档器就会将所有 WAR的必需和可选依赖项的Class-Path条目放入清单中.addClassPath=true

但是,有些条目根本就不属于那里.Class-Path条目用于表示"Download Extensions"或对WAR 外部的JAR的引用.位于JAR文件WEB-INF/lib应该没有,因此,必须在WAR的Class-Path清单条目.当您addClassPath=true在归档器中设置时,Maven的War插件会破坏此规则.

此外,当您传递addClassPath=true给Maven的归档程序时,它会为所有Class-Path条目提供相同的目录前缀 - 无论依赖项位于EAR中的哪个位置.当可选和必需的依赖项位于不同的位置(例如EAR根目录,EAR lib和WAR)时,这会导致问题WEB-INF/lib.

当然,当一个部署其WAR清单包含上述错误的EAR时,如果WAR类加载器最终可以找到依赖项(位于JAR中WEB-INF/lib)或者如果类路径前缀错误(例如,在EJB JAR或依赖项上),则JBoss会发出警告在EAR lib目录中).

因此,如果您的WAR(如我的)依赖于位于EAR根目录的EJB模块以及位于其中的任意数量的依赖项WEB-INF/lib,Maven归档程序将为所有依赖项生成类路径条目,它们将全部生成无论其在EAR中的位置如何,都具有相同的前缀.

不好.

如果归档程序提供了一种方法来排除位于WEB-INF中的JAR的类路径条目,那么问题就会有所改善.但事实并非如此.

以下是使用时每个依赖关系设置的结果摘要addClassPath=true:

           Setting                  Generate               Copy JAR into
                                   Class-Path              WEB-INF/lib
                                     Entry

1.  <scope>provided</scope>             NO                      NO

2.  <optional>true</optional>          YES                      NO

3.  (no option -- default)             YES                     YES

4.  ?????                               NO                     YES
Run Code Online (Sandbox Code Playgroud)

我们需要的是上面情况#4的覆盖范围:不要创建Class-Path条目,是的,将JAR复制到WEB-INF/lib.默认情况下,Maven归档程序应该实现此行为.

我能想到的最好的解决方案是使用暴力破解并关闭Maven归档器的自动类路径条目生成.相反,我使用archiver的manifestEntries选项为WAR的清单中的EJB模块显式创建了一个Class-Path条目.执行此操作的方法是从以下位置删除以下内容Patrac-web/pom.xml:

<manifest>
    <addClasspath>true</addClasspath>
</manifest>
Run Code Online (Sandbox Code Playgroud)

并将其替换为:

<manifestEntries>
    <Class-Path>Patrac-ejb-${project.version}.jar</Class-Path>
</manifestEntries>
Run Code Online (Sandbox Code Playgroud)

使用此配置,只显示EJB模块的一个Class-Path条目.