tomcat7-maven-plugin to deploy spring boot with appropriate spring profile selected - maven

My goal is to be able to use the tomcat-maven plugin to deploy my spring boot application from the command line where an argument is supplied that tells spring which profile to use like this:
mvn tomcat7:deploy -Dspring.profiles.active="dev"
I've tried several different things such as the solution described here but the default application.properties is still always selected.
The only way that I've been able to get the application-dev.properties selected is by using
mvn spring-boot:run -Dspring.profiles.active="dev"
But we don't want to have tomcat packaged in our war
I'm new to maven and spring boot and I've been spinning my wheels for the better part of a a day now so any advice would be appreciated.

Consider using MAVEN_OPTS environment variable to set VM argument. (Linux/osx) example you would need to execute before your maven goal:
export MAVEN_OPTS="-Dspring.profiles.active=dev"

I found out the issue and I was able to get the correct profile selected using
export SPRING_PROFILES_ACTIVE=dev. The problem that I was having was when I was starting my local tomcat server through the eclipse UI my environment variables were being ignored. When starting tomcat through startup.bat the environment variable gets used and spring uses the correct profile.

Related

Maven install command with environment variables file

Is there any way to execute the environment variables file .env along with maven commands such as mvn clean install or mvn clean deploy. The main idea behind the concept that I'm looking for similar kind of solution:
mvn clean install -DenvFile=/path/<filename>.env
OR
mvn clean deploy -DenvFile=/path/<filename>.env
OR
mvn clean package -DenvFile=/path/<filename>.env
Note: Not trying to produce the environment specific builds. In dev environment, my intention to run the junit tests with all the
environment variables configured from <filename>.env.
where, the above maven commands should set all the environment variables from <filename>.env and then execute the maven plugins. In IntelliJ, there's a envFile plugin which exactly do the same.
Don't want to have environment specific properties dev|staging|prod.properties in my project because it's messy and hard to manage. I'd rather prefer to have one single environment specific file filename.env which contains all the dynamic/changeable properties.
application.properties
spring:
cloud:
config:
uri: http://config-service:${CONFIG_SERVICE_PORT}
fail-fast: true
password: ${CONFIG_SERVICE_PASSWORD}
username: user
Environment File: .env
CONFIG_SERVICE_PORT=8080
CONFIG_SERVICE_PASSWORD=123
Now when I deploy the application in different environments like AWS, GCP and Azure. All I need to change the environment variables in the .env file and run the application java -DenvFile=/path/<fileName>.env -jar application.jar and it will do the magic.
My problem is related with maven-sure-fire plugin for testing in dev-mode, which require these environments variables for spring context.
Any help would be appreciated.
Ok from your comments it seems like you're looks for two different solutions:
Run the application in different environments with java -DenvFile=/path/<fileName>.env -jar application.jar
Solution for running tests.
These are different issues I'll try to address both
Issue 1
When you run java -jar this means that the artifact is already assembled (with the help of spring boot maven plugin as far as I understand).
This jar is a ready to go spring boot application and maven is basically irrelevant here - maven is a build system, spring is a runtime framework and we're talking about the runtime.
Spring boot has a lot of ways to achieve what you want. A "Native" spring boot way which is close to your situation is running the application with "--spring.config.location=file:// with all the required configurations
It looks like this (see here for complete documentation):
java -jar application.jar --spring.config.location=myprops.properties
Even if you have some properties defined in src/main/resources/application.properties this method allows to override them effectively providing a way to run different configurations in different environments.
This has an advantage over the .env files because it can run in the same way in all the OS-es, even Windows ;) Since Java is OS independent - I believe its the best you can achieve.
Of course you can wrap the java -jar line in some kind of bash script and load / execute a series of export commands before running the jvm, but again, its less "spring-y" way.
Issue 2
Maven runs the tests (unit/integration) in a way that spring boot maven plugin is irrelevant. Its all about surefire/failsafe and spring boot testing framework.
I'll assume you're asking about integration tests because I believe this is all irrelevant for unit tests, since those should not require any environment variables at all and should be run without spring at all (junit/mockito should do the job)
I'll also allow myself to keep the assumption that the way of overriding/configuring the spring boot application via yaml or properties file is better than .env and will provide spring test configuration solution here:
With these assumptions you can create a yaml file in the following path: src/test/resources/application-test.yml
This file can contain configurations relevant for tests and will override anything written in src/main/resources/application.yml. Note, since application-test.yml resides in test sources, spring boot maven plugin won't package it into the application.
Depending on the exact way of doing integration tests you might consider also using #TestPropertySource annotation to provide the custom properties/yaml file that doesn't follow spring boot's default convention. Its especially useful for spring driven tests that do not bootstrap with the spring boot full fledged support (read the tests that use junit's spring runner but don't have annotation #SpringBootTest)
Another possibly useful annotation is #ActiveProfile("myprofile"). This will cause spring boot tests to automatically load file src/test/resources/application-myprofile.yml (or application-myprofile.properties)
Last but not least I'll refer the second comment with "dev/prod/staging/properties" in the source.
When it comes to tests - there should be only one file application-test.yml. However note that when you're using yaml, its possible to define configurations for many spring boot profiles in the same file:
# default value
foo:
bar: 1
---
spring:
profiles: staging
foo:
bar: 2
---
spring:
profiles: prod
foo:
bar: 3
Some relevant SO thread

