Maven - Profile&Modules - Activation by property? - maven

Could someone help me understand this issue below? Approach #1 below works as expected, when the IDE asks maven to build the project it rebuilds moduleA and include it as a dependency; everybody happy. Approach #2 which is what I want to use does not behave the same way, myProperty is a system property I've defined and toggling it between true/false does activate the profile BUT it does not build moduleA, why?
#1
...
<profiles>
<profile>
<id>testProfile</id>
<activation>
<activationByDefault>true</activationByDefault>
</activation>
</profile>
<modules>
<module>../moduleA</module>
</modules>
</profiles>
...
#2
...
<profiles>
<profile>
<id>testProfile</id>
<activation>
<property>
<name>myProperty</name>
<value>true</value>
</property>
</activation>
</profile>
<modules>
<module>../moduleA</module>
</modules>
</profiles>
...

Oh, after hours up and down the documentation I found my problem. Was not aware that the name of the config file mattered, so I had named it jvm.config as I saw the bash script looked after such a file for maven options. Apparently it was supposed to be in maven.config

Related

Activating a Child Profile from a Parent Profile

I have the following parent pom.xml file:
<profile>
<id>build_full</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>mymodule_interface</module>
<module>mymodule_switch</module>
<module>mymodule_switch_simulator</module>
<module>mymodule_switch_controller</module>
<module>mymodule_server</module>
</modules>
</profile>
and in my child pom for mymodule_server, I have the following:
<profile>
<id>subprofile</id>
<modules>
<module>...various modules...</module>
</modules>
</profile>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>...various modules...</module>
</modules>
</profile>
How, when I invoke maven: mvn -P build_full, can I force the child module (mymodule_server) to use profile subprofile rather than default?
No, you can't activate a child profile from a parent profile. More generally, you can't activate or deactivate any profile from any other profile (there is a JIRA feature-request MNG-3309). What you can do is activate two profiles based on the same property.
First of all, using a profile that is activated by default is generally not a good idea. What you want is to activate a profile based on some condition (OS version, system property...). To solve your problem, you can activate build_full profile when a certain system property is present, and make sure that subprofile is also activated when that same property is present.
A sample configuration would be the following, where both profiles are activated when the fullBuild system property is set to true. Invoking Maven with mvn -DfullBuild=true ... will thus activate both profiles.
<profile>
<id>build_full</id>
<activation>
<property>
<name>fullBuild</name>
<value>true</value>
</property>
</activation>
<modules>
<module>mymodule_interface</module>
<module>mymodule_switch</module>
<module>mymodule_switch_simulator</module>
<module>mymodule_switch_controller</module>
<module>mymodule_server</module>
</modules>
</profile>
<profile>
<id>subprofile</id>
<activation>
<property>
<name>fullBuild</name>
<value>true</value>
</property>
</activation>
<modules>
<module>...various modules...</module>
</modules>
</profile>
In your case, from the top parent/aggregator folder, you could just run:
mvn clean install -Pbuild_full,!default,subprofile
It will disable any profile having name default (and hence disable the profile in the concerned sub-module) and enable any profile having name subprofile (and hence enable the profile you wanted).
Alternatively, you could configure subprofile as such:
<profiles>
<profile>
<id>subprofile</id>
<activation>
<property>
<name>subprofile</name>
<value>true</value>
</property>
</activation>
....
and then run as following:
mvn clean install -Dsubprofile=true -Pbuild_full
It will have the same effect. You can even avoid the value element and simply specify -Dsubprofile, its existence would be enough to activate the profile (in that case a more meaningful name is suggested, like -DactivateSubprofile). Since you active a different profile, automatically Maven will deactivate the default one.

Using profiles to control which Maven modules are built

I have the following XML in my maven POM.xml:
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>default</name>
<value>!disabled</value>
</property>
</activation>
<modules>
<module>m1</module>
<module>m2</module>
<module>m3</module>
</modules>
</profile>
<profile>
<id>x</id>
<modules>
<module>m1</module>
</modules>
</profile>
</profiles>
What I'm trying to achieve is this:
When I run mvn install, I want it to build m1, m2 and m3 projects.
When I run mvn install -Px, I want it to only build m1.
My current problem is that with the code above, option 2 builds all m1, m2 and m3.
Found the solution guys, define 'x' profile first and the 'default' and it works fine (insane Maven!!). Here's the final result:
<profiles>
<!-- DO NOT CHANGE THE *ORDER* IN WHICH THESE PROFILES ARE DEFINED! -->
<profile>
<id>x</id>
<modules>
<module>m1</module>
</modules>
</profile>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>m1</module>
<module>m2</module>
<module>m3</module>
</modules>
</profile>
</profiles>
You can disable maven profiles that have runByDefault set to true from the command line like so:
mvn install -P !default
Note, this requires Maven version 2.0.10.
Just add a space after -P the sintax of the command is
mvn install -P x
And not like you are using
mvn install -Px
Take a look at Maven - Introduction to profiles

In Maven, can a profile override the modules (to not include any)

