Tag Archives: workaround

Maven: activation conditions really DON’T work as advertised

Many people using the Maven build system want to conditionally trigger parts of the build:   say, add a .dll only when on Windows, or add a library only when some file is missing.

This is why Maven profiles exist. Profile activation conditions are the mechanism for turning on a profile based on conditions like operating system and missing files. However, they work nearly opposite of how they are documented to work.

Despite all the examples in the official docs, profile activation conditions aren’t ANDed together, but ORed. For example, you might want to activate a profile when on Windows AND a file is missing.  You can’t:  the profile will activate if either condition is true.

This is true in version 3.0.2 and has been thus ever since Maven 2.1: you can see the bug ticket where someone “fixed” it the wrong way. This is an egregious flaw that makes activation conditions unusable for many common use cases.

Working Around It Using Groovy

One workaround is to dip into the Groovy scripting language to do multiple conditions.

In the Maven pom.xml sample below, you can see that I’m using a combination of profile activation (to test for the existence of a file) and Groovy conditionals (to test for the operating system). The profile activation isn’t necessary, really; I could have done the whole thing with Groovy conditions.

<profiles>
	<!-- a Maven profile that does something when a particular file is missing from the build -->
	<profile>
		<id>install-shared-resources</id>
		<activation>
			<file>
				<!-- Activate this profile when there's no src/main/some-file yet -->
				<missing>src/main/some-file</missing>
			</file>
		</activation>
		<build>
			<plugins>
				<!-- Use the Groovy scripting language detect the OS and do something OS-specific -->
				<plugin>
					<groupId>org.codehaus.mojo</groupId>
					<artifactId>groovy-maven-plugin</artifactId>
					<version>1.3</version>
					<executions>
						<execution>
							<phase>package</phase>
							<goals>
								<goal>execute</goal>
							</goals>
							<configuration>
								<source>
									// True for any POSIX compliant operating system such as AIX,
									// HP-UX, Irix, Linux, MacOSX, Solaris or SUN OS
									if (org.apache.commons.lang.SystemUtils.IS_OS_UNIX)
									{
										// do something like execute a shell script
									}
									// Else if Windows 7 or Vista
									else if (org.apache.commons.lang.SystemUtils.IS_OS_WINDOWS_VISTA ||
											 System.properties['os.name'].toLowerCase().contains('windows 7'))
									{
										// do something like execute a shell script
									}
									// Else it's an unsupported OS (in this case, like Windows XP)
									else
									{
										fail("\nYou're on an unsupported operating system: " + System.properties['os.name']);
									}
				        		</source>
							</configuration>
						</execution>
					</executions>
				</plugin>
			</plugins>
		</build>
	</profile>
</profiles>