Running Spring Boot Application.main() via IntelliJ doesn't find my local profile

I've been running my Spring Boot (2.1.0) app via Gradle bootRun but since adding in the Actuator, this causes the app to not actually shutdown when I tell IntelliJ to stop the app. For whatever reason, this is only an issue when running in Debug mode.
The solution I found online was to just run the Application.main() but now, my local profile isn't being picked up. So I have the typical application.yml along with various other profiles. All of the developers have an application-local.yml that is sitting at the root of the project and is ignored by git. Running Gradle's bootRun with local as the active profile works. But running Application.main() with the local active profile does not pick up the application-local.yml file's config.
As you can see in the image, I've not only specified the profile in Intellij's Active profiles section, but also as a VM option just like I do when running via Gradle.
One more thing which you can try
Set spring.profiles.active=local in Environment Variables below VM Options

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.

how to tune jvm when using spring boot application as unix service

i'm using the new spring-boot 1.3.0 feature to run tomcat embedded spring-boot application jar as a unix service.
All is working fine but i don't know how to tune jvm (with -Xms and -Xmx parameters for example)
I've searched in spring documentation and around the web without success.
It's missing from the documentation (I've opened an issue to correct that), but you should be able to use the JAVA_OPTS environment variable.
You can configure it in a .conf file that's situated next to the jar. For example, if you jar file is /var/myapp/myapp.jar, the file /var/myapp/myapp.conf will be sourced by the launch script.
There is one more option to achieve the same , if you are running jar with mvn you can do something like this
mvn spring-boot:run -Drun.jvmArguments="-Xmx512m"
And If you are running with java -jar ,you can try something like this
java -Xmx1G -jar myapp.jar

Hot deploy war maven project in embedded tomcat

I have maven war project.
I know inplace. it deploys to a given server. But i want to deploy on embedded tomcat and dont want to restart everytime. just say
for first time run deploy
Then change some java class and say redeploy. All in embedded tomcat.
Is this possible ?
Could the Tomcat Maven Plugin help with this?
You can use it by using the command tomcat:run
This page describes how to set up your POM/settings to make calling the plugin easier (using a prefix vs having to use full groupId/artifactId of plugin on the command line).
Maybe you can have a look at the executable war/jar feature see http://tomcat.apache.org/maven-plugin-2/executable-war-jar.html
So that will produce a simple jar which contains tomcat classes. You will be able to simply run: java -jar pathtofile.jar.

Resources