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

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.

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.
https://www.mkyong.com/spring-boot/spring-boot-profiles-example/
https://www.baeldung.com/spring-profiles
Please let me know if it works.

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

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.

Related

IDEA import of Maven GitHub projects not working/running -> "Cannot resolve symbol"

#### UPDATE v2 ####
Ok I found out the issue, it was in fact an IDEA bug. More precisely, it's the git extension, gitflowincrementalbuilder, which from 3.8+ breaks Idea. Changing version to 3.7 solves it, for now.
https://github.com/vackosar/gitflow-incremental-builder/issues/91
Intellij/git, please fix it
------ Old Update v1 -----
I just tried running the project with Eclipse... works perfectly without any issues whatsoever, at first try... So it's kind of a Intellij-IDEA bug/problem (...)
I am trying to run some examples from Github, the spring spring-boot ones from baeldung.com; more specifically this one (no one works in idea): https://github.com/eugenp/tutorials/tree/master/spring-mvc-simple-2
While it works using Maven commands, "mvn clean install"
and then "mvn spring-boot:run", wont work in Idea (it does clean and install ok, but no run). Project is imported using "New"->"Project from Existing Sources" (check images below for settings).
I think there is some problem with the pom imported configuration, especially since there is a multi module structure (parent tag); cannot even resolve #SpringBootApplication.
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-mvc-simple-2</artifactId>
<packaging>war</packaging>
<name>spring-mvc-simple-2</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-2</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
</plugin>
</plugins>
<finalName>spring-mvc-simple2</finalName>
</build>
I have been trying to add a SpringBoot configuration manually using IDEA gui but it doesnt recognize the application class (?). What partially works though is replacing the parent pom with:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
Tests still wont work, but I dont think u're supposed to change/edit the pom file manually to make things works...
I have been trying alot already: invalidate cache, maven reimport & Generate sources and update folders, using mvn first, checking all jdk configuration... nothing works.
You didn't build the parent module so IntelliJ does not find this in your local Maven repository.
You should run mvn install in the project:
https://github.com/eugenp/tutorials/blob/master/parent-boot-2/pom.xml
But also exchanging the parent helps like you described yourself.
To make the tests run you have to add the test dependency from the parent:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
</dependency>

Choosing spring profile when building with maven

I was trying to create a build for my production environment.In my spring web application, I have 4 .yml files
application.yml
application-development.yml
application-staging.yml
application-production.yml
In the application.yml file, I specified
spring:
profiles:
active: production
the command i am using maven to create a build is
mvn clean install tomcat7:deploy -B -Pproduction
In my target folder I can see all properties and my production settings in not come up.
What i am getting is my default application.yml properties. How to build correctly?
In your application.yml, add as follows:
spring:
profiles:
active: #active-profiles#
Then try :
mvn clean install tomcat7:deploy -B -P production
In pom.xml (The maven profile is passed during the mvn command - production profile which finds the property and replaces the ones in application.yaml by spring-boot-maven-plugin inbuilt in spring-boot-starter-parent)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.2.RELEASE</version>
<relativePath />
</parent>
.
.//Dependencies go here
.
<profiles>
<profile>
<id>production</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<active-profiles>production</active-profiles>
</properties>
</profile>
</profiles>
More info here :
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html
http://dolszewski.com/spring/spring-boot-properties-per-maven-profile/
Maven resource filtering not working - because of spring boot dependency

Spring boot maven executable jar not running with Double click

Created a maven jar of a simple spring boot application.
If I try and execute the jar file from the command line using java -jar x.jar and it runs ok, even see all the traces of spring boot..booting up..
If try to execute it just by double clicking it with the mouse, it wont run. A command window pops up for a milli second and vanishes and if I try to get to an exposed endpoint (HTTP Rest - Get)..site cant be reached error..
The project is a sample Eureka server, so contains cloud dependencies..
Any ideas what could be the problem, is it just some environment setting?!
Regards,
From the POM:
<groupId>example.demo</groupId>
<artifactId>EurekaServiceDiscovery</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
.
.
.
.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
.
.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Basic Spring Eureka example, virtually no code except:
#EnableEurekaServer
#SpringBootApplication
public class EurekaServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServiceApplication.class, args);
}
Did you follow this?
https://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html
To create a ‘fully executable’ jar with Maven, use the following plugin configuration:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
The following example shows the equivalent Gradle configuration:
bootJar {
launchScript()
}
You can then run your application by typing ./my-application.jar (where my-application is the name of your artifact). The directory containing the jar is used as your application’s working directory.
There is no problem at all
Doubble click on jar fie and executing by command are not same
java -jar x.jar
Either execute from eclipse or from command prompt.
Else change Windows(operating system) setting or change execution setting in maven config to execute from command prompt

