Can a Maven profile enable/disable another profile from its definition? - maven

Given two profiles A and B, is it possible to specify something within profile A definition that would enable or disable profile B?

This is not possible to activate / deactivate a profile from another profile. Maven needs to know the list of active profiles before building the model.
There are a couple of work-arounds depending on your use-case:
Set one profile to activeByDefault: it will be automatically deactivated
when another profile is activated.
Use a custom property so that one profile is activated by the presence of the property and the other profile is deactivated by the presence of the property. Sample configuration would look like:
<profile>
<id>profileA</id>
<activation>
<property>
<name>somename</name>
</property>
</activation>
</profile>
<profile>
<id>profileB</id>
<activation>
<property>
<name>!somename</name>
</property>
</activation>
</profile>
Thus, if you invoke Maven with -Dsomename, profileA will be activated; otherwise profileB will be activated.

Related

How do I use cucumber profile to dynamically use different environment hostname, testdata, testGroup. I am using cucumber, java, maven

I have test cases written in feature files. The test cases are tagged per requirements.
I want these test cases to be executed on different environments, using maven command, by passing profile name.
Each profile will have hostname, username, password for particular environment.
How do I achieve this?
#stage_ready
Feature: GUI Tests
Background:
Given the site <hostname> is reached using "Chrome" browser
When maximize window
And credentials <user_host> is typed into the "sd_username_editbox"
And credentials <password_host> is typed into the "sd_password_editbox"
And the "sd_login_button" button is clicked
CommandLine:
mvn test -Dcucumber.options=”–tags #stage_ready” -p profile_name
I want to know how to write profile, which will have parameters like hostname, user_host, password_host for different profiles and be dynamically used in the cucumber steps, that I have marked in angle brackets for reference.
From the Cucumber documentation:
"Profiles are not available in Java."
If you want to pass arguments to Maven, you can use Maven profiles
For example (from the Maven link above):
<project>
...
<profiles>
<profile>
<id>appserverConfig-dev</id>
<activation>
<property>
<name>env</name>
<value>dev</value>
</property>
</activation>
<properties>
<appserver.home>/path/to/dev/appserver</appserver.home>
</properties>
</profile>
<profile>
<id>appserverConfig-dev-2</id>
<activation>
<property>
<name>env</name>
<value>dev-2</value>
</property>
</activation>
<properties>
<appserver.home>/path/to/another/dev/appserver2</appserver.home>
</properties>
</profile>
</profiles>
..
</project>

Maven - Is it possible to build a project specifying multiple profiles simultaneously?

We are developing a Maven archetype for applications that only consume web services. This archetype offers three profiles, one for each environment (dev, pre, pro).
The point is that we would like to offer the possibility of having ORM dependencies included optionally (JPA, Hibernate) for those project that may require them in the future. We had though of creating an additional profile containing those dependencies.
When we build our project we use mvn package -Denvironment=dev. Is it possible to specify more than one profile such as: mvn package -Denvironment=dev,orm?
Yes, this is possible. But it seems you are confused about how profiles are activated in the first place.
The command
mvn package -Denvironment=dev
will not activate any profile without further configuration. In your case, it works because there must be a profile definition in your POM that is activated by the presence of the system property environment with a value of dev. The configuration you have would look like:
<profiles>
<profile>
<activation>
<property>
<name>environment</name>
<value>dev</value>
</property>
</activation>
</profile>
</profiles>
This is the magic that makes the profile activates when you pass the system property with -Denvironment. With that in mind, you can activate multiple profiles with the same idea: declare multiple <profile> element that are activated by the presence of a system property.
<profiles>
<profile>
<activation>
<property>
<name>myAwesomeProperty1</name>
<value>true</value>
</property>
</activation>
</profile>
<profile>
<activation>
<property>
<name>myAwesomeProperty2</name>
<value>true</value>
</property>
</activation>
</profile>
</profiles>
The above configuration would activate both profile if myAwesomeProperty1 and myAwesomeProperty2 is a system property with the value true.
In this particular case though, it seems that what you want is to activate a build depending on your environment so it could perhaps be a better idea to activate the profiles based on the -P command line switch, instead of a system property.
From Introduction to Build Profiles:
Profiles can be explicitly specified using the -P CLI option.
This option takes an argument that is a comma-delimited list of profile-ids to use. When this option is specified, the profile(s) specified in the option argument will be activated in addition to any profiles which are activated by their activation configuration or the <activeProfiles> section in settings.xml.
mvn groupId:artifactId:goal -P profile-1,profile-2
With this solution, you invoke Maven with multiple profile ids. That is to say, if you have in your configuration
<profiles>
<profile>
<id>profile-1</id>
<!-- rest of config -->
</profile>
<profile>
<id>profile-2</id>
<!-- rest of config -->
</profile>
</profiles>
The above invocation would activate both profile-1 and profile-2.

