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

发布于 2025-01-04 16:59:57 字数 4305 浏览 3 评论 0原文

我已将 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

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

.
|
|-- Patrac-ear
|   `-- pom.xml
|-- Patrac-ejb
|  `-- pom.xml
|-- Patrac-web
|   `-- pom.xml
`-- pom.xml

在部署应用程序时,我不知道如何停止一些烦人的警告消息:

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.

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

为了可移植性,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 的类路径条目放入清单中。它不应该这样做。它应该只为 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>

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

非常感谢您的任何建议或指示。

参考资料:

I've used the maven-ear-plugin with the maven-war-plugin and maven-ejb-plugin to successfully deploy and run an application packaged as EAR to 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

In the application source code directories, the poms are located as follows:

.
|
|-- Patrac-ear
|   `-- pom.xml
|-- Patrac-ejb
|  `-- pom.xml
|-- Patrac-web
|   `-- pom.xml
`-- pom.xml

I can't figure out how to stop a few annoying warning messages when I deploy the application:

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.

Patrac-web-1.0-SNAPSHOT.war!META-INF/MANIFEST.MF looks like this:

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

The ejb class-path entry needs to be present for the EJB module, for portability, and the richfaces, cssparser and guava class-path entries should NOT be in the WAR's manifest.

The problem is that my WAR depends on all of the JARs, some of which live in WEB-INF/lib (RichFaces), and one JAR, Patrac-ejb-1.0-SNAPSHOT.jar, that lives in the root directory of the EAR. Each dependency needs to be entered in Patrac-web/pom.xml but NOT each of the dependencies should appear in the manifest.

Maven puts the JARs in the correct places, but it puts Class-Path entries for ALL of the JARs into the manifest. It should not do this. It should ONLY put an entry in for 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>

I'm using the most recent maven-war-plugin version, 2.2. How do I tell the maven-war-plugin to put the "non-ejb" JARs into WEB-INF/lib while not putting class-path entries in MANIFEST.MF?

Any advice or pointers you have are greatly appreciated.

References:

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

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

发布评论

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

评论(4

兔姬 2025-01-11 16:59:57

Maven 存档器,由 Maven WAR 插件,提供了一种在 WAR 清单中生成类路径条目的方法,但不幸的是,归档器采用了全或-没有什么办法。将 addClassPath=true 传递给存档配置后,存档程序会将 WAR 的所有必需和可选依赖项的类路径条目放入清单中。

然而,有些条目根本不属于那里。类路径条目用于表示 "下载扩展” 或对 WAR 外部 JAR 的引用。因此,位于 WEB-INF/lib 中的 JAR 不应在 WAR 清单中具有类路径条目。当您在归档器中设置 addClassPath=true 时,Maven 的 War 插件会打破此规则。

此外,当您将 addClassPath=true 传递给 Maven 的归档器时,它会为所有类路径条目提供相同的目录前缀——无论依赖项位于 EAR 中的何处。当可选依赖项和必需依赖项位于不同位置(例如 EAR 根目录、EAR lib 和 WAR WEB-INF/lib)时,这会导致问题。

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

因此,如果您的 WAR 和我的一样,依赖于位于 EAR 根部的 EJB 模块,以及位于WEB-INF/lib 中的任意数量的依赖项,Maven archiver 将生成 Class - 所有依赖项的路径条目,无论它们在 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

需要的是覆盖上面的情况 #4:不要创建类路径条目,是的,执行复制将 JAR 放入 WEB-INF/lib 中。 Maven 归档程序应该默认实现此行为。

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

<manifest>
    <addClasspath>true</addClasspath>
</manifest>

并将其替换为:

<manifestEntries>
    <Class-Path>Patrac-ejb-${project.version}.jar</Class-Path>
</manifestEntries>

使用此配置,仅为 EJB 模块显式创建一个类路径条目。

The Maven archiver, used by the Maven WAR plugin, provides a means to generate Class-Path entries in the WAR's manifest but unfortunately the archiver takes an all-or-nothing approach. Once you pass addClassPath=true to the archive configuration, the archiver puts Class-Path entries for all of the WAR's required- and optional dependencies into the manifest.

However, some entries simply do not belong in there. Class-Path entries are used to denote "Download Extensions," or references to JARs external to the WAR. JARs located in WEB-INF/lib should not, therefore, have Class-Path entries in the WAR's manifest. Maven's War plugin breaks this rule when you set addClassPath=true in the archiver.

Moreover, when you pass addClassPath=true to Maven's archiver, it gives all of the Class-Path entries the same directory prefix -- no matter where the dependencies are located within the EAR. This causes problems when optional- and required dependencies are located in separate locations such as the EAR root directory, EAR lib and WAR WEB-INF/lib.

Naturally, when one deploys an EAR whose WAR manifest contains the above errors JBoss throws warnings if the WAR class loader can ultimately find a dependency (JARs located in WEB-INF/lib) or errors if the class path prefix is wrong (e.g. on an EJB JAR or a dependency in the EAR lib directory).

Therefore, if your WAR, like mine, depends on an EJB module, located at the root of the EAR, and any number of dependencies that are located inWEB-INF/lib, Maven archiver will generate Class-Path entries for all of the dependencies and they will all have the same prefix regardless of their location within the EAR.

Not good.

The problem would be ameliorated somewhat if the archiver would provide a means to exclude Class-Path entries of the JARs located in WEB-INF. But it does not.

Here's a summary of the outcome for each dependency setting when one uses 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

What is needed is coverage for situation #4, above: do not create a Class-Path entry and, yes, do copy the JAR into WEB-INF/lib. Maven archiver should implement this behavior by default.

The best solution I can think of is to use brute force and turn off the Maven archiver's automatic Class-Path entry generation. Instead, I explicitly create a Class-Path entry for the EJB module in the WAR's manifest using the archiver's manifestEntries option. The way to do this is to remove the following from Patrac-web/pom.xml:

<manifest>
    <addClasspath>true</addClasspath>
</manifest>

and replace it with this:

<manifestEntries>
    <Class-Path>Patrac-ejb-${project.version}.jar</Class-Path>
</manifestEntries>

Using this configuration only one Class-Path entry, for the EJB module, is created explicitly.

橙幽之幻 2025-01-11 16:59:57

对于那些需要从 MANIFESTWEB-INF/lib 中排除的 JAR,您需要将它们标记为 provided< /代码>。这意味着 JAR 文件将由容器提供(在您的情况下是 EAR)。

对于其他选项,请检查 WAR 清单指南

For those JARs with need to be excluded from MANIFEST and from WEB-INF/lib you need to mark them as <scope>provided</scope>. That means JAR files will be provided by the container (and that is EAR in your case).

For other options check WAR manifest guide.

听,心雨的声音 2025-01-11 16:59:57

EJB 模块需要存在 ejb 类路径条目……

仅对于引用其他 EJB 模块(在同一 EAR 的根目录中)的 EJB 模块(在 EAR 的根目录中),才需要存在类路径

The ejb class-path entry needs to be present for the EJB module …

The class-path only needs to be present for EJBs modules (in the root of the EAR) who reference other EJB modules (in the root of the same EAR)

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