Reputation: 11796
I am upgrading my old spring boot 1.5.x to latest 2.0.4, and I found mvn spring-boot:run
doesn't honor the profile specified in command line:
I have an application.properties
which stores common properties, and application-dev.properties
and application-prod.properties
specifying their db connections and tomcat ports.
It means, I have two profiles: dev
and prod
. I lookup the document, I have to specify profiles in pom.xml
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<profiles>
<profile>dev</profile>
<profile>prod</profile>
</profiles>
</configuration>
</plugin>
And I want to execute the dev
profile, I run:
mvn spring-boot:run -Dspring-boot.run.profiles=dev
And I see console outputs
boot.SpringApplication - The following profiles are active: dev
It seems Ok, but then I found it connects to wrong database and open different port, which is specified in prod
profile.
It seems all values specified in prod
override the dev
ones.
And if I comment the values in prod
, the dev
ones are pickup (so, there is no typo in dev
profile).
I tried the following combos:
mvn spring-boot:run -Dspring-boot.run.profiles=dev
mvn spring-boot:run -Dspring-boot.run.profiles="dev"
mvn spring-boot:run -Pdev -Dspring-boot.run.profiles=dev
mvn spring-boot:run -Pdev -Dspring-boot.run.profiles="dev"
All show The following profiles are active: dev
but connect to prod
DB and open wrong tomcat port.
I then tried:
mvn spring-boot:run -Pdev -Dspring.profiles.active=dev
mvn spring-boot:run -Pdev -Dspring.profiles.active="dev"
mvn spring-boot:run -Dspring.profiles.active="dev"
mvn spring-boot:run -Dspring.profiles.active=dev
mvn spring-boot:run -Drun.jvmArguments="-Dspring.profiles.active=dev"
All the 5 above show The following profiles are active: dev,prod
(which is incorrect, I just want dev
) and still connect to prod
DB
What may go wrong here?
This was easy in spring boot 1.5.x but became a WTF in 2.0.x . I feel frustrated here.
env:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/>
</parent>
------- updated -------
As @Jayesh said , maybe there's something wrong hidden, which leads default to prod
. I renamed my application-prod.properties
to application-prod2.properties
. I am sure there's no prod2
string in the whole project code.
after mvn clean compile install
,
Rerun with
mvn spring-boot:run -Dspring-boot.run.profiles=dev
Same result (The following profiles are active: dev
but still opens to wrong DB specified in prod2
)
And...
mvn spring-boot:run -Dspring.profiles.active=dev
Same result: The following profiles are active: dev,prod
, connects to wrong DB, opens wrong port specified in prod2
It seems spring boot picks whatever application-*.properties
and load the last one
I even set log level to TRACE
logging.level.org.springframework=TRACE
But still found no prod2
string in the output log...
The problem is solved.
There is another spring's XML containing this line:
<context:property-placeholder location="classpath*:*.properties"/>
It is the culprit. After commenting out this line, everything works fine.
P.S.: This is an evolving app, from pure spring app, with spring's XML setting, and the above line. Then wrapped in MVC, and then spring-boot . Everything works fine in 1.5.x, but in 2.x, boot truly loaded all .properties
files and override all value one by one.
Upvotes: 1
Views: 2258
Reputation: 11796
OK , The problem is solved.
There is another spring's XML containing this line :
<context:property-placeholder location="classpath*:*.properties"/>
It is the culprit. After commenting out this line , everything works fine.
P.S. : This is an evolving app , from pure spring app , with spring's XML setting , and the above line. Then wrapped in MVC , and then spring-boot . Everything works fine in 1.5.x , but in 2.x , boot truly loaded all .properties
files and override all value one by one.
Maybe there are some subtle changes on parsing .properties
from spring boot 1.5.x to 2.x.
Upvotes: 0
Reputation: 2075
Please update your pom.xml without the profiles section. As per boot maven plugin doc, you should only provide active profile in the section.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<profiles>
<!--<profile>dev</profile>
<profile>prod</profile> you are setting active profile via command line args-->
</profiles>
</configuration>
</plugin>
Since, you are passing via command line args you dont need to give it there.. You may look at these beautiful tutorials.
Please let me know if it works.
Upvotes: 3
Reputation: 687
I tried with the latest Spring Boot(v2.0.4.RELEASE) and the profile are getting loaded as expected.
pom.xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<profiles>
<profile>dev</profile>
<profile>prod</profile>
</profiles>
</configuration>
</plugin>
</plugins>
</build>
</project>
TestController.java:
package com.example.demo.TestController;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by Raj Rathore on 27-Aug-18
*/
@RestController
@RequestMapping("/test")
public class TestController {
@Value("${profile}")
String profile;
@GetMapping("/profile")
public String getProfile() {
return profile;
}
}
application-dev.poperties:
profile=dev profile
application-pord.poperties:
profile=prod profile
Then by using the mvn spring-boot:run -Dspring-boot.run.profiles=dev
the dev
profile is loaded :
com.example.demo.DemoApplication : The following profiles are active: dev
Output : (http://localhost:8080/test/profile)
dev profile
Upvotes: 0