Maven assembly plugin produces undeployable war file

I'm working on a multi module project using Spring, Hibernate, GWT and Maven 3 and try to deploy a war-file distribution to a servlet container (preferably Tomcat 7 or Jetty 8). I create the war-file using maven-assembly-plugin 2.2.1 (I'm running maven 3). During the maven build everything works perfectly and the distribution archive is created.

But when I try to deploy the war file, I get ClassNotFound-Exceptions (eg Spring ContextLoaderListener and the like) although everything is in place (Web-inf/lib etc. pp.). So, the webapp isn't starting. Then I unpack the war-file into the servlet containers webapp directory and everything is working fine... ??

After further investigation I came across the following thing: If I take an arbitrary war file A' created by maven-war-plugin (!), replace its content with the unpacked content from the war file I created using maven-assembly-plugin (let me call it A.) I can see two things happen:

  • the resulting war file A' is a few bytes smaller than my original file A although their content is identical
  • the deployment of A' suddenly works like a charm
  • This is weird and I have absolutely no idea what's happening. Maybe there is an issue and maven-war-plugin and maven-assembly-plugin handle war file packaging differently?! I mean, a war is only a renamed zip file with some predefined structure... Maybe it has absolutely nothing to do with maven but with file encoding or other things? Any ideas on this? I appreciate any hint, that could help me in investigating this...

    This is my assembly descriptor

    <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>
    


    The maven-assembly-plugin is not intended to create a war. For this purpose use the maven-war-plugin instead.

    If you need to create war files for different environments like test,qa, production. This can be used as well a base for different app servers. But if we are talking about a application server this means we should create ear files instead of war files (This means to use maven-ear-plugin instead of maven-war-plugin).

    |-- pom.xml
    `-- src
        |-- main
        |   |-- java
        |   |-- resources
        |   |-- environment
        |   |   |-- test
        |   |   |   `-- database.properties
        |   |   |-- qa
        |   |   |   `-- database.properties
        |   |   `-- production
        |   |       `-- database.properties
        |   `-- webapp
    

    You need the following assembly for that (for every environment) which can be created based on this as a template:

    <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>
    

    To support different artifacts for different environments this is the time for the maven-assembly-plugin like this:

        <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>
    

    The result is creating three different war files which can be distinguished by their appropriate classifier with a single call (detailed description can be read here):

    mvn clean package
    
    链接地址: http://www.djcxy.com/p/29610.html

    上一篇: Maven程序集插件在编译阶段不会覆盖文件

    下一篇: Maven程序集插件会生成不可部署的war文件