Question

I would like to build two different versions of a WAR in Maven (I know that's a no-no, that's just the way it is given the current situation). In the version of a WAR depicted by an assembly, I want to replace a dependency by the same dependency with a different classifier. For example, I was expecting this assembly to work:

<assembly>
  <id>end-user</id>
  <formats>
    <format>war</format>
  </formats>
  <dependencySets>
    <dependencySet>
      <excludes>
        <exclude>group:artifact:jar:${project.version}</exclude>
      </excludes>
      <includes>
        <include>group:artifact:jar:${project.version}:end-user</include>
      </includes>
    </dependencySet>
  </dependencySets>
</assembly>

This doesn't work, but am I heading in the right direction? I've already read all the pages on the Maven assembly page and the section on the Maven Definitive Guide that seems relevant. Any pointers would be helpful.

Was it helpful?

Solution

Personally, I think that the cleanest solution would be to use two profiles (one of them depending on the artifact with the classifier, the other on the "regular" artifact). But you can indeed achieve what you want with a custom assembly. I just don't think you're heading in the right direction. Here is how I would do it...

First, create a specific project for the assembly and declare both the webapp and the artifact with the classifier as dependencies. Something like this:

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>artifact</artifactId>
      <version>${project.version}</version>
      <classifier>end-user<classifier>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>zewebapp</artifactId>
      <version>${project.version}</version>
      <type>war</type>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.2-beta-5</version>
        <configuration>
          <descriptors>
            <descriptor>src/main/assembly/end-user.xml</descriptor>
          </descriptors>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <!-- this is used for inheritance merges -->
            <phase>package</phase>
            <!-- append to the packaging phase. -->
            <goals>
              <goal>single</goal>
              <!-- goals == mojos -->
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Then, in your assembly descriptor:

<assembly>
  <id>end-user</id>
  <formats>
    <format>war</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <unpack>true</unpack>
      <unpackOptions>
        <excludes>
          <exclude>**/artifact-*.jar</exclude>
        </excludes>
      </unpackOptions>
      <includes>
        <include>*:war</include>
      </includes>
    </dependencySet>
    <dependencySet>
      <unpack>false</unpack>
      <outputDirectory>WEB-INF/lib</outputDirectory>
      <includes>
        <include>group:artifact:jar:*:end-user</include>
      </includes>
    </dependencySet>    
  </dependencySets>
</assembly>

Basically, this tells the assembly plugin to get the war for zewebapp and to unpack it but to exclude the unwanted artifact while unpacking. Then, the assembly plugin get the artifact with the classifier and place it in WEB-INF/lib (so we substitute it to the original). Finally, the whole thing is packaged as a war.

I tested this on a simplified example, it should work.

OTHER TIPS

The "version" information is not required when specifying artifact coordinates for includes/include*.

This should work:

<assembly>
  <id>end-user</id>
  <formats>
    <format>war</format>
  </formats>
  <dependencySets>
    <dependencySet>
      <includes>
        <include>group:artifact:jar:end-user</include>
      </includes>
    </dependencySet>
  </dependencySets>
</assembly>

I think the maven assembly documentation for the includes/include* section is incorrect. It says "Artifact coordinatess may be given in simple groupId:artifactId form, or they may be fully qualified in the form groupId:artifactId:type:version[:classifier]." However, from my testing, the "version" is not required. I got the hint from here.

Took me while to find out, thought might be useful to others in the future.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top