I have 2 maven2 profiles, selenium and jspc. Now for "selenium" id'd like to have an implicit activation of "jspc", so that I don't have to write mvn -Pselenium,jspc from the command line. Is this possible ?
You can't "chain" profile activations (maven reference) but you can activate them both through the same property:
<activation>
<property>
<name>profile.selenium</name>
</property>
</activation>
And the run mvn -Dprofile.selenium
Related
Is it possible to disable settings.xml for particular project build using pom.xml?
I want to avoid using repositories specified in settings.xml file but only for one project.
Repositories are defined inside profiles in settings.xml file. You can activate and deactivate profiles based on some criteria. See documentation regarding profile activation.
You could:
deactivate given profile per project by passing -P !profile-name
you could define the profile as
<activation>
<property>
<name>skipThisProfile</name>
<value>!true</value>
</property>
</activation>
and then run your project with -DskipThisProfile
define the profile as
<activation>
<file>
<missing>.doNotRunProfile</missing>
</file>
</activation>
and will not run for any project where there is .doNotRunProfile file
Configuration:
- Maven: 3.0.5
- Java: 1.6.0_45
Description:
Let's say we have profile configuration like below:
<profiles>
<profile>
<id>profile-1</id>
<activation>
<jdk>1.6</jdk>
<property>
<name>name</name>
<value>Hubert</value>
</property>
</activation>
</profile>
<profile>
<id>profile-2</id>
<activation>
<jdk>1.6</jdk>
<property>
<name>name</name>
<value>Wiktoria</value>
</property>
</activation>
</profile>
</profiles>
We have two profiles: profile-1 and profile-2.
Profile profile-1 should be active when two requirements are met:
- jdk is version 1.6
- property name has value Hubert
Question:
Let's check this configuration:
mvn -Dname=Hubert help:active-profiles
As a result I get that there are two active profiles: profile-1 and profile-2.
Hmm...
Profile profile-2 should not be active since property name has value different from expected Wiktoria.
Could someone explain me why this work like this? Is it a normal behavior?
Thanks.
The problem here is that the activation list with your trigger conditions is connected with OR. They do have a ticket to provide multiple activation triggers, but it's still open.
That means, that it matches your sdk rule which is true and therefore active.
<profile>
<id>profile-1</id>
<activation> <!-- true || true = true -->
<jdk>1.6</jdk> <!-- true -->
<property> <!-- true -->
<name>name</name>
<value>Hubert</value>
</property>
</activation>
</profile>
<profile>
<id>profile-2</id>
<activation> <!-- true || false = true -->
<jdk>1.6</jdk> <!-- true -->
<property> <!-- false -->
<name>name</name>
<value>Wiktoria</value>
</property>
</activation>
</profile>
NOTE: This is only a suplement to Chasmo's correct answer.
There is a book from sonatype describing Maven. In section Sonatype book (section 5.3.1) we can find:
A profile is activated when all activation criteria has been satisfied.
This is not true. Truth is that one condition is enought to activate profile, which is of course equal to OR logical condition. This behavior is described in Maven docs:
Activation occurs when one or more of the specified criteria have been met. When the first positive result is encountered, processing stops and the profile is marked as active.
This is for me neither intiutive nor very useful. But thats how maven works at the time of writing that.
There is a ticket MNG-4565 for AND conjunction. This is marked as Bug, but acording to Maven doc it is not, so this ticket has been opened for almost 4 years.
The most useful part is last comment to this ticket written by Ronny Pscheidl. His comment points to this source: and-activation-profile-selector. This changes default maven OR condition to AND condition. Tested. Works. But of course if you decide to use this, you have one more thing to remember of.
e.g.
<profiles>
<profile>
<id>rofileX</id>
</profile>
</profiles>
The profile could have been activated using -ProfileX, why am I seeing people bother to add in an activation property, e.g.
<profiles>
<profile>
<id>rofileX</id>
<activation>
<property>
<name>oX</name>
</property>
</activation>
</profile>
</profiles>
to allow activation using -DoX?
Is there any reason to use -D insteal of -P? Or you can achieve more things with -D as oppose to -P?
Thank you
One usage of -Dmyproperty instead of -Pmyprofile is to activate several profiles using only one parameter.
Moreover, you can reuse the -Dmyproperty in other parts of your POM, using ${myproperty}.
The property does not necessarily has to be set via the -D maven option, it may also be a system property. So it is possible to switch between profiles without changing the invocation.
[edit]
from theMaven documentation:
-D, --define <arg>
Defines a system property
...
Properties defined on the command line are also available as properties to be used in a Maven POM or Maven Plugin
I want to use Maven to handle artifact generation for the different local and testing regions. I believe I can use different profiles but I am not certain.
In Maven can I select different directories to select files used on packaging (such as application.properties)? How would I set that up?
An idea of what I want is to have a the following folders for resources in my project
local
build server
dev
sys
prod
Each folder should contain a different version of application.resources which is a file in Spring that can be used to handle hard-coded strings for use in variables. For local builds- our developers also work on different operating systems. Should I require I want to make it seamless on different OS' also.
Key outcomes would be:
Control Maven lifecycle phases from inside the IDE (IntelliJ)
Not complicate phases and team processes
Keep things as consistent for each developer
Make the different configurations per developer/region appear invisible when running a phase e.g. install
Ideally I would have my project set up according to best practices (Duvall, Matyas, Glover).
We provide different properties currently but not by way of different folders. We do this
via a mix of
Spring's PropertyPlaceholderConfigurer
Maven profiles (something we use to build our Dev environment),
Build Server (TeamCity in our case)
Maven phases to produce the correct artifact
start-up and build arguments
My understanding of what we do is limited, but hopefully this serves as a useful example for others and maybe myself to consider.
We provide parameters, as you'll see below, to point to different property files.
Each property file has configuration for a region/environment. I'll explain the current use
as best I can in-case it provides some use to others.
To use Maven profiles we have created a profile in our pom identified as development which includes a region configuration property called env. I don't yet know entirely how that is being used yet in our project however you'll see below our POM includes the a Maven Compiler plugin and a Maven Tomcat plugin.
Day to day, as developers we run our our applications locally on Tomcat from within IntelliJ
and provide the env property. On start-up the env property is provided as an argument to
set to classpath*:dev-common.properties.
This file is a properties configuration file - setting placeholder values for our different
regions.
The value of env is made available to our PropertyPlaceholderConfigurer
Example 1 - Implementation of Maven profile in pom.xml:
The implementation of a profile in our pom is:
<profile>
<id>development</id>
<activation>
<property>
<name>env</name>
<value>development</value>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0-SNAPSHOT</version>
...
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
Example 2 - Property placeholder configurer for normal build:
We also make use ofa Spring component, a PropertyPlaceholderConfigurer. We use this in collaboration with a build argument to set up a classpath pointer to resource files.
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>
${env}
</value>
</list>
</property>
Example 3 - Property placeholder configurer for test:
We have Spring Contexts specifically set up for integration testing which also use the PropertyPlaceholderConfigurer. These are picked up by a integration testing class using a combination of #ContextConfiguration(locations = {"classpath:test-dataexchange-application-context.xml"}) and #RunWith(SpringJUnit4ClassRunner.class)).
In the testing context we configure the PropertyPlaceholderConfigurer as follows to pick up the properties of an integration testing region:
<bean id="testpropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:dev-local-common.properties</value>
</list>
</property>
Other notes:
We make use of Team City for build management but I have not seen how these settings are
used there, if they are at all. I can conceive there's an ability to combine the above approaches together to aid Continuous Integration and Delivery.
I do not see where the profile identified as development is being used. It is something I
must follow up with my fellow team members.
Resources:
Building for different environments at the Maven Project site.
Maven 3 does not allow configuration of a profile outside of a pom or settings.xml (the Maven configuration file) and says that users who used these external settings should now put them inside of settings.xml
If you are using Spring boot, there is an easy way of doing this.
Create two profiles in maven, and set a property in each profile with the name of the Spring profile you want to execute.
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!-- Default spring profile to use -->
<spring.profiles.active>dev</spring.profiles.active>
<!-- Default environment -->
<environment>develop</environment>
</properties>
</profile>
Inside your application.properties, add this property:
spring.profiles.active=${spring.profiles.active}
Create an application.property for each profile, using this pattern application-profile.properties. For example:
application-dev.properties
application-prod.properties
Be sure to active filtering in the resource plugin:
...
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
...
Another way is to create a file during the execution of maven called activeprofile.properties. Spring boot looks this file to load the active profile. You can create this file as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<configuration>
<target>
<echo message="spring.profiles.active=${spring.profiles.active}" file="target/classes/config/activeprofile.properties" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
</configuration>
</plugin>
Aim to generate an artifact for each environment at one time on the central server (CI/Build server), aim to generate an artifact and start/test the application with one click locally, provide a consistent easy to learn way to check out and run your build, and check in and configure your CI.
You can use profiles in Maven and utilize Maven targets to achieve the right build using a build server which in our case is TeamCity.
Use property placeholder configurer in Spring context with an application.resources file for each region and a filename mask e.g. application-resources-${region}.
We are trying to do Selenium tests for our java web application. We would like to be able to quickly configure our tests with a combination of the java function "System.getProperty" and modifying the profiles available for the test.
The reason for doing this is so that we can test different servers with a simple change of the dropdown box in netbeans (from < default config > to "server name/details"). Our servers run things like a Snapshot, RC, and hotfix branch so this would be very helpful in tracking down when bugs are introduced.
Our current method for doing this is modifying the test variables before each run to target the server we want (yuck!).
Any thoughts would be helpful
The simplest mechanism might well be to create profiles in your POM that are activated by a system property or environment variable.
An example from the Maven documentation (with small modifications for clarity):
<profiles>
<profile>
<activation>
<property>
<name>myProperty</name>
<value>test</value>
</property>
</activation>
...
</profile>
</profiles>
Which you'd activate manually with:
mvn groupId:artifactId:goal -DmyProperty=test
You'd enable this based on an environment variable by using the fact that Maven maps environment vars into properties with the name env.… (with case normalization on Windows):
<profiles>
<profile>
<activation>
<property>
<name>env.ENVIRONMENT</name>
<value>test</value>
</property>
</activation>
...
</profile>
</profiles>
Which you'd activate with:
export ENVIRONMENT=test # Does not need to be done every build, just per session
mvn groupId:artifactId:goal