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.
classifier: The classifier distinguishes artifacts that were built from the same POM but differ in content. It is some optional and arbitrary string that - if present - is appended to the artifact name just after the version number.
So in order for you to customize the way the Assembly Plugin creates your assemblies, you need to know how to use the Assembly Descriptor. This descriptor specifies the type of assembly archive to create, the contents of the assembly, and the ways in which dependencies or its modules are bundled with an assembly.
A list of references to assembly descriptors available on the plugin's classpath. The default classpath includes these built-in descriptors: bin , jar-with-dependencies , src , and project .
The Assembly Plugin for Maven enables developers to combine project output into a single distributable archive that also contains dependencies, modules, site documentation, and other files. Your project can easily build distribution "assemblies" using one of the prefabricated assembly descriptors.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With