#deployment #packaging #war #maven-assembly-plugin
#развертывание #упаковка #Война #maven-assembly-plugin
Вопрос:
Я работаю над многомодульным проектом с использованием Spring, Hibernate, GWT и Maven 3 и пытаюсь развернуть дистрибутив war-файла в контейнере сервлета (предпочтительно Tomcat 7 или Jetty 8). Я создаю файл войны с помощью maven-assembly-plugin 2.2.1 (я использую maven 3). Во время сборки maven все работает идеально, и создается архив дистрибутива.
Но когда я пытаюсь развернуть файл war, я получаю ClassNotFound-Exceptions (например, Spring ContextLoaderListener и т.п.), Хотя все на месте (Web-inf / lib и т.д. pp.). Итак, веб-приложение не запускается. Затем я распаковываю war-файл в каталог webapp контейнеров сервлетов, и все работает нормально … ??
После дальнейшего расследования я наткнулся на следующую вещь: Если я беру произвольный файл war A’, созданный maven-war-plugin (!), замените его содержимое распакованным содержимым из файла war, который я создал с помощью maven-assembly-plugin (позвольте мне назвать его A.), я вижу, что происходят две вещи:
- результирующий файл war A’ на несколько байт меньше моего исходного файла A, хотя их содержимое идентично
- развертывание ‘внезапно работает как шарм
Это странно, и я абсолютно понятия не имею, что происходит. Может быть, проблема в том, что maven-war-plugin и maven-assembly-plugin по-разному обрабатывают упаковку файла war?! Я имею в виду, что war — это всего лишь переименованный zip-файл с некоторой предопределенной структурой… Может быть, это не имеет абсолютно никакого отношения к maven, но к кодировке файла или другим вещам? Есть идеи по этому поводу? Я ценю любой намек, который мог бы помочь мне в расследовании этого…
Это мой дескриптор сборки
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>dist</id>
<formats>
<format>war</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<includes>
<include>mypackage.client:parametermgmt:*</include>
<include>mypackage.static:client:*</include>
</includes>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>/</outputDirectory>
</dependencySet>
<dependencySet>
<unpack>false</unpack>
<includes>
<include>mypackage.server.database:domain:*</include>
<include>mypackage.server.businessobjects:BOdomain:*</include>
<include>mypackage.server.security:security:*</include>
<include>mypackage.server.services:paramgmt:*</include>
</includes>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>Web-inf/lib</outputDirectory>
</dependencySet>
<dependencySet>
<unpack>true</unpack>
<includes>
<include>mypackage.static:server:*</include>
</includes>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>/</outputDirectory>
</dependencySet>
<dependencySet>
<unpack>false</unpack>
<includes>
<include>*</include>
</includes>
<excludes>
<exclude>mypackage.*</exclude>
</excludes>
<scope>runtime</scope>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>Web-inf/lib</outputDirectory>
</dependencySet>
</dependencySets>
Ответ №1:
Maven-assembly-plugin не предназначен для создания войны. Вместо этого используйте maven-war-plugin.
Если вам нужно создать файлы war для разных сред, таких как тестирование, контроль качества, производство. Это также может быть использовано в качестве основы для разных серверов приложений. Но если мы говорим о сервере приложений, это означает, что мы должны создавать файлы ear вместо файлов war (это означает использовать maven-ear-plugin вместо maven-war-plugin).
|-- pom.xml
`-- src
|-- main
| |-- java
| |-- resources
| |-- environment
| | |-- test
| | | `-- database.properties
| | |-- qa
| | | `-- database.properties
| | `-- production
| | `-- database.properties
| `-- webapp
Для этого вам нужна следующая сборка (для каждой среды), которая может быть создана на основе этого в качестве шаблона:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>test</id>
<formats>
<format>war</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<useProjectArtifact>true</useProjectArtifact>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<outputDirectory>WEB-INF</outputDirectory>
<directory>${basedir}/src/main/environment/test/</directory>
<includes>
<include>**</include>
</includes>
</fileSet>
</fileSets>
</assembly>
Для поддержки различных артефактов для разных сред настало время для плагина maven-assembly, подобного этому:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>test</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${project.basedir}/src/main/assembly/test.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>qa</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${project.basedir}/src/main/assembly/qa.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>production</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${project.basedir}/src/main/assembly/production.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
Результатом является создание трех разных файлов war, которые можно отличить по их соответствующему классификатору с помощью одного вызова (подробное описание можно прочитать здесь):
mvn clean package
Комментарии:
1. Спасибо за ваш ответ. Плагин сборки можно использовать для создания файлов war, так как его можно использовать для создания zip, dir, tar.gz и другие форматы. Я склонен использовать его помимо плагина war, потому что мне нужен точный контроль над процессом сборки и окончательным содержимым war. Другим вариантом было бы использовать war oyerlays, но, к сожалению, у меня это не сработало, потому что все содержимое зависимой войны за пределами Web-inf / classes опущено, т. Е. теряется во время распаковки зависимых войн. Возможно, я чего-то не хватает
2. Если он не предназначен для создания war, то почему он предоставляет это в качестве поддерживаемого формата?
3. Если вы хотите создавать разные войны для разных серверов приложений, как вы могли бы достичь этого с помощью maven-war-plugin?
4. @ChristopherHunt Формат — это более или менее только расширение файла, а не формат на самом деле. Потому что, если вы хотите создать файл war, вам нужно создать определенную папку / файловую структуру. Вы можете создать zip-файл с тем же содержимым и просто переименовать zip-файл в war. Вот и все.