Using Spring Boot profiles with command line arguments - maven

I am getting confused about how to use profiles within a Spring Boot App.
Assuming that I defined profiles in pom.xml file,
Here is the different ways that I find.
mvnw -Pdev
mvnw spring-boot:run -Dspring-boot.run.profiles=dev
mvnw spring-boot:run -Dspring.profiles.active=dev
mvnw spring-boot:run --spring.profiles.active=dev
1/ Is there any difference between them ?
2/ What is the best approach to use ?

You should not confuse Maven profiles and Spring profiles - this is completely different things.
mvnw spring-boot:run -Dspring.profiles.active=dev - it is telling a Spring which profile to use at runtime.
Spring Profile - is how your Spring application will be configured at the runtime, based on the active profile.
You can read more about it here and here.
mvnw -P dev - it telling a Maven to use build Maven profile
Maven Profile - is how your Java application will be compiled/build/packed. It is related to the compiling/packaging, not runtime execution of your Spring application, and it doesn't related to Spring at all.
You can read more about it here and here.
This is answer to your first question.
Regarding your second question,
Maven profile are used when you need to build your application differently based on the profile settings. For example, pack a "fat jar" with all dependencies when you execute mvn -P fat-jar.
Spring profile is used when you want to configure your Spring application to work differently at runtime, for example - to use development and production database, etc.

mvnw -Pdev
This will consider maven profile
mvnw spring-boot:run -Dspring-boot.run.profiles=dev
This will consider maven profile
mvnw spring-boot:run -Dspring.profiles.active=dev
This will consider spring boot profile
mvnw spring-boot:run --spring.profiles.active=dev
This shouldn't work as maven don't understand --spring

Related

spring maven active profile

I am trying to run the Spring application from the server.
What is the difference between:
mvn spring-boot:run -Dspring.profiles.active=dev
and
mvn spring-boot:run -Dspring-boot.run.profiles=dev
Tnx
The difference is that the second property, spring-boot.run.profiles, comes from the Spring Boot Maven plugin which allows you to define profiles in your pom.xml, while spring.profiles.active comes from spring and can be used without any plugin, but in the end, they can do the same thing.

How to debug spring boot maven project in debug mode in Intellij?

I run my maven project with the following command for dev profile from my terminal
sudo mvn spring-boot:run -Dspring.profiles.active=dev
How can I run my project to run in debug mode with given profile. How to set configuration in intellij for this?
Running a Spring Boot project from Maven with a specific profile
mvn spring-boot:run -Dspring-boot.run.profiles=foo,bar
Or by using a shell variable
SPRING_PROFILES_ACTIVE=foo mvn spring-boot:run
Or by passing arguments to the JVM
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Dspring.profiles.active=foo,bar"
These are the only methods that I know of that work for Spring Boot v2.0+.
The first option is recognized by the Spring Boot Maven plugin and passes it on to the application JVM.
Since version 2.0 of Spring Boot, the run goal forks the process by default. Since -Dspring.profiles.active is not recognized by the plugin directly, it's only seen by the Maven process and not passed on to the app itself. This is why it doesn't work in the form mvn spring-boot:run -Dspring.profiles.active=foo,bar.
In the second option, the shell variable should be visible to any subprocesses spawned from that shell.
Starting a Spring Boot project in debug mode from Maven
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
Putting it together
mvn spring-boot:run -Dspring-boot.run.profiles=foo,bar -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
Alternative, passing all arguments to JVM
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 -Dspring.profiles.active=foo,bar"
The Maven pom.xml should include the Spring Boot plugin
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.1.RELEASE</version>
</plugin>
In IntelliJ you should create a new "Remote" debug configuration from the "Run/Debug Configurations" tool window. You'll find it in the main menu - "Run / Edit Configurations..."
The default config will use the same 5005 port.
After that, launch that debug config. The console should display "Connected to the target VM...".
Sources:
https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/maven-plugin/examples/run-profiles.html
https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/maven-plugin/examples/run-debug.html
If you're running from maven, then add the following parameters:
mvn spring-boot:run -Dspring.profiles.active=dev -Drun.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5555"
Here 5555 is a debug port number (you can use any other unoccupied port).
Then in IntelliJ you can use Remote Debug configuration and connect to that port.
If you open the pom.xml from intelliJ, you can create a Run Configuration with --spring.profiles.active=dev and main class that is a class with method main just like in a regular the most simple java application.
Just click run button (green triable button) then click Debug...
IntelliJ will run your spring-boot app in debugging mode
If you want to run with arguments just open edit configuration and put your args in VM Options/Program arguments like

