How to configure Clover license location in Maven and Jenkins - maven

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>

Related

activate spring boot profile from maven profile

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

setting active profile defined in parent pom in project pom

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.

Can Maven ask the user for values and enter them into a file?

I have a lot of config files that values have to change in. I would like to know if someone runs the "package" command can it ask for some values and insert them into my project files?
Better Approach would be have different property/config file depending upon environment.
Prod
Dev
Keep the two set of values in two different file. At times specify the file name.
For 90% of build tasks, there's Maven. For everything else, there's maven-antrun-plugin.
I suggest creating a custom ant script (which can be embedded in your pom.xml) that prompts for user input and writes out your config files using the Ant Input Task
You can use maven -P to select a maven profile and in turn selec the property files for it.
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<resource.prefix>dev</resource.prefix>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<resource.prefix>prod</resource.prefix>
</properties>
</profile>
</profiles>
Now access your resource file as ${resource.prefix}_config.properties. So when the profile is prod, the resource file prod_config.properties will be taken.
You cannot really make maven prompt for input unless you do some ant stuff suggested by noahz.
What you can do if you don't want to play around with Profiles is to use properties in your pom file.
Example:
<project>
<groupId>abc</groupId>
<artifactId>def</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<myProperty>someValue</myProperty>
</properties>
<build>
<plugins>
<plugin>
...
<configuration>
<outputDir>${myProperty}</outputDir>
</configuration>
</plugin>
</plugins>
</build>
</project>
You can use the property wherever you want within the pom file and you can even use the property when filtering resources.
The property could be empty by default and then have a new value set from command line:
mvn package -DmyProperty=anotherValue
And the anotherValue would be propagated to wherever it is used in pom.
You can read about Maven Resource Filtering here.
If you place a file in src/main/resources it could be filtered with the above property:
src/main/resources/important-stuff.properties
some.nice.property = Nice!
some.variable.property = ${myProperty}
And this should be added to the pom:
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
...
</build>
The filtered important-stuff.properties would end up in target/classes and in the jar and look like this:
some.nice.property = Nice!
some.variable.property = anotherValue
Resource filtering is really handy.

How to configure maven to use different log4j.properties files in different environments

I want to be able to use different log4j configuration for different environments.
In my development environment, I want to use log4j.properties (A). But when I build in Maven for the production environment, I want to use log4j.properties (B).
Please tell me how to configure this in my pom.xml?
You can use profiles to achieve the desired behavior:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>log4j</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>output_directory</outputDirectory>
<resources>
<resource>${log4j.file}</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<log4j.file>path_to_file_A</log4j.file>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<log4j.file>path_to_file_B</log4j.file>
</properties>
</profile>
</profiles>
1. in your project add 3 folders :
Your Project\src\main\resources\
\A > log4j.properties
\B > log4j.properties
\Default > log4j.properties
2. in pom.xml
<properties>
<param>Default</param>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources/${param}</directory>
</resource>
</resources>
</build>
3.
- if : mvn clean install : classpath => log4j.properties(Default)
- if : mvn clean install -Dparam=A : classpath => log4j.properties(A)
- if : mvn clean install -Dparam=B : classpath => log4j.properties(B)
> much better than using profiles is more extensible without touching the pom
You don't need the maven-resources-plugin if you have a simple environment.
In this example, log4j.properties B is the file you use for production and is in the directory src/main/java and log4j.properties A is the file you use for development and is in the directory /Users/junger/.m2/.
In your pom.xml:
<properties>
<log4j.properties.directory>src/main/java</log4j.properties.directory>
</properties>
<build>
<resources>
<resource>
<directory>${log4j.properties.directory}</directory>
<includes>
<include>log4j.properties</include>
</includes>
</resource>
</resources>
</build>
Now, in your /Users/junger/.m2/settings.xml (create one if it doesn't exist):
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<log4j.properties.directory>/Users/devuser/.m2/</log4j.properties.directory>
</properties>
</profile>
</profile>
By using this method, each developer can have a different log4j.properties directory and you keep your pom.xml clean.
Simplest way for me,
Define a system variable ENV and set its value _dev for your development env.
Where you refer this file use like this log4j${ENV}.properties
So,
In production it simply use log4j.xml and for your dev log4j_dev.xml
In order to prevent problems it would be better to create also ENV variable for production as _pro so for production log4j_pro.xml, for dev log4j_dev.xml will be used.
I believe that relying on different files than copying resource is better practice.
There is a very simple solution good for small projects with jar packaging (I haven't tested it on war packaged projects). The only disadvantage is that you have to duplicate all resources, but if your only resource is log4j.properties this is not a problem.
If you have a directory tree like this:
...
You should have the following pom:
<build>
<finalName>${project.artifactId}</finalName>
<sourceDirectory>src/</sourceDirectory>
<resources>
<resource>
<directory>${resources.path}</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<resources.path>resources/prod</resources.path>
</properties>
</profile>
<profile>
<id>dev</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<resources.path>resources/dev</resources.path>
</properties>
</profile>
</profiles>
Then when you use dev profile log4j.properties from resources/dev is used. When you use any other profile or no profile at all then log4j.properties from resources/prod is used. So your *.jar should look like this:
Of course if you have different resources location, for example main/java/resources/..., you should specify it instead of resources/...
To some extent you can reference environment variables inside a log4j.properties to add environment dependent behavior.
e.g.
log4j.rootLogger=${rootLoggerLevel}, ${appender}

Define maven profiles outside POM

Is there a way to define my maven profiles outside POM file but not in .m2/settings.xml?
I want to define them in a separate xml file inside the application (way to work efficiently with maven 2 and 3) because I am using maven 2 and intend to switch to 3 soon.
Until Maven 2.2.1 you could define your profiles into the profiles.xml file as a separate file but with Maven 3 this opportunity has been removed. The question ist why do you need a separate file for the profiles?
You may want to go through this maven documentation on build profiles, which describes the types of profiles and how each can be used.
As I see it, profiles cannot be defined outside pom.xml or settings.xml, if you want to use maven 3.
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<build.profile.id>dev</build.profile.id>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<build.profile.id>prod</build.profile.id>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<build.profile.id>test</build.profile.id>
</properties>
</profile>
</profiles>
And add a filter
<filters>
<filter>src/test/resources/${build.profile.id}/config.properties</filter>
</filters>
And add any directory (dev, prod, test)
I was recently migrating an application to maven3 from maven2. With maven 3 there is no possibility to have external profiles. But what can be done is to have external property files. This can be achieved by maven-properties-plugin
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<!-- Associate the read-project-properties goal with the initialize phase,
to read the properties file. -->
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>../com.tak/build.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
So here I have explained how to do that http://programtalk.com/java/migrate-from-maven2x-to-maven3x/

Resources