I have the following profiles in my parent pom
<profile>
<id>P1</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>P2</id>
<activation>
<file>
<exists>${project.basedir}/src/main/whatever</exists>
</file>
</activation>
</profile>
Why P1 is active in child POM and P2 isn't?
The directory ${project.basedir}/src/main/whatever
, does not exist in the parent project, but exists in the child one.
Profile P2
is not activated because the path under its exists
tag does not resolve to an existing path even though the directory ${project.basedir}/src/main/whatever
exists. If you rewrite the property ${project.basedir}
as ${basedir}
, it should activate the P2
profile.
That should mean that the ${project.basedir}
does not resolve to the project base directory as it should. The help:effective-pom
shows that it does, though. I have reported this (MNG-5516).
Also I think that P1 will not be active if P2 is.
That is correct. Quoting the documentation for activeByDefault
:
This profile (P1 in this example) will automatically be active for all builds unless another profile in the same POM is activated using one of the previously described methods. All profiles that are active by default are automatically deactivated when a profile in the POM is activated on the command line or through its activation config.
The word inherit got me confused, because the "profile inheritance" works in project aggregation but not in project inheritance.
To make things clear, I simulated this situation. Empty pom means that it is empty except for the standard model, group, artifact and version tags.
Directory structure:
simple
\-pom.xml
pom content:
<profiles>
<profile>
<id>P1</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>P2</id>
<activation>
<file>
<exists>${basedir}/dir/</exists>
</file>
</activation>
</profile>
</profiles>
If there is no dir
directory mvn help:all-profiles
outputs:
Profile Id: P1 (Active: true , Source: pom)
Profile Id: P2 (Active: false , Source: pom)
If there is dir
directory mvn help:all-profiles
outputs:
Profile Id: P2 (Active: true , Source: pom)
Profile Id: P1 (Active: false , Source: pom)
Directory structure:
inheritance
|--child
| \-pom.xml // child pom
\-pom.xml // parent pom
Child pom is empty while parent pom has the profiles as in the simple scenario. Regardless of the existence of the inheritance/child/dir
directory running mvn help:all-profiles
from child
directory outputs:
Profile Id: P1 (Active: false , Source: pom)
Profile Id: P2 (Active: false , Source: pom)
When running mvn help:effective-pom
from child
directory it shows that the profiles are indeed not inherited. It behaves as documented:
Elements in the POM that are merged are the following:
- dependencies
- developers and contributors
- plugin lists (including reports)
- plugin executions with matching ids
- plugin configuration
- resources
No profiles are mentioned here.
Directory structure:
aggregation
|--module
| \-pom.xml // module pom
\-pom.xml // aggregator pom
Module pom is empty while aggregator pom has the profiles as in the simple scenario. If there is no aggregation/module/dir
directory running mvn help:all-profiles
from module
directory outputs:
Profile Id: P1 (Active: true , Source: pom)
Profile Id: P2 (Active: false , Source: pom)
If there is aggregation/module/dir
directory running mvn help:all-profiles
from module
directory outputs:
Profile Id: P2 (Active: true , Source: pom)
Profile Id: P1 (Active: false , Source: pom)
When running mvn help:effective-pom
from module
directory it shows that the profiles are inherited. This is not explicitly documented:
Project inheritance
If you have several Maven projects, and they all have similar configurations, you can refactor your projects by pulling out those similar configurations and making a parent project. Thus, all you have to do is to let your Maven projects inherit that parent project, and those configurations would then be applied to all of them.
Notes:
inheritance
directory will run only parent build.Project aggregation
And if you have a group of projects that are built or processed together, you can create a parent project and have that parent project declare those projects as its modules. By doing so, you'd only have to build the parent and the rest will follow.
Notes:
aggregation
directory will run the build of each module and the aggregator (the actual order is determined by maven based on different criteria).Profiles can be defined globally, per user or per project. Since the aggregated projects are built together (in the same build) some sort of profile resolution must be run to calculate the active ones. So this is the confusing part:
This was tested this using Maven 3.1.0. and 3.0.5.
The problem is not with inheritance but with interpolation (i.e. which values are supported for ${...}
): file-based profile activation only supports limited interpolation: see http://maven.apache.org/pom.html#Activation
So ${project.basedir}
isn't supported but only ${basedir}
(and system properties).
For more details, you can have a look at the model building algorithm: http://maven.apache.org/ref/3.2.1/maven-model-builder/
Full model interpolation happens after profile activation: so even if your effective pom shows interpolated value for ${project.basedir}
, the value isn't calculated when profile activation happens.
In Maven 3.2.2, there are multiple enhancements regarding this: documentation in http://jira.codehaus.org/browse/MNG-5590, warning at runtime in http://jira.codehaus.org/browse/MNG-5608 and better effective pom result http://jira.codehaus.org/browse/MNG-5612
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With