Inherited profiles in Maven

I have the following profiles in my parent folder

<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 is P1 active in the child POM, but P2 not?

The directory ${project.basedir}/src/main/whatever does not exist in the parent project, but exists in the child.

+6
source share
5 answers

The P2 profile is not activated because the path under its exists tag does not allow the existing path, even if the directory ${project.basedir}/src/main/whatever exists. If you rewrite the property ${project.basedir} as ${basedir} , it should activate the P2 profile.

This should mean that ${project.basedir} does not resolve the project’s base directory, as it should . However, help:effective-pom shows that it does. I reported this ( MNG-5516 ).

Also I think that P1 will not be active if P2.

It is right. Quoting documentation for activeByDefault :

This profile (P1 in this example) will be automatically active for all assemblies if another profile in the same POM is not activated using one of the previously described methods. All profiles that are active by default are automatically deactivated when a profile in POM is activated on the command line or through the activation configuration.

Inheritance inheritance confused me because "profile inheritance" works in project aggregation , but not in project inheritance .

To make everything clear, I simulated this situation. Empty pom means that it is empty, with the exception of the standard model, group, artifact, and version tags.

Simple script

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 exits:

 Profile Id: P1 (Active: true , Source: pom) Profile Id: P2 (Active: false , Source: pom) 

If dir exists, the mvn help:all-profiles directory mvn help:all-profiles returns:

 Profile Id: P2 (Active: true , Source: pom) Profile Id: P1 (Active: false , Source: pom) 

Project Inheritance

Directory structure:

 inheritance |--child | \-pom.xml // child pom \-pom.xml // parent pom 

The child pom is empty, and the parent pom has profiles as in a simple scenario. Regardless of the existence of the inheritance/child/dir directory working with mvn help:all-profiles from the child directory:

 Profile Id: P1 (Active: false , Source: pom) Profile Id: P2 (Active: false , Source: pom) 

When you start the mvn help:effective-pom directory from child it shows that profiles are not really inherited. It behaves as documented :

The elements of the combined POM are as follows:

  • dependencies
  • developers and contributors
  • plugin lists (including reports)
  • execution of plugins with corresponding identifiers
  • Resources

There are no profiles here.

Project aggregation

Directory structure:

 aggregation |--module | \-pom.xml // module pom \-pom.xml // aggregator pom 

The pom module is empty, and the pom aggregator has profiles as in a simple scenario. If the aggregation/module/dir directory does not work mvn help:all-profiles from module :

 Profile Id: P1 (Active: true , Source: pom) Profile Id: P2 (Active: false , Source: pom) 

If the aggregation/module/dir directory exists with the mvn help:all-profiles directory from the module directory:

 Profile Id: P2 (Active: true , Source: pom) Profile Id: P1 (Active: false , Source: pom) 

When you start the mvn help:effective-pom directory from module 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 reorganize your projects by pulling out these similar configurations and creating a parent project. Thus, all you have to do is let your Maven projects inherit this parent project, and these configurations will be applied to all of them.

Notes:

  • This does not apply to profiles as shown.
  • Runnnig a maven build from the inheritance directory will only run the parent assembly.

Project aggregation

And if you have a group of projects that are created or processed together, you can create a parent project and create this parent project as your modules. By doing so, you only need to create the parent element, and the rest will follow.

Notes:

  • Runnnig a maven build from the aggregation directory will run the assembly of each module and aggregator (the actual order is determined by maven based on different criteria).

Conclusion

Profiles can be defined globally for each user or for each project. Since aggregated projects are built together (in the same assembly), you need to run a specific profile resolution to calculate active ones. So this is the confusing part:

  • When projects are inherited, profiles not inherited from the parent pom to child pom.
  • When projects are aggregated profiles , inherited from the pom aggregator to the pom module.

This has been verified using Maven 3.1.0. and 3.0.5.

+12
source

Just to clarify this, Maven Profiles are actually inherited. For a link to another SO question, see: Inheriting Maven profiles . I have successfully inherited profiles in my project and does not require additional work.

As for the original question, you have a variable defined in the exist element. According to the documentation :

Starting with Maven 2.0.9, and tags can be interpolated. Supported variables are system properties such as $ {user.home} and environment variables such as $ {env.HOME}. please note that the properties and values ​​defined in the POM itself are not available for interpolation here, for example. the activator described above cannot use $ {project.build.directory}, but you need to hard-code the target path.

So, I get from this that $ {project.basedir} cannot be used and will not work. If, however, it is defined as an environment variable, it will work.

One caveat I discovered is that in the parent pom <plugin-management> should be used to configure plugins . However, as part of the profiles, I found that <plugin-management> should not be used for the profile-specific configuration to work.

+8
source

The problem is not with inheritance , but with interpolation (that is, what values ​​are supported for ${...} ): file-based profile activation supports only limited interpolation: see http://maven.apache.org/pom.html #Activation

So ${project.basedir} not supported, but only ${basedir} (and system properties).

For more information, you can take a look at the model building algorithm: http://maven.apache.org/ref/3.2.1/maven-model-builder/

Interpolation of the full model occurs after the profile is activated: so even if your effective pom shows the interpolated value for ${project.basedir} , the value is not calculated when the profile is activated.

Maven 3.2.2 has several improvements regarding this: documentation at http://jira.codehaus.org/browse/MNG-5590 , a run-time warning at http://jira.codehaus.org/browse/MNG-5608 and best effective pom result http://jira.codehaus.org/browse/MNG-5612

+4
source

In general, Maven profiles are not inherited (see http://jira.codehaus.org/browse/MNG-5127 for a discussion and links to blog posts that may be useful). I had success doing something like this:

 <!-- Parent --> <profile> <id>P2</id> <activation> <file> <exists>${project.basedir}/src/main/whatever</exists> </file> </activation> <!-- all the things you want to define for the child POMs --> </profile> <!-- Child --> <!-- Include only the activation block, which must match parent exactly --> <!-- Whatever is in the parent will be inherited --> <profile> <id>P2</id> <activation> <file> <exists>${project.basedir}/src/main/whatever</exists> </file> </activation> </profile> 

Also I think that P1 will not be active if P2. This is because <activeByDefault> true for P1. In my opinion, the name of the element is a little wrong. “Active by default” means “always active” when it really means “active only if no other profile is active in this POM”.

The above was discovered using Maven 3.0.x.

+1
source

Remove P2 from the second profile that has file-based activation.

 <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> 
0
source

Source: https://habr.com/ru/post/954049/


All Articles