Is there any meaning to running -Dspring.profiles.active=dev,runtime when running Spring Boot locally?

In my team I frequently (>10) see Spring Boot projects with the following instructions for running locally:
mvn clean spring-boot:run -Dspring.profiles.active=dev,runtime
My understanding of Spring Boot profiles is that each one corresponds to a particular environment, eg dev, test - so you would never need more than one. Also that each profile name corresponds to a particular env file - eg src/main/java/resources/application-dev.yml application-test.yml etc.
I would have thought that you would run the app on your local machine with:
mvn clean spring-boot:run -Dspring.profiles.active=local
And have the local configuration in:
src/main/java/resources/application-local.yml
This is running:
Java 11
maven parent is org.springframework.boot spring-boot-starter-parent 2.2.6.RELEASE
maven version is 3.3.9
My question is: Is there any meaning to running -Dspring.profiles.active=dev,runtime when running Spring Boot locally?

mvn spring-boot:run vs java -jar

I know it may sound silly question but I am unable to understand the difference between mvn spring-boot:run and java -jar (.jar file generated with mvn install)
I have a spring boot application with jsp pages in /src/main/resources/META-INF/resources/WEB-INF/. If I use mvn spring-boot:run these pages are served. But If I use java -jar these pages are not found by application.
The application that I am working on is at https://github.com/ArslanAnjum/angularSpringApi
UPDATE:
It works with spring boot 1.4.2.RELEASE while I intend to use the latest version i.e., 1.5.8.RELEASE.
UPDATE:
Well I solved the problem by putting jsps in src/main/webapp/WEB-INF/views/ and changing packaging type to war and then running this war using java -jar target/myapp.war and its working fine now.
Short answer: spring-boot:run is a java -jar command on steroïd running as part of your Maven build, ensuring all required parameters are passed to your app (such as resources). spring-boot:run will also ensure that your project is compiled by executing test-compile lifecycle goals prior to running your app.
Long answer:
When you run java -jar, you launch a new JVM instance with all the parameters you passed to this JVM. For example, using the Spring doc example
java -Xdebug -Xrunjdwp:server=y, \
transport=dt_socket, address=8000, suspend=
-jar target/myproject-0.0.1-SNAPSHOT.jar
You will launch a brand new JVM with the given parameters. You need to make sure to include everything needed, such as classpath elements, application parameters, JVM options, etc. on the command line.
When you run mvn spring-boot:run, you launch a Maven build that will:
Run the test-compile lifecycle goals, by default it will be resources:resources, compiler:compile, resources:testResources, compiler:testCompile goals of the Maven Resources and Compiler plugin.
Launch your application with a bunch of parameters that will depend on the
Spring Boot Maven Plugin configuration you defined in your project (your pom.xml, parents and settings, command line, etc.). This includes among other things:
A lot of classpath elements: your target/classes folder which may contain resources and libraries required by your app, your Maven dependencies, etc.
Whether to fork your JVM or not (whether to create a brand new JVM to run your app or re-use the JVM of the Maven build), see fork and agent parameter of the plugin
As per:
I have a spring boot application with jsp pages in
/src/main/resources/META-INF/resources/WEB-INF/. If I use mvn
spring-boot:run these pages are served. But If I use java -jar these
pages are not found by application.
It's because the mvn spring:boot command will make sure your target/classes folder is present in the Classpath when your app is running. After compilation, this folder will contain target/classes/META-INF/resources/WEB-INF among other things. Your app will then be able to find META-INF/resources/WEB-INF and load them when asked. When you ran java -jar command, this folder was probably not on the classpath, your app was then not able to find your resources. (these resources were copied from the src/main/resources folder during the resources:resources goal)
To have a similar result with your java -jar command, you must include your resources on the classpath such as javar -jar myapp.jar -cp $CLASSPATH;/path/to/my/project/target/classes/
Have you tried creating a jar file using mvn package instead of mvn install when you are running jar file using java -jar? package will create a jar/war as per your POM file whereas install will install generated jar file to the local repository for other dependencies if present.

How to specify additional classpath in command line when running Spring Boot application via Maven?

I'm running an application (in GitBash on Windows) with:
mvn spring-boot:run
Except that the application is looking for a properties file, which I'd like to make available in the classpath. But I don't want to have to change any code in this application.
Is there a way to specify additional classpaths when running this command? I've tried various forms of:
mvn spring-boot:run -Dclasspath="C:\\path\\to\\config\\dir"
or
mvn spring-boot:run -Dclasspath=/C/path/to/config/dir
And I've tried setting $CLASSPATH.
None of this works, but I don't get a clear idea about where it is breaking because the only error is that my properties file cannot be found.

Resources