Maven keeps overwriting my spring boot application.properties file?

I am using the open source messenger4j project to create a spring boog based Facebook bot:
https://github.com/messenger4j/messenger4j-spring-boot-quickstart-template
I am running on Ubuntu 12.x and using Maven 3.5.0.
I need to use nano to edit the application.properties file of the Maven project. I make my edits, which include changing the server port and a few other SSL related items and the application.properties file looks like this:
messenger4j.appSecret = ${MESSENGER_APP_SECRET}
messenger4j.verifyToken = ${MESSENGER_VERIFY_TOKEN}
messenger4j.pageAccessToken = ${MESSENGER_PAGE_ACCESS_TOKEN}
logging.level.com.github.messenger4j=INFO
server.port=1919
... <other edits> ...
I then save the file, exit nano, and "cat" that file to make sure the edits are still there. They are. However, when I compile and run the messenger4j app with this maven wrapper command line:
./mvnw spring-boot:run
I notice that the status messages tell me that the embedded Tomcat server is not listening on port 1919 but instead on the default port 8080. I reopen the application.properties file and I see only the default content again and see this:
messenger4j.appSecret = ${MESSENGER_APP_SECRET}
messenger4j.verifyToken = ${MESSENGER_VERIFY_TOKEN}
messenger4j.pageAccessToken = ${MESSENGER_PAGE_ACCESS_TOKEN}
logging.level.com.github.messenger4j=INFO
Does anyone know what is causing this and how to fix this? It appears that Maven is overwriting the application.properties file from some other source each time it compiles and runs (I'm guessing here)?
I saw a stack overflow post talking about a command line flag that tells maven not to overwrite the application.properties file. But if there is another source file that Maven is using (or should use) to auto-generate the application.properties file, I would like to edit that file instead of using that flag and stay with the usual expected workflow of a Maven project. I also would rather not pass a boat load of parameters on the mvnw command line either if I can help it.
UPDATE: Added pom.xml file.
Here is my pom.xml file:
<?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.github.messenger4j</groupId>
<artifactId>messenger4j-spring-boot-quickstart-template</artifactId>
<version>1.0.2</version>
<packaging>jar</packaging>
<name>${project.groupId}:${project.artifactId}</name>
<description>Facebook Messenger Chatbot Template using Java, Spring Boot, and messenger4j</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</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>
<dependency>
<groupId>com.github.messenger4j</groupId>
<artifactId>messenger4j</artifactId>
<version>0.8.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
UPDATE: It turns out I was editing the ./target/classes/application.properties file instead of the file that Maven copies from to create that file. I'm referring to the true source file named ./src/main/resources/application.properties. Thank you dunni & Kyle.

SpringBoot: Adding 3rd Party jars in a Spring Boot Project

I have set MAVEN paths and variables. I am able to run a sample SpringBoot project in Eclipse but what I want is I have a custom jar and I am using classes from that jar in my Spring Boot Project. When I include this custom jar and build the SpringBoot application, I get the following errors
[ERROR] The goal you specified requires a project to execute but there
is no POM in this directory (D:......\SpringBootDemo\target).
Please verify you invoked Maven from the correct directory. -> [Help
1]
org.apache.maven.lifecycle.MissingProjectException: The goal you
specified requires a project to execute but there is no POM in this
directory (D:......\SpringBootDemo\target).
Please verify you invoked Maven from the correct directory.
My POM.xml is as follows:
<groupId>com.demo</groupId>
<artifactId>SpringBoot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>SpringBootDemo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.8.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>
</plugin>
</plugins>
</build>
Am I missing anything?
Any help will be greatly appreciated.
Thanks
Sometimes you will have 3rd party JARs that you need to put in your local repository for use in your builds, since they don't exist in any public repository like Maven Central. The JARs must be placed in the local repository in the correct place in order for it to be correctly picked up by Apache Maven. To make this easier, and less error prone, we have provide a goal in the maven-install-plugin which should make this relatively painless. To install a JAR in the local repository use the following command:
mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> \
-DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>
With version 2.5 of the maven-install-plugin it gets even better. If the JAR was built by Apache Maven, it'll contain a pom.xml in a subfolder of the META-INF directory, which will be read by default. In that case, all you need to do is:
mvn install:install-file -Dfile=<path-to-file>
From a Maven Guide to installing 3rd party JARs.

Resources