Build multiple artifacts with different classifiers at once

19,095

Solution 1

This can be done without profiles if you specify multiple plugin executions and resource filtering.

Create a properties file for each version in ${basedir}/src/main/filters (e.g. prod.properties, dev.properties) holding appropriate values for each environment.

Turn on filtering for your resources:

<resources>
  <resource>
    <directory>src/main/resources</directory>
    <filtering>true</filtering>
  </resource>
</resources>

Now add the resource plugin executions. Note the different filter file and output directory.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-resources-plugin</artifactId>
  <executions>
    <execution>
      <id>default-resources</id>
      <phase>process-resources</phase>
      <goals>
        <goal>resources</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.build.outputDirectory}/dev</outputDirectory>
        <filters>
          <filter>${basedir}/src/main/filters/dev.properties</filter>
        </filters>
      </configuration>
    </execution>
    <execution>
      <id>prod</id>
      <phase>process-resources</phase>
      <goals>
        <goal>resources</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.build.outputDirectory}/prod</outputDirectory>
        <filters>
          <filter>${basedir}/src/main/filters/prod.properties</filter>
        </filters>
      </configuration>
    </execution>
  </executions>
</plugin>

Finally, the jar plugin; note classifier and input directory:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <executions>
    <execution>
      <id>default-jar</id>
      <phase>package</phase>
      <goals>
        <goal>jar</goal>
      </goals>
      <configuration>
        <classifier>dev</classifier>
        <classesDirectory>${project.build.outputDirectory}/dev</classesDirectory>
      </configuration>
    </execution>
    <execution>
      <id>jar-prod</id>
      <phase>package</phase>
      <goals>
        <goal>jar</goal>
      </goals>
      <configuration>
        <classifier>prod</classifier>
        <classesDirectory>${project.build.outputDirectory}/prod</classesDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

Running mvn clean install should produce the properly filtered resources in artifacts with dev and prod classifiers like you want.

In the example, I used execution IDs of default-resources and default-jar for the dev versions. Without this you would also get an unclassified jar artifact when you build.

Solution 2

Just an FYI - put the version number in there to make sure you have the version supporting custom filters. In maven 3 I set mine up like this for example. Without version it didn't work.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>2.6</version>
    ...
</plugin>
Share:
19,095

Related videos on Youtube

Piotr Gwiazda
Author by

Piotr Gwiazda

Cloud (Azure, GCP) Senior Solution Architect. Comes from Java world.

Updated on September 14, 2022

Comments

  • Piotr Gwiazda
    Piotr Gwiazda over 1 year

    W want my maven project to produce three artifacts with different classifiers at once. I know that I can produce it with modules etc. This is actually a resources project that I want to produce configuration for DEV, STAGE and PROD environment.

    What I want to have is to run mvn:install once and have my.group:resources:1.0:dev, my.group:resources:1.0:stage and my.group:resources:1.0:prod in my repo.

  • Christian Vielma
    Christian Vielma about 11 years
    In the packages are included prod.properties and dev.properties, how do I do if I want both jar files to have the same, let's say, config.properties?
  • user944849
    user944849 about 11 years
    @ChristianVielma, are you asking about including config.properties in your jars or using config.properties as filters for both jars?
  • Christian Vielma
    Christian Vielma about 11 years
    I mean what if I have a config-dev.properties and a config-prod.properties, how do I do to have only one config.properties in each of the generated jars. Do I explain myself?
  • user944849
    user944849 about 11 years
    In my answer, the prod.props and dev.props files are filters, not configuration. You could put config.properties in /src/main/resources, values in there would be filled in during the filtering, and you end up with one file in the final artifact. If this isn't quite enough, you should probably ask a separate question describing what you want to do in more detail.
  • Christian Vielma
    Christian Vielma about 11 years
    This doesn't includes the libraries. And in my case it didn't even include the classes of my application.
  • user944849
    user944849 about 11 years
    Please note that the original question specifically mentioned a resources project; the OP's intent was to create classified jars containing resources specific to a particular environment, not classes, libs, etc. The answer satisfies the given requirement. Adapt the pattern to fit your requirements if they are different. Or consider writing a custom plugin.
  • Sergey Ponomarev
    Sergey Ponomarev almost 9 years
    Here is simialr solution, but for WARs jayway.com/2010/01/21/…