The maven assembly plugin is an extremely powerful tool when it comes to creating custom distributions (aka assemblies) of your artifacts for individual platforms etc. However, the ability to create multiple variants of an artifact within a single build conflicts with the standard maven approach of using multiple build profiles and executing a single build for each profile to generate artifact variants.

This also means that mavens resource filtering is not very useful for individual assemblies, since you can only replace placeholders such as ${someValue} with the same value for all assemblies (since resources are only filtered once, using the active profile(s), for all assemblies).

You can, however, configure the maven assembly plugin to use individual filter property files for each assembly using the <execution> section of the plugin configuration, like so:

<plugin>
  <artifactId>maven-assembly-plugin</artifactId>

  <version>2.2-beta-5</version>
  <executions>
    <execution>
      <id>production</id>
      <goals>

        <goal>single</goal>
      </goals>
      <configuration>
        <filters>
          <filter>${project.basedir}/src/main/assembly/production.properties</filter>

        </filters>
        <finalName>${artifactId}-production-${version}</finalName>
        <ignoreDirFormatExtensions>true</ignoreDirFormatExtensions>
        <descriptors>
          <descriptor>src/main/assembly/assembly.xml</descriptor>

        </descriptors>
      </configuration>
      <phase>package</phase>
    </execution>
    <execution>

      <id>integration</id>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>

        <filters>
          <filter>${project.basedir}/src/main/assembly/integration.properties</filter>
        </filters>
        <finalName>${artifactId}-integration-${version}</finalName>
        <ignoreDirFormatExtensions>true</ignoreDirFormatExtensions>

        <descriptors>
          <descriptor>src/main/assembly/assembly.xml</descriptor>
        </descriptors>
      </configuration>
      <phase>package</phase>

    </execution>
  </executions>
</plugin>

This snippet uses the same assembly descriptor (you can use any assembly descriptor, actually) to build individual artifacts for production and integration. Note that the ${project.basedir}/ prefix is a workaround for MASSEMBLY-150 and is nedded to avoid a nasty Failed to create assembly: Error filtering file ... Error loading property file 'src/main/...' error when executing the mojo from outside the module directory (say, for instance, in a mvn release:prepare…).

Filtering must be enabled in the assembly descriptor, like so:

<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/xsd/assembly"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://maven.apache.org/xsd/assembly http://maven.apache.org/xsd/assembly-1.1.1.xsd">
  ...
  <fileSets>
    <fileSet>
      <filtered>true</filtered>
      ...
    </fileSet>

  </fileSets>
</assembly>

Thanks to John Casey for suggesting this in MASSEMBLY-430!

Share →

2 Responses to Per-assembly filtering with the maven-assembly-plugin

  1. Holger says:

    Hi Olaf,

    thanks for this hint!
    Using a property for the assembly-Id even eliminates the need for specifying finalName, and the artifact is properly installed afterwords.

    ${assemblyId}

    Best regards,
    Holger

  2. Georgi says:

    Thanks mate! This is exactly I’ve been searching for!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>