Как правильно настроить путь класса в maven-war-plugin
Я использовал плагин maven-ear с плагином maven-war и 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
В каталогах исходного кода приложения, помпы расположены следующим образом:
.
|
|-- 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, для переносимости и богатых интерфейсах, записи классов классов cssparser и guava НЕ должны находиться в манифесте WAR.
Проблема в том, что моя WAR зависит от всех JAR, некоторые из которых живут в WEB-INF/lib
(RichFaces) и один JAR, Patrac-ejb-1.0-SNAPSHOT.jar
, который живет в корневом каталоге EAR. Каждая зависимость должна быть введена в Patrac-web/pom.xml, но НЕ каждая из зависимостей должна появляться в манифесте.
Maven помещает JAR в правильные места, но он помещает записи Class-Path для ВСЕХ JAR в манифест. Он не должен этого делать. Он должен ТОЛЬКО вводить запись для Patrac-ejb-1.0-SNAPSHOT.jar
.
<!--
According to Java EE 6 spec, the application is portable if
Patrac-web.war 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?
Любые советы или указатели, которые у вас есть, очень ценятся.
Литература:
Ответы
Ответ 1
архиватор Maven, используемый плагин Maven WAR, предоставляет средство для генерации записей класса в манифестах WAR, но, к сожалению, архиватор использует подход "все или ничего". После того, как вы передадите addClassPath=true
в конфигурацию архива, архиватор помещает записи манифеста для всех обязательных и необязательных зависимостей WAR в манифест.
Однако некоторые записи просто не принадлежат. Элементы класса-пути используются для обозначения "Download Extensions" , или ссылок на внешние JAR-интерфейсы WAR. Таким образом, JAR, расположенные в WEB-INF/lib
, не должны иметь записи Class-Path в манифесте WAR. Плагин Maven War нарушает это правило, когда вы устанавливаете addClassPath=true
в архиваторе.
Кроме того, когда вы передаете addClassPath=true
в архиватор Maven, он предоставляет все записи класса-пути одному и тому же префиксу каталога - независимо от того, где находятся зависимости в EAR. Это вызывает проблемы, когда необязательные и требуемые зависимости расположены в разных местах, таких как корневой каталог EAR, EAR lib
и WAR WEB-INF/lib
.
Естественно, что при развертывании EAR, чей WAR-манифест содержит вышеупомянутые ошибки, JBoss выдает предупреждения, если загрузчик класса WAR может в конечном счете найти зависимость (JARs, расположенную в WEB-INF/lib
), или ошибки, если префикс пути класса неверен (например, on EJB JAR или зависимость в каталоге EAR lib
).
Поэтому, если ваша WAR, как и моя, зависит от модуля EJB, расположенного в корне EAR, и любого количества зависимостей, расположенных в WEB-INF/lib
, архиватор Maven будет генерировать записи класса-типа для всех зависимостей, и все они будут иметь один и тот же префикс, независимо от их местоположения в EAR.
Нехорошо.
Проблема будет несколько улучшена, если архиватор предоставит средства для исключения записей класса-класса JAR, расположенных в WEB-INF. Но это не так.
Здесь приведено краткое описание результата для каждого параметра зависимости, когда вы используете 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 должен реализовать это поведение по умолчанию.
Лучшее решение, о котором я могу думать, - использовать грубую силу и отключить автоматическое создание записей Class-Path Maven. Вместо этого я явно создаю запись класса-класса для модуля EJB в манифесте WAR, используя параметр архиватор manifestEntries
. Способ сделать это - удалить из Patrac-web/pom.xml
следующее:
<manifest>
<addClasspath>true</addClasspath>
</manifest>
и замените его на это:
<manifestEntries>
<Class-Path>Patrac-ejb-${project.version}.jar</Class-Path>
</manifestEntries>
Используя эту конфигурацию, создается только одна запись Class-Path для модуля EJB.
Ответ 2
Для тех JAR, которые необходимо исключить из MANIFEST
и из WEB-INF/lib
, вам нужно пометить их как <scope>provided</scope>
. Это означает, что файлы JAR будут предоставлены контейнером (и это будет EAR в вашем случае).
Для других опций проверьте Руководство по манифеста WAR.
Ответ 3
Элемент класса ejb должен присутствовать в модуле EJB...
Путь к классу должен присутствовать только для модулей EJBs (в корне EAR), которые ссылаются на другие модули EJB (в корне того же EAR)
Ответ 4
читал конкретно о тощих войнах
http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html