The short question:
How can you configure environment profiles, or even just an alternative configuration file name for
spring-boot:run?
The long version:
Yes, I read the doc. http://docs.spring.io/spring-boot/docs/current/reference/html/index.html
I have my application configuration settings in src/main/resources/application-mysql.properties:
# Specify the DBMS
spring.jpa.database = MYSQL
# Other Mysql config properties
spring.jpa.hibernate.ddl-auto=create
There is a corresponding application-hsql.properties, which contains the same set of configuration options for Hsql.
There is no application.poperties
There is a corresponding import.sql:
insert into users(name, email) values ('User One', 'one#email.com')
insert into users(name, email) values ('Two User', 'two#email.com')
The unit tests exist only to check for the presence of these users in the repo.
I believe it to be true that whenever the test is run using the MySql configuration, those rows are added to the users table. When the test is run with hsql, the mysql db should be unaffected.
I am manually dropping the users table between runs, because I want to manually see when it exists.
1) If I run mvn test, the tests use the configured db:
mvn -Dspring.profiles.active=mysql clean test
Produces mysql database rows and
mvn -Dspring.profiles.active=hsql clean test
Does not.
2) If I make a package, and then run the resulting jar file, I am able to specify a config file name:
java -jar -Dspring.profiles.active=mysql ./target/app.jar
3) If I run with spring-boot:run, only properties in application.properties (which doesn't exist in this test scenario) are discovered.
mvn -Dspring.profiles.active=mysql clean spring-boot:run
What does spring-boot:run do differently in launching than running unit tests and kicking off the jar? The db config is one example, but in theory I'd like to be able to specify a set of dev configs when the application is being run locally vs. a production configuration.
The Maven spring-boot plugin forks a new process so you'll need to send any extra parameters to it via jvmArguments, e.g.:
mvn spring-boot:run -Drun.jvmArguments="-Dspring.profiles.active=mysql"
The plugin allows you to specify the active profile(s) directly (perhaps it wasn't the case 3 year ago?) :
mvn spring-boot:run -Drun.profiles=mysql
Related
I'm using this command line in order to start my service locally:
mvn -pl rep-digital-api clean compile spring-boot:run \
-Dspring-boot.run.arguments=--spring.config.additional-location=front-pre-props.properties
pre profile is activated since front-pre-props.properties contains spring.profiles.active=pre.
Into default application-dev.properties I've set this property:
api.path-web=web
Nevertheless, I need to simulate pre profile into my local environment. So I need to change this property value:
api.path-web=other-path
Nevertheless, this property is not overriden.
Also I've tested it seting -Dapi.path-web=other-value in to mvn command, but it doesn't work...
Any ideas?
If you are trying to add a file from the file system, you need to set the value of property spring.config.additional-location to file:/pathtofile/yourfile.properties.
Lets say your file front-pre-props.properties is in path /Users/demo/front-pre-props.properties
Then you can execute the run command as :
mvn -pl rep-digital-api -Dspring.config.additional-location=“file:/Users/demo/front-pre-props.properties” clean compile
spring-boot:run
Is there any support for different test profiles? During my local tests I would like to use "mvn package" which uses the "test" profile. This points to my localhost db. For my devops toolchain I want to use a different test profile because we are using containers and cannot use localhost. Goal is to distinguish between local machine test and cloud env. test.
you mean you run 'mvn packge' which leads to the tests being run - like with 'mvn test' . In this case #QuarkusTest tests will run with the 'test' profile. The same goes for running tests in the ide.
There is a system property (used with '-D') 'quarkus.test.profile'. It leads to this profile being activated:
mvn test -Dquarkus.test.profile=foo
.....
2020-04-10 14:06:20,451 INFO [io.quarkus] (main) Quarkus 1.3.0.Final started in 17.408s. Listening on: http://0.0.0.0:8081
2020-04-10 14:06:20,451 INFO [io.quarkus] (main) Profile foo activated.
You may set this property on the surefire or failsafe plugin in your pom.xml (see 1).
You may also set this property within your IDE on a run/launch configuration to start the test (IntelliJ: use the vm options field and add '-Dquarkus.test.profile=integrate')
https://quarkus.io/guides/maven-tooling
Quarkus supports custom profiles. You have two ways to set a custom profile: via the quarkus-profile system property or the QUARKUS_PROFILE environment variable.
For your needs, you can for example, use a 'staging' profile with a different db address in application.properties in this way:
%staging.db.address=value
And set the QUARKUS_PROFILE environment variable to staging to activate the profile.
you can use quarkus.profile property so at runtime it will be:mvn package -Dquarkus.profile=your_custom_profile
I'm new to Spring Boot, so bear with me. Currently, I'm working on a small app just for the purposes of learning Spring Boot. My goal is to deploy it using AWS (elastic beanstalk).
So far, I've created three application properties files:
application.properties: Properties which apply to all profiles.
application-dev.properties: Properties only for development. This includes localhost connection to DB, path to self signed key store, etc.
application-prod.properties: Properties used only for prod. This includes the prod DB details, etc.
Everything works fine when running the app locally using the dev profile since everything has been hard coded in the application-dev.properties.
However, the application-prod.properties file contains references which will be resolved through OS environment variables, such as:
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
I currently do not have the variables DB_USERNAME and DB_PASSWORD set up in my local OS, and I do not wish to do so. But when I run the following command, it obviously fails:
mvn package spring-boot:repackage -Dspring.profiles.active=prod
It fails because it's unable to find the above environment variables.
Is there any way to delay this check until I actually execute the JAR? My plan is to build the JAR locally and then copy it over to my prod server, and run it there. The prod server will definitely have these environment variables.
The workaround I found is this:
mvn package spring-boot:repackage -Dspring.profiles.active=dev
java -jar -Dspring.profiles.active=prod [jar-file-name].jar
However, this feels like a hack. And it may cause issues in the future that I can't think of right now.
You can use any value you want in those properties for prod profile. If the env varieble exists, Spring will take the value from there instead of the properties.
As explained here:
Spring Boot uses a very particular PropertySource order that is
designed to allow sensible overriding of values. Properties are
considered in the following order:
[...]
OS environment variables.
[...]
Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).
So your application-prod.properties can look like this:
spring.datasource.username=willBeOverridenByEnvValue
spring.datasource.password=willBeOverridenByEnvValue
You have to make sure though that you set both SPRING_DATASOURCE_USERNAME and SPRING_DATASOURCE_PASSWORD env values in your prod server
I thought I had this working because in my IDE the correct environment properties file was being used, and a local application.properties was being correctly used. I am trying to use profile specific properties to determine various values throughout my Spring-Boot 1.3.5 app.
My src/main/resources/application.properties is:
spring.profiles.active=test
server.port=8080
deploy.server=http://localhost
liquibase.change-log:classpath:/db/changelog/db.changelog-master.xml
liquibase.check-change-log-location=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
logging.file=myapp.log
spring.jackson.serialization.write_dates_as_timestamps=false
And I have a src/main/resources/application-test.properties:
server.port=8081
deploy.server=https://test.myapp.com
logging.level.liquibase:TRACE
logging.level.org.springframework.security:DEBUG
Now I apparently have two problems:
After I run "gradle clean build" I get my jar and trying to run via:
java -jar build/libs/app.jar -Dspring.profiles.active=local
I see the message:
The following profiles are active: test
So it picking that up from the application.properties file and I can't seem to override it, which I think is causing my second problem:
My Jenkins build fails when I try to use a parameterized build with the values:
spring.profiles.active set to "test".
The error I get is Tomcat in a failed state. If I take that parameter out of the build, it works. But that build will not run from the command line unless I copy the application-{env}.properties to the run directory (which might be best practice anyway?).
I am not sure if the problem is the location of the properties files or the way I am trying to build them.
I use the yml configuration files pattern application-{default,dev,production}.yml.
To define which configuration application will use, I fix the environment SPRING_PROFILES_ACTIVE=dev so when the spring app run, it choose the correct configuration.
I have now theses two issues:
The ./gradlew build command also run the test command, test need to have the correct configuration as the application does when it start.
My jenkins does not have access to the database and the units tests keep failing.
Which make make ask:
Does the build command tries all the datasource in order ? Is there a way to specify the spring boot active profile ?
Is there another different approach for deploying spring-boots app in production from jenkins ?
Does anyone has a workaround except
./gradlew -x test build
This is not what I want.
Neither adding #ActiveProfile("dev") to my tests because this require source code modification.
Simply Create multiple property files.For Example:
application.properties
application-test.properties
application-production.properties
Provide different properties based on profile and
Below you can specify
which profile to load in you gradle.build file
def profile = "test"
bootRun {
args = ["--spring.profiles.active="+profile]
}
Put below code in the end of gradle file