Spring Boot Not Resolving Properties Variable When Using spring-boot:run - spring

This was working for me and I'm not sure what changed.. I have my spring boot profile configured to be set based on a maven profile. The basics:
application.properties:
spring.profiles.active=#environment#
pom.xml:
<profiles>
<profile>
<id>development</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<environment>development</environment>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</profile>
<profile>
<id>production</id>
<properties>
<environment>production</environment>
</properties>
</profile>
</profiles>
When I run mvn clean package -Pdevelopment I see the line The following profiles are active: development.
Yet when I run mvn spring-boot:run -Pdevelopment I see the line The following profiles are active: #environment#.
Using the spring-boot:run command seems to not be able to resolve application property variables based on maven environment variables. Anyone know why? I tried adjusting the spring starter version without success.

According to the docs, you could tune the profiles to enable when running the application as follows:
$ mvn spring-boot:run -Dspring-boot.run.profiles=development
If not, try to comment your "spring.profiles.active" property in application.properties, that should work!
See also this thread.

Based on this tip in the docs, I added a configuration to my spring-boot-maven-plugin which broke this functionality:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<addResources>true</addResources>
</configuration>
</plugin>
Removing the addResources configuration restores the property expansion behavior.

Related

Cannot set Spring profile through Maven profile

This is my application-mysql.yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/XXXX
username: XX
password: XX
driver-class-name: com.mysql.jdbc.Driver
This is my pom:
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>spring.profiles.active</name>
<value>mysql</value>
</property>
</activation>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
Now I want to simple: mvn clean install.
Also tried mvn clean install -Pdev.
and get error when starting the Spring Boot application like it is not taking the application-mysql properties.
When I set in the application.properties
spring:
profiles:
active: dev
Then it works.
It looks like you're mixing up Maven properties with System properties. The <properties> inside the pom can only be used within the context of that pom. So they are not being exposed as System properties, hence not being picked up by Spring.
Not sure how/why you are starting the application during build, I assume for a test.
What I suggest to do is to read https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config which shows you how you can control the configuration under different conditions (without Maven).

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

How to refer a profile in maven spring boot project

I am novice when it comes to maven and spring boot. I need to run a spring boot project based on the profile. By default, the scope of following dependency is test which throws error at run time if I want to use h2. As I am not allowed to change the scope, I thought of adding two profiles in pom.xml - one default to be active by default and one for the h2 dependency without scope as test.
Following is what I added to pom.xml -
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>automation</id>
<properties>
<env>automation</env>
</properties>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
Now, I tried to run my project using following command -
mvn -D "spring-boot.run.profiles=automation" -DskipTests=true spring-boot:run
But I still see the same h2 dependency scope error that I was seeing earlier.
Caused by: java.lang.IllegalStateException: Cannot load driver class: org.h2.Driver
i.e. I am unable to change the scope of dependency this way. What am I missing here?
You are defining a Maven profile, but activating a Spring profile. Use the following syntax:
mvn groupId:artifactId:goal -P profile-1,profile-2
https://maven.apache.org/guides/introduction/introduction-to-profiles.html
Update
I tested the configuration you posted, and spring-boot:run fails for me if only default profile is active with the follwoing exception:
java.lang.IllegalStateException: Cannot load driver class: org.h2.Driver
You can check your dependencies with
mvn dependency:tree
The output of above command varies according to maven profiles passed in.

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.

How to configure Clover license location in Maven and Jenkins

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>

Resources