smallufo
smallufo

Reputation: 11796

Spring Boot's spring-boot:run doesn't honor specified profile

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...


Solved

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

Answers (3)

smallufo
smallufo

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

Anand Varkey Philips
Anand Varkey Philips

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.

  1. https://www.mkyong.com/spring-boot/spring-boot-profiles-example/
  2. https://www.baeldung.com/spring-profiles

Please let me know if it works.

Upvotes: 3

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

Related Questions