Conditional processing in Maven projects

I have some configuration settings that are in the Maven project that I'd like to keep there for building into a newly set up system but not touched if the configuration setting already exists. One of the problems I had is that when I deleted the setting from the build, it also deleted the setting from the target server when I did a build.
What would good alternatives be?
A possible solution could be to move the particular set-up for the new systems in a Maven profile and activate the profile only based on either an environment variable or the existence/non-existence of a file.
For instance, from official documentation, you can activate the profile if a certain environment variable exists, not exists or exists with a certain value.
<profiles>
<profile>
<activation>
<property>
<name>environment</name>
<value>test</value>
</property>
</activation>
...
</profile>
</profiles>
Please also note that, as from official documentation:
Note: Environment variables like FOO are available as properties of the form env.FOO. Further note that environment variable names are normalized to all upper-case on Windows.
Alternatively, the profile can be activated on a certain file (existing or missing), as following:
<profiles>
<profile>
<activation>
<file>
<missing>path/to/missing/file</missing>
</file>
</activation>
...
</profile>
</profiles>
If your set-up cannot be applied to any of these two cases, you could (as an example) anyway adapt it to create an harmless file which would then deny any further set-up.
harmless file missing > profile activated > set-up performed
harmless file existing > profile not activated

maven override profile from parent in child

I have a multi-module maven project.
parent-module-->child-submodule1
\->child-submodule2
Children are both submodules AND children of parent-module.
Child-submodule1 has a build profile my-profile very specific that should be shared with his sibling (submodule 2) as it setup the environment for both.
I moved this "my-profile" to the parent.
Now when I build activating this profile it is executed three times, thus the build fails (as this profile does very specific things here).
I needed the profile to be executed only once in the parent, and being skipped in the children.
I tried removing the parent-children relationship and this way it woud work, but I have other problems to solve (dependencies carried out from the parent).
How can I do it?
Can I override the profile in the children deactivating it?
You cannot deactivate a profile in children or prevent it from run.
You could however set <inherited>false</inherited> on all executions in my-profile in parent.
Alternatively, you can active the profile using one of these methods:
Having an activation policy of a specific property value only set on the two sub modules
<profiles>
<profile>
<activation>
<property>
<name>doit</name>
<value>true</value>
</property>
</activation>
...
</profile>
</profiles>
Using the presence of a specific file or folder, which is probably in your scenario anyway.
<profiles>
<profile>
<activation>
<file>
<exists>src/main/xcopy</exists>
</file>
</activation>
...
</profile>
</profiles>

Is there a way to achieve reverse of maven profile activation by property?

I want to have a profile that triggers a certain plugin(say PMD) but I want to explicitly disable that plugin execution sometimes.
So I want to have a profile that is always active except when a property is defined.
Something like mvn -Dnopmd clean install, and the profile gets de-activated. Other than that the profile should always be active.
You can activate a profile when a property is not specfied like so:
<profile>
<id>someprofile</id>
<activation>
<property>
<name>!property.name</name>
</property>
</activation>
</profile>
This is also explained in the Maven documentation, Introduction to Build Profiles.

Resources