Paul Lowry created MNG-5408:
-------------------------------
Summary: Explicit profile activation in pom.xml
Key: MNG-5408
URL: https://jira.codehaus.org/browse/MNG-5408
Project: Maven 2 & 3
Issue Type: Improvement
Components: Profiles
Affects Versions: 3.0.4
Reporter: Paul Lowry
+Background:+
Organisations should be able to define complex maven tasks, each involving
multiple plugin executions, in a way that is standardised for use in all
projects.
The obvious solution would seem to be profiles:
* They allow us to define maven project configuration and multiple plugin
executions
* They can be enabled/disabled, and they are not mutually exclusive, so we can
use them to run execution A or execution B of the same plugin, or A and then B,
or any other sequence (note: this sort of control is not available in
pluginManagement)
For example, consider an organisation where some project teams do integration
testing of war artifacts by running them in Jetty, whereas others use Tomcat.
Both scenarios require several plugins to run, and though the process is
similar it is not the same (for our example, let's assume that Jetty requires a
test context file, and Tomcat projects have a different naming scheme for their
test classes).
Using profiles in a root pom, which is the parent for all projects in the
organisation, we can make the process for running a war in Jetty/Tomcat quite
simple, and more importantly quite consistent:
{code:xml|title=root.pom.xml}
<project>
<profiles>
<!--
profile for running integration tests using jetty
-->
<profile>
<id>runJetty</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>runJetty.prep</id>
<phase>pre-integration-test</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>\${project.build.testOutputDirectory}/jetty</directory>
<filtering>true</filtering>
</resource>
</resources>
<outputDirectory>\${project.build.directory}/\${project.build.finalName}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<executions>
<execution>
<id>runJetty.start</id>
<phase>pre-integration-test</phase>
<!-- start server in jetty, using property
${runJetty.port} -->
</execution>
<execution>
<id>runJetty.stop</id>
<phase>post-integration-test</phase>
<!-- stop jetty -->
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<id>runJetty.test</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<!--
profile for running integration tests using tomcat
-->
<profile>
<id>runTomcat</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat6-maven-plugin</artifactId>
<executions>
<execution>
<id>runTomcat.start</id>
<phase>pre-integration-test</phase>
<!-- start server in tomcat, using property
${runTomcat.port} -->
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<id>runTomcat.test</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<includes>
<include>\${runTomcat.testPattern}</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
{code}
A war project, with the above as its parent, can be configured to start its
build artifact and run all integration tests, using Jetty or Tomcat as follows:
{noformat:title=project tested using Jetty}
<project>
<properties>
<runJetty.port>7070</runJetty.port>
</properties>
</project>
{noformat}
{noformat:title=the same project tested using Tomcat}
<project>
<properties>
<runTomcat.port>7070</runTomcat.port>
<runTomcat.testPattern>**/*AcceptanceTest.java</runTomcat.testPattern>
</properties>
</project>
{noformat}
Having defined these re-usable profiles, we then reach the question of how to
activate them automatically in the organisation's various war projects (since
the organisation's best practices demand that every build of a war project
should run integration tests).
Profiles can be activated by JDK version or OS, but these are not specific
enough conditions. They can also be activated by command line properties, but
these are too explicit - in this case we want our profile to run automatically.
The only other activation condition is for a file to exist; but we cannot look
in the target directory because profile activation is evaluated before the
build starts; nor can we reliably depend on 'src/main/webapp', since different
projects may arrange their sources differently, and some projects might want to
disable the profile.
+Problem:+
So we hit a problem, namely: A project should be able to activate a profile
explicitly; but the activation mechanisms provided out of the box are not
refined enough.
Several alternative ways have been suggested to activate profiles, such as
packaging type (http://jira.codehaus.org/browse/MNG-4154), artifactId/groupId
(http://jira.codehaus.org/browse/MNG-944), and pom properties. This last is
probably the most widely mentioned, and was even used as the example for a
custom profile activator feature, that was spiked in Maven 2.1 but never made
it into the product. See these links for details...
*
http://maven.40175.n5.nabble.com/Activating-a-profile-in-settings-xml-based-on-a-property-set-in-pom-xml-tp512562p512598.html
*
http://maven.40175.n5.nabble.com/profile-activation-based-on-property-properties-in-POM-tp88010p88011.html
* http://docs.codehaus.org/display/MAVEN/Custom+Profile+Activators
If pom properties could activate profiles, it would certainly work nicely for
the example above, in that developers could enable Jetty or Tomcat as follows:
{code:xml|title=root.pom.xml}
<project>
<profiles>
<profile>
<id>runJetty</id>
<activation>
<property>
<name>runJetty</name>
<value>true</value>
</property>
</activation>
...
</profile>
<profile>
<id>runTomcat</id>
<activation>
<property>
<name>runTomcat</name>
<value>true</value>
</property>
</activation>
...
</profile>
</profiles>
</project>
{code}
{noformat:title=project tested using Jetty}
<project>
<properties>
<runJetty>true</runJetty>
<runJetty.port>7070</runJetty.port>
</properties>
</project>
{noformat}
{noformat:title=the same project tested using Tomcat}
<project>
<properties>
<runTomcat>true</runTomcat>
<runTomcat.port>7070</runTomcat.port>
<runTomcat.testPattern>**/*AcceptanceTest.java</runTomcat.testPattern>
</properties>
</project>
{noformat}
However, none of these improvements (or similar) have ever been released.
It seems to me like I'm missing something. Maybe the Maven
developers/committers consider profiles an inappropriate way to configure
builds like the example above; or maybe it's just too costly to activate
profiles using info from the pom model.
+Summary:+
I'd like very much to understand why profiles cannot (or should not) be used in
scenarios like the one described above.
I'd also like to know if John Casey's custom profile activator might ever see
the light of day, or if there is some alternative solution on the roadmap for
Maven.
Thanks & Regards
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:
https://jira.codehaus.org/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira