42

I need to modify the maven build for a large project to skip certain steps during typical development builds (i.e. don't build the *-source.jar files). I've searched for "conditional execution" for maven, but haven't found anything.

A dev profile sounds like the intuitive way to do this - but I don't know how intuitive maven is. The docs for profiles show how to set different properties (i.e. database connection parameters) for different profiles. I suppose I could set a property and then test if that property is set in the maven-source-plugin - executions - execution tag.

Is this the right way to do conditional execution in maven?

What's the "right" way to do this in maven?

3 Answers 3

54

You're thinking about it a bit backwards: have the profile enable the behaviour, not disable it. This is just what profiles are best at, and is exactly your case: you only want the steps to be run in certain circumstances. So you might have something like:

<profile>
  <id>source-jars</id>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        ...

And in fact there's an example just like this on the maven-source-plugin usage page. When you need to generates your artifact, use mvn -P source-jars (or whatever). That's it! If you only need to do this at release time, the release plugin even offers a way to define the profiles to use right in the release plugin configuration.

5
  • Our poms are written where maven-source-plugin runs by default so I'll have to restructure them as you suggest. Commented Jan 14, 2011 at 16:33
  • 4
    There are many cases where plugins are desirable to have on by default and disabled by using a profile. I think this answer avoids the problem without solving it.
    – Kevin
    Commented Feb 10, 2014 at 2:25
  • 1
    @Mowgli But the maven profile system is not well-suited to that: there is only an "activation" mechanism, not a "deactivation" mechanism. Some plugins handle this by building a deactivation mechanism of their own (e.g. skipTests for surefire plugin). Commented Feb 11, 2014 at 18:13
  • 1
    This is Maven Disease in a nutshell. "No, you actually don't want a conditional build, you really want this upside-down thing over here that requires you to retool your entire build system! See, isn't that awesome?" Nothing against the answer, mind you, I +1'ed it.
    – wberry
    Commented Jul 1, 2016 at 20:28
  • @wberry eh, maybe. As I said above, the maven profile system is fine for conditional builds ... by conditionally enabling stuff. If you want to conditionally enable and disable stuff, I suspect your build system is going to require increased maintenance effort over time. These days, most objections to maven sound to me like, "I want to create my own build system!" But thanks for the +1 :) Commented Jul 5, 2016 at 21:22
14

You can achieve your actual goal of enabling the source-jars plugin by default by adding two profiles to your POM. The Maven profiles documentation notes that you can add an element <activeByDefault>true</activeByDefault> to the activation section and states that

This profile will automatically be active for all builds unless another profile in the same POM is activated using one of the previously described methods

So, you can add two profiles, one of which is activeByDefault, which includes the relevant plugin, and another, which can be activated in any of the standard ways (such as -P from the command line) to prevent the default profile from running. The profiles section in your pom.xml (or Maven settings or whatever) might therefore look like this:

<profile>
  <id>source-jars</id>
  <activation>
    <activeByDefault>true</activeByDefault>
  </activation>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        ...
      </plugin>
    </plugins>
  </build>
</profile>
<profile>
   <!-- active this profile to disable the source-jars plugin -->
   <id>no-optional-plugins</id>
</profile>

Unfortunately, I can't see a way to make this method scale well for controlling multiple plugins – I think you need O(n^2) profiles for n plugins, but for this simple case it should work fine.

Another possibly simpler option with Maven ≥ 2.0.10 is to just have the source-jars profile from above (still activeByDefault), and to manually deactivate the profile when you want by prefixing the profile ID with - or ! after -P CLI flag:

$ mvn -P !source-jars

This method doesn't have the same O(n^2) problems with multiple plugins but it is also less flexible, since the deactivation can't be triggered by a system property, environment variable, JDK version etc.

0
0

There is always the trick of involving system props so for instance you may have, like I do, a gui maven module with java and react/javscript/npm/-gui-code. If my pom.xml looks like

  <profile>
  <id>ui</id>
  <activation>
    <activeByDefault>true</activeByDefault>
    <!-- Only build the UI if the skipUI system prop is not set -->
    <property>
      <name>!skipUI</name>
    </property>
  </activation>
  <build>
    <plugins>
      <plugin>
      ..

then I can build it like

# mvn clean install

which will build the whole thing yet

# mvn -DskipUI clean install

will skip this part so I don't always have to wait two thousand years for the npm stuff for instance in my case - obviously not a solution 'just by profiles', the accepted answer describes this functionality. Yet if you can inject system props, this is what I usually do.

Also, maybe this is self explanatory but anyway, if you structure your project so you have a main parent pom on top of your child modules, then in this pom.xml you can say things like

  <modules>
    <module>apa</module>
    <module>bepa</module>
    <module>cepa</module>
    ..
  </modules>
  
  <profiles>
    <profile>
      <id>additions</id>
      <activation>
        <activeByDefault>false</activeByDefault>
      </activation>
      <modules>
        <module>epa</module>
        <module>fepa</module>
        ..
      </modules>
    </profile>
    ..

meaning that apa, bepa, cepa and the others in the 'main' modules section will always be built but if you provide the additions profile, then and only then epa and fepa will also be built.

Not the answer you're looking for? Browse other questions tagged or ask your own question.