In maven, once you define your modules in you pom.xml all profiles aggregate the modules defined in them: (relevant part only)
<project>
<modules>
<module>module1</module>
</modules>
<profiles>
<profile>
<id>pr1</id>
<modules>
<moudule>module2</module>
</modules>
If you perform a mvn clean it will pass the command to module1.
If you issue mvn clean -Ppr1 it will pass along to module1 and module2.
I wonder if in maven 3 it is possible to have a pom.xml with submodules and override this. I mean to execute a profile that instead of add their own modules to the build force those like:
<project>
<!-- omitted -->
<modules>
<!-- modules -->
</modules>
<build>
<!-- build -->
</build>
<profiles>
<profile>
<!-- This profile with no modules -->
</profile>
</profiles>
</project>
The requirement might sound silly, but I just want to know if there is a mechanism like in plugin configuration.
<configuration self.combine="override"
Regards!
ssedano
It's not possible. Profile configuration is always merged with main configuration, so you only can add modules in your case.
What you can do instead, however, is to create a some kind of "default" profile (by <activeByDefault>true</activeByDefault> in <activation> section) that is enabled when no other profiles are invoked and put your default modules' list there. Then, when no profile is specified on Maven build call, this "default" profile is used, but when you call explicitly at least one profile, it's not, so you can this way define modules' list from scratch.
While the question is old, Google still ranks it highly, so it makes sense to add a new answer.
You can use the activation by absence of a property trick to achieve what you want.
<profiles>
<!-- By default, include the modules -->
<profile>
<id>full-build</id>
<activation>
<!-- Activation by absence of a property. Run normally, without -Dskip-modules -->
<property>
<name>!skip-modules</name>
</property>
</activation>
<modules>
<module>module1</module>
<module>module2</module>
<module>module3</module>
</modules>
</profile>
<!-- No-modules build -->
<profile>
<id>no-modules</id>
<activation>
<!-- Activation by a property. Run with -Dskip-modules to activate -->
<property>
<name>skip-modules</name>
</property>
</activation>
<modules>
</modules>
</profile>
</profiles>
You can do things like this:
<profiles>
<profile>
<id>run-xyz</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>www-ab</module>
<module>www-cd</module>
</modules>
</profile>
<profile>
<id>run-its</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<modules>
<module>www-db</module>
<module>www-it</module>
</modules>
</profile>
</profiles>
If you are talking about such things. But i would recommend to be very carefull about such things.
It's only the question how you set activeByDefault. With this it's possible to create more or less any combination.

Confused that order matters when defining conditional profiles in maven

I have a configurable property line.ending that I used during the assembly phase of the building of my project to specify the line ending type of my application property files. For that I have created two profiles LF_DOS and LF_UNIX, so that when I launch :
mvn install
or
mvn install -P LF_DOS
line.ending equals 'dos', and when I launch :
mvn install -P LF_UNIX
line.ending equals 'unix'.
My first attempt to do this was simply :
<profile>
<id>LF_UNIX</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<line.ending>unix</line.ending>
</properties>
</profile>
<profile>
<id>LF_DOS</id>
<activation>
<property>
<name>!line.ending</name>
</property>
</activation>
<properties>
<line.ending>dos</line.ending>
</properties>
</profile>
Unfortunately, this always gave me line.ending=dos, whatever LF_UNIX is set or not. Weird... But, the more confusing to me, is that I solved the problem just by changing the profile declaration order, like this :
<profile>
<id>LF_DOS</id>
<activation>
<property>
<name>!line.ending</name>
</property>
</activation>
<properties>
<line.ending>dos</line.ending>
</properties>
</profile>
<profile>
<id>LF_UNIX</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<line.ending>unix</line.ending>
</properties>
</profile>
This works exactly like I want.
My questions is : is this a bug ? Or is it something to know about maven profiles, a kind of limitation that makes profiles order declaration particularly matter in such a case ?
The confusion lies in your understanding of how profile activation works.
You think that this:
<activation>
<property>
<name>!line.ending</name>
</property>
</activation>
means if I don't have a maven property named "line.ending" set, activate this profile. What it really means if I didn't specify -Dline.ending=X on the command line, activate this profile. So unless you run something like this:
mvn clean install -Dline.ending=unix
You are activating this profile and thus having the value set to dos.

Maven: Only activate profile A if profile B is not activated?

I have two Maven profiles profile-A and profile-B. "B" should only be activated if "A" is not activated.
So if I would call
mvn install
profile-B is executed (but not profile-A).
But if I would call
mvn install -Pprofile-A
then only profile-A is executed (but not profile-B).
Any hints how I need to write my pom.xml to achieve this?
I already tried this, but it doesn't work:
<profiles>
<profile>
<id>profile-A</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
...
</profile>
<profile>
<id>profile-B</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>!profile-A</name>
</property>
...
</activation>
...
</profile>
</profiles>
I think for your example command line to work as expected, all you need is the <activeByDefault>true</activeByDefault> for profile B.
http://maven.apache.org/guides/introduction/introduction-to-profiles.html states:
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.

Resources