Плагин сборки Maven создает не развертываемый файл войны

#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.), я вижу, что происходят две вещи:

  1. результирующий файл war A’ на несколько байт меньше моего исходного файла A, хотя их содержимое идентично
  2. развертывание ‘внезапно работает как шарм

Это странно, и я абсолютно понятия не имею, что происходит. Может быть, проблема в том, что 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. Вот и все.