We have a corporate wide Super Pom we use to define many of the defaults we use. For example, the Super Pom defines what version of the JDK to use, and other parameters. This is inherited by our projects as the parent pom.
Most of our projects use JDK 1.7, but one set of projects is still on version JDK 1.6. I've put the following profile definitions in my parent pom:
<properties>
<travelclick.snapshot.repo>artifactory/libs-snapshot-local</travelclick.snapshot.repo>
<old.javac.source>1.5</old.javac.source>
<old.javac.target>1.6</old.javac.target>
</properties>
<profiles>
...
<profile>
<id>jdk1.6</id>
<build>
<plugins>
<plugin>
<groupId>com.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<...>
<source>${old.javac.source}</source>
<target>${old.javac.target}</target>
<...>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<...>
</profiles>
Now, I have a profile called jdk1.6 and I'd like to specify in the project's pom that it should use this one by default. How do I do this?
I've tried adding into the project's pom:
<profiles>
<profile>
<id>jdk1.6</id>
<activations>
<activeByDefault>true</activeByDefault>
</activations>
</profile>
</profile>
But that redefines my jdk1.6 profile.
I've tried putting in this:
<activeProfiles>
<activeProfile>jdk1.6</activeProfile>
</activeProfiles>
But that only works in settings.xml.
How do I specify a profile in the parent pom, and then say that this is the active profile in the child pom?
More Attempts
I've tried using properties. In my parent pom.xml:
<profiles>
<profile>
<id>jdk1.6</id>
<activation>
<property>
<name>use-jdk1.6</name>
</property>
</activation>
<profile>
</profiles>
And the following in my local pom:
<properties>
<use-jdk1.6>true</use-jdk1.6>
</properties>
But, it doesn't pick up the profile. And, this does work:
$ mvn -Puse-jdk1.6 clean package site
So, I know that the parent profiles do work.
Profiles
Could you add yours profile details exectuing goal help:all-profiles
[INFO] Listing Profiles for Project: xxxx
Profile Id: artifactory (Active: true , Source: settings.xml)
Profile Id: jdk1.6 (Active: false , Source: pom)
Profile Id: arse-version (Active: false , Source: pom)
Profile Id: urge (Active: false , Source: pom)
I can activate jdk1.6 from the command line. I just want to activate it as the default in my child poms.
AAAAHGGGGHHHH!
That's me screaming.
I found the issue and why this wasn't working.
In my parent pom, I had the following:
<properties>
<javac.source>1.7</javac.source>
<javac.source>1.7</javac.source>
<old.javac.source>1.7</old.javac.source>
<old.javac.source>1.7</old.javac.source>
...
</properties>
<profiles>
<profile>
<id>jdk1.6</id>
<activation>
<property>
<name>use-jdk1.6</name>
</property>
</activation>
<build>
<plugins>
....
<plugin>
<groupId>maven-compiler-plugin</groupId>
...
<configuration>
<!-- This isn't doing what I think -->
<source>${old.javac.source}</source>
<target>${old.javac.target}</source>
...
</configuration>
</plugin>
</plugins>
<profile>
In my child pom, I had this:
<properties>
<use-jdk1.6>true</use-jdk1.6>
</properties>
And, it appeared that setting the use-jdk1.6 property just wasn't working. However, that wasn't the case. I was setting the profile.
What happens is if I have the system property javac.source and javac.target set, it overrides the configuration of the maven-compiler-pluing (even though I had explicitly set <source> and <target> not to use version 1.7).
So, I spent six hours on this issue before I realized it was due to me setting a property named javac.source rather than something like java-version.
Related
I want to separate my junit test and integration test separate. So I created a separate profile in pom.xml for the integration test as follows:
<profiles>
<profile>
<id>integration-test</id>
<properties>
<test>IntegrationTestTrigger</test>
<spring.profiles.active>integration-test</spring.profiles.active>
</properties>
</profile>
<profiles>
The when I run the maven command mvn test -Pintegration-test, it is picking the test class as defined in the <properties> tag shown above as IntegrationTestTrigger. But it is not setting the spring.profiles.active property. So the test is starting with default profile. It is working fine with the maven command mvn test -Dtest=IntegrationTestTrigger -Dspring.profiles.active=integration-test
But as per my organisations jenkins setting, I need to run mvn test -Pintegration-test for the integration test, so I cannot add any extra environment variables to mvn command
Indeed as #gtivari333 said, profile/properties section is only to be used for substitution in POM files (and other files processed by maven, if so desired).
To set JVM properties aka "system properties" in POM directly, for use during test execution, you need to set them using surefire plugin configuration like this:
<profiles>
<profile>
<id>integration-test</id>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId>
<configuration>
<systemProperties>
<foo>bar</foo>
<spring.profiles.active>integration-test</spring.profiles.active>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
The properties at the is meant for property substitution at the .properties/.yml file inside resources folder.
Example:
application.yml:
spring:
profiles:
active: '#spring.profiles.active#'
pom.xml:
<profile>
<id>dev</id>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>
Here, the #spring.profiles.active# will be replaced with dev during compile(by maven-resources-plugin plugin). Spring Boot uses # as the resource delimiter at the spring-boot-starter-parent pom. You can change it to any character by changing the following property
//pom.xml
<project .....>
<properties>
<resource.delimiter>#</resource.delimiter>
...
</properties>
See https://github.com/gtiwari333/spring-boot-blog-app/blob/master/pom.xml#L436 for an complete example
See also: https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-automatic-expansion-maven
I have pom.xml with the following contents.
<profiles>
<profile>
<id>P1</id>
<build>
... some exec-maven-plugin entries
</build>
</profile>
<profile>
<id>P2</id>
<build>
... some exec-maven-plugin entries
</build>
</profile>
<profiles>
<build>
... some more (but common for all) exec-maven-plugin entries
</build>
Only one of the profile P1 or P2 is activated from command line. But whatever the selected profile, it is expected that plugins in the common section (i.e., the build section outsides the profiles) should also execute. It is also expected that the plugins both in the profile and the common section get executed in the order of configured phase.
Now the build works with maven2 but fails with maven3. I have not been to able to debug this exactly.
With Maven3, would this work as expected?
In what order would the plugins get executed?
Or is it only the selected profile that alone builds?
UPDATE: The common build does get executed. There were conflicting execution IDs in common and in one of the profile. So it failed.
You need something like this:
<profiles>
<profile>
<id>P1</id>
<build>
.. executed for with -PP1
</build>
</profile>
<profile>
<id>P2</id>
<build>
.. executed for with -PP2
</build>
</profile>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
.. executed with no profile
</build>
</profile>
</profiles>
<build>
.. executed for in all cases.
</build>
I want to make testing for different folders in a maven project and I need to change the maven's project.build.testSourceDirectory property.
I'm using a maven profile for this problem.
My profile looks like this:
<profiles>
<profile>
<id>sahi_UI_testing</id>
<activation>
<property>
<name>sahiTesting</name>
<value>true</value>
</property>
</activation>
<properties>
<maven.test.skip>false</maven.test.skip>
<project.build.testSourceDirectory>src/test/java/org/package1/package2/sahi</project.build.testSourceDirectory>
</properties>
</profile>
</profiles>
The project.build.testSourceDirectory isn't changed, only remains the default /home/username/workspace/projectName/core/src/test/java (I've tested this with maven-antrun-plugin and gives that path).
I have multiple pom.xml in the projects, so in the path I have the ../core/.. folder (this is the project's core pom.xml).
The maven-antrun-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>******** Displaying value of property ********</echo>
<echo>${project.build.testSourceDirectory}</echo>
<echo>${maven.test.skip}</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
Executing mvn help:active-profiles -f core/pom.xml -Dtest=JavaClientTest -o -e test -DsahiTesting=true with <maven.test.skip>true</maven.test.skip> in maven-antrun-plugin this gives me:
[INFO] Executing tasks
[echo] ** Displaying value of property **
[echo] /home/username/workspace/projectName/core/src/test/java
[echo] true
and with <maven.test.skip>false</maven.test.skip> in maven-antrun-plugin this gives me:
[INFO] Executing tasks
[echo] ** Displaying value of property **
[echo] /home/username/workspace/projectName/core/src/test/java
[echo] false
So, we can see that the another variable was changed.
I know that the profile was activated because I used maven-help-plugin to identify this.
The maven-help-plugin gives me this result:
The following profiles are active:
sahi_UI_testing (source: pom)
I've tried without maven's profile to change the project.build.testSourceDirectory property only in the <build> tag.
...
<build>
<testSourceDirectory>src/test/java/org/package/package2/sahi</testSourceDirectory>
...
</build>
There the property was changed (but I need to assign more than one value to that property).
I've tried the maven-surefire-plugin and doesn't work too.
The question is that why the project.build.testSourceDirectory isn't changed when using the profile?
I found a not very nice solution to this question but it's a solution. For me it's working and it changes the testSourceDirectory variable.
In the pom.xml file I've declared an own variable in the properties tag initialized with the testSourceDirectory's default value:
<project ...>
...
<properties>
<myTestSourceDirectory>${project.basedir}/src/test/java</myTestSourceDirectory>
...
</properties>
...
</project>
My profile is:
<profiles>
<profile>
<id>sahi_UI_testing</id>
<activation>
<property>
<name>sahiTesting</name>
<value>true</value>
</property>
</activation>
<properties>
<maven.test.skip>false</maven.test.skip>
<myTestSourceDirectory>src/test/java/org/<package1>/<package2>/sahi</myTestSourceDirectory>
</properties>
</profile>
</profiles>
At the start of build tag I've set the testSourceDirectory to
<project ...>
<build>
<testSourceDirectory>${myTestSourceDirectory}</testSourceDirectory>
...
<build>
...
</project>
So, when we don't use the profile we have a default value to the myTestSourceDirectory variable and when we use a the profile the variable will be changed to the requested testing directory. The variable always exists, and in the build tag we change the testSourceDirectory property to the desired value.
You can't overwrite the project model with properties, Maven doesn't allow that. The only option you have is by specifying the testSourceDirectory in the plugin you want to use (assuming it's available).
I know how to Clover in Maven (in local Eclipse or Jenkins), the problem is it's not a good idea to ask everyone put clover license in the same directory. Is there any suggestion for it?
<properties>
<clover.version>3.1.8</clover.version>
<clover.license>C:\xxx\clover_license</clover.license>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-clover2-plugin</artifactId>
<version>${clover.version}</version>
<configuration>
<license>${clover.license}</license>
</configuration>
</plugin>
</plugins>
</build>
I think use Maven parameter to pass the variable is possible, but I need to set it in every project in Jenkins. And if I change the file in Jenkins server, I need to modify every project.
-Dclover.license=C:\xxx\clover_license
See How to configure your clover.license for advice here. I recommend the suggestion to "Set up your .m2/settings.xml file", so you can define that property once:
<profiles>
<profile>
<id>my-clover-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!-- You can define the path to a license file: -->
<maven.clover.licenseLocation>/path/to/clover.license</maven.clover.licenseLocation>
<!-- Or you can embed license key (remember to keep newline characters): -->
<maven.clover.license><![CDATA[
...
]]></maven.clover.license>
</properties>
</profile>
</profiles>
I have a need to detect if a user is using mvn2 or mvn3 in my parent pom in order to load the proper plugin version. I followed the recommendation from here : http://maven.apache.org/plugins/maven-site-plugin/maven-3.html#Using_maven-site-plugin_2.x_with_Maven_2_and_maven-site-plugin_3.x_with_Maven_3
The detection mechanism works great - however, my other profiles that are activatedByDefaul do not get picked up anymore.
Super pom look like below:
<profile>
<id>profile-1</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>profile-2</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>
<profile>
<id>maven-3</id>
<activation>
<file>
<!-- This employs that the basedir expression is only recognized by Maven 3.x (see MNG-2363) -->
<exists>${basedir}</exists>
</file>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.company.plugins</groupId>
<artifactId>my-super-plugin</artifactId>
<version>1.0-123</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
when I run mvn help:active-profiles with mvn3 --> only maven-3 profile get listed. If I use mvn2, profile-1 is rightfully listed.
*Edit * : as it turns out, its actually well documented here : http://maven.apache.org/guides/introduction/introduction-to-profiles.html
This profile 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.
My question is now then : what work around would you recommend to have profile1 activated by default and profile 2 activated if -P profile2, while maven-3 profile activated if maven3 is used?
So far I haven't found anything better than just:
<activation>
<property>
<name>!dummy</name>
</property>
</activation>
where dummy is some kind of stupid variable name that you won't use for sure.