spring.profiles.include does not work from command line parameter - spring-boot

I made trivial Spring Boot application and packaged it as JAR.
When I call
java -jar target/boot-active-include-0.0.1-SNAPSHOT.jar
I got
No active profile set, falling back to default profiles: default
When I call
echo spring.profiles.include=B > application.properties
java -jar target/boot-active-include-0.0.1-SNAPSHOT.jar
I got
The following profiles are active: B
When I call
rm application.properties
java -Dspring.profiles.include=B -jar target/boot-active-include-0.0.1-SNAPSHOT.jar
I got
No active profile set, falling back to default profiles: default
But I expect The following profiles are active: B
Can I include Spring profile from command line?
Version: 1.5.1.RELEASE
PS. spring.profiles.active works as expected. But I don't want replace active profiles.

I see what's happening now, and I think it's arguably something I missed when making this change.
Prior to that change, spring.profiles.include was only considered when it was used in a configuration file. Following that change, spring.profiles.include is now considered from any source (System properties, command line arguments, etc) as long as spring.profiles.active is also set.
You can see this by running your sample with both properties set:
java -Dspring.profiles.include=alpha -Dspring.profiles.active=bravo -jar target/boot-active-include-0.0.1-SNAPSHOT.jar
Both the alpha and bravo profiles are active:
2017-02-09 11:30:49.467 INFO 40409 --- [ main] my.Example : The following profiles are active: alpha,bravo
I've opened an issue so that we can straighten this out.

Related

Spring Add Profile at runtime

I want to add a profile at runtime based on some environment variable, so I have -Dspring.profiles.active=local and in code I have
if(someCondition){
springApplication.additionalProfiles("mock-test");
}
If someCondition is true, was expecting active profiles to be "local", "mock-test" but its in reverse order?
INFO o.s.b.SpringApplication : The following 2 profiles are active: "mock-test", "local"
Anyway to make mock-test as last profile?

How to set JVM arguments when running mvn spring-boot:build-image command in Spring Boot 2.3.0 to generate a docker image?

I am trying to build a docker image using the latest version of Spring Boot (2.3.0) . All I have to create an image now is run the command mvn:spring-boot:build-image . This will create a docker image for me. How do I set the JVM arguments (Max , Min heap sizes) in this case?
As of today, you can't set JVM arguments in spring-boot:build-image.
Spring boot build image uses Packeto internally and it accepts following 4 environment variables as mentioned in bellsoft-liberica GitHub.
"BP_JVM_VERSION" : "13.0.1",
"BPL_JVM_HEAD_ROOM" : "10",
"BPL_JVM_LOADED_CLASS_COUNT" : "35",
"BPL_JVM_THREAD_COUNT" : "10"
As alternate option, you can pass JVM arguments when you run the image.
docker run -p 8080:8080 --env JAVA_OPTS="-Xmx300m -Xms200m" -t youImageName
If using Kubernetes, you can configure JVM options at deployment level.
spec:
containers:
- name: yourapp
image: image path
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
- name: BPL_JVM_HEAD_ROOM
value: "2"
- name: BPL_JVM_LOADED_CLASS_COUNT
value: "35"
- name: BPL_JVM_THREAD_COUNT
value: "10"
- name: JAVA_OPTS
value: >-
-XX:ReservedCodeCacheSize=40M
-XX:MaxMetaspaceSize=60M
-Xlog:gc
-Xms34m
-Xmx40m
-Xss256k
-XX:MaxRAM=150M
There's a GitHub issue open in Spring boot repository discussing this Failed to change JVM arguments for buildpacked image
Build Back Environment Variables
I tried setting JVM arguments when I started using Spring Boot 2.3 & BuildPacks in November 2020, got nowhere and gave up / put it to one side.
Two weeks ago I picked it up again and purely by chance found this: https://github.com/paketo-buildpacks/environment-variables
Basically, you prefix your environment variable with BPE_APPEND_ and this triggers the Environment Variables Build Pack to append your value to the environment variable.
NB: JAVA_TOOL_OPTIONS is what you want here, not JAVA_OPTS.
I needed to attach a Java Agent to monitor our microservices and something like this build.gradle snippet was what worked:
bootBuildImage {
environment = [
'BPE_DELIM_JAVA_TOOL_OPTIONS' : ' ',
'BPE_APPEND_JAVA_TOOL_OPTIONS' : '-javaagent:my-java-agent.jar'
]
}
I used BPE_DELIM_JAVA_TOOL_OPTIONS to make sure a space was added to the existing value of JAVA_TOOL_OPTIONS before my value was appended (the buildpack also allows you to override or prepend to existing value - see their README).
PS: my value was more like '-javaagent:my-java-agent-${some-dynamic-version}.jar', so I needed double quotes, but that made it a Gradle String which didn't work so I had to write this instead "-javaagent:my-java-agent-${some-dynamic-version}.jar".toString().
None of these answers quite get it right. Here's the full situation at the time of writing.
It's important to understand that there are two different times where code runs: at build time and at runtime.
You can set env variables at build time using Spring Boot in your Maven or Gradle config. You just give it a list of env variables to set. See here https://docs.spring.io/spring-boot/docs/2.3.x/maven-plugin/reference/html/#build-image-customization. Those will only be set at build time though. Not what you want to set things like -Xmx.
If you want env variables set at runtime, then it's not something Spring Boot or the buildpacks can control. It's not a failing of either, it's just that neither are involved in actually running your app image/containers.
To pass env variables to your app image/containers at runtime, you need to use the facilities of whatever is running your app image, like Docker or Kubernetes. For Docker, it's just docker run -e foo=bar .... For Kubernetes, it's in the pod spec.
FYI. Any env variable that is prefixed with BPL_ means it only applies at run time (the L is for launch, which is what buildpacks term the runtime environment). Thus it would only make sense to set those when your app runs.
The environment variables buildpack, mentioned in the other answers, is a mix of the two. If you set env variables using option #1 above but prefixed in a certain way, this buildpack will see them and turn them into env variables that are embedded into the image. This will have the effect of setting them at runtime.
This works well if you want to set default values on your images. Then users of your image won't need to set them unless they need to deviate from the default values you, the image author set. Having said that, you would never want to use this for anything that is sensitive or secret. This is because the env variable and value end up in the image and thus anyone with access to the image can see that value.
To answer the question:
How do I set the JVM arguments (Max , Min heap sizes) in this case?
If you want to set default values that your image users can override, if needed, then you want the environment variables buildpack.
Ex:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<env>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-Xss256k</BPE_APPEND_JAVA_TOOL_OPTIONS>
<BPE_DELIM_JAVA_TOOL_OPTIONS> </BPE_DELIM_JAVA_TOOL_OPTIONS>
</env>
</image>
<layers>
<enabled>true</enabled>
</layers>
</configuration>
</plugin>
You'll see output like this:
[INFO] [creator] Paketo Environment Variables Buildpack 3.1.1
[INFO] [creator] https://github.com/paketo-buildpacks/environment-variables
[INFO] [creator] Launch Configuration:
[INFO] [creator] $BPE_<NAME> prepend value to $NAME, delimiting with OS path list separator
[INFO] [creator] $BPE_APPEND_<NAME> append value to $NAME
[INFO] [creator] $BPE_DEFAULT_<NAME> set default value for $NAME
[INFO] [creator] $BPE_DELIM_<NAME> set delimeter to use when appending or prepending to $NAME
[INFO] [creator] $BPE_OVERRIDE_<NAME> set $NAME to value
[INFO] [creator] $BPE_PREPEND_<NAME> prepend value to $NAME
[INFO] [creator] Environment Variables: Contributing to layer
[INFO] [creator] Writing env.launch/JAVA_TOOL_OPTIONS.append
When you run an instance of your image, the values you set should get passed through to the container, unless the user overrides them.
> docker run -it apps/maven
Setting Active Processor Count to 6
Calculating JVM memory based on 9057276K available memory
Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -Xmx8699636K -XX:MaxMetaspaceSize=88839K -XX:ReservedCodeCacheSize=240M (Total Memory: 9057276K, Thread Count: 50, Loaded Class Count: 13271, Headroom: 0%)
Adding 129 container CA certificates to JVM truststore
Spring Cloud Bindings Enabled
Picked up JAVA_TOOL_OPTIONS: -Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties -agentpath:/layers/paketo-buildpacks_bellsoft-liberica/jvmkill/jvmkill-1.16.0-RELEASE.so=printHeapHistogram=1 -Xss256k -XX:ActiveProcessorCount=6 -XX:MaxDirectMemorySize=10M -Xmx8699636K -XX:MaxMetaspaceSize=88839K -XX:ReservedCodeCacheSize=240M -Dorg.springframework.cloud.bindings.boot.enable=true
If you want to set the values, then just set them at runtime. For example: docker run -e JAVA_TOOL_OPTIONS '-Xss256k' ... or in your Kubernetes pod spec like this.
apiVersion: v1
kind: Pod
metadata:
name: my-cool-app
labels:
purpose: my-cool-app-label
spec:
containers:
- name: my-cool-app
image: my-cool-image
env:
- name: JAVA_TOOL_OPTIONS
value: "-Xss256k"
You'll see similar output when the container runs and Picked up JAVA_TOOL_OPTIONS: will show the values you set, -Xss256k from this example.
As #jeremyt suggests, you can override the value of this property using BPE_OVERRIDE_BPL_JVM_THREAD_COUNT build variable. Example:
bootBuildImage {
environment('BPE_OVERRIDE_BPL_JVM_THREAD_COUNT', '150')
}
Sadly, as of now, BPE_DEFAULT_BPL_JVM_THREAD_COUNT does not work (the value is ignored). The downside of BPE_OVERRIDE_BPL_JVM_THREAD_COUNT is that it ignores the environment variable set for runtime (in docker run).

GitLab CI CD runner not loading properties file for profile

When I run a command mvn clean test -Dspring.profiles.active=GITLAB-CI-TEST in the GitLab CI CD it not loading properties file application-gitlab-ci-test.properties. It is loading only application.properties.
As file application-gitlab-ci-test.properties contains the different value for spring.datasource.url the pipeline is failing in the remote runners with error
The last packet sent successfully to the server was 0 milliseconds ago.
The driver has not received any packets from the server.
Of course, this error is expected as properties file application.properties refers to the localhost database.
Code which loading application-gitlab-ci-test.properties:
#Profile("GITLAB-CI-TEST")
#PropertySource("classpath:application-gitlab-ci-test.properties")
#Configuration
public class GitLabCiTestProfile {
}
When I try to run the same command locally it's working as expected and in logs, I see the following records:
2020-03-30 19:23:00.609 DEBUG 604 --- [ main]
o.s.b.c.c.ConfigFileApplicationListener : Loaded config file
'file:/G:/****/****/****/****/target/classes/application.properties'
(classpath:/application.properties)
2020-03-30 19:23:00.609 DEBUG 604 --- [ main]
o.s.b.c.c.ConfigFileApplicationListener : Loaded config file
'file:/G:/****/****/****/****/target/classes/application-GITLAB-CI-TEST.properties' (classpath:/application-GITLAB-CI-TEST.properties) for profile
GITLAB-CI-TEST
I noticed that remote runners missing the second line. This one which loading application-GITLAB-CI-TEST.properties.
I also tried mvn clean test --batch-mode -PGITLAB-CI-TEST and this one too failing in the remote host but in local run working as expected.
I found the workaround for this issue by using the command
mvn clean test --batch-mode -Dspring.datasource.url=jdbc:mysql://mysql-db:3306/*******?useSSL=false&allowPublicKeyRetrieval=true
Can you please help me to solve this issue as this workaround is not satisfying me?
I found the solution to this issue.
I changed the name of the profile from the upper case (GITLAB-CI-TEST) to lower case (gitlab-ci-test), to match the lower case of profile name in properties file - application-gitlab-ci-test.properties.
Now in the remote runner, I'm using the following command:
mvn clean test -Dspring.profiles.active=gitlab-ci-test
Spring doc - link

Spring: Why I cant check for spring boot version without an error?

I am follow the guide for setting up spring boot with the following link.
http://docs.spring.io/spring-boot/docs/1.4.1.RELEASE/reference/htmlsingle/#getting-started-installing-the-cli
section 10.2.2
when I type $ spring --version
I receive the error below.
/cygdrive/c/Users/Jesse/Documents/.sdkman/candidates/springboot/current/bin/spring: line 83: [: C:\Program: binary operator expected
Error: Could not find or load main class org.springframework.boot.loader.JarLauncher
You need to set the SPRING_HOME variable.
After setting, SPRING_HOME was not resolving correctly for me even though it was set in windows as a user and a system variable, and was also visible when running export via Git Bash. I ended up replacing the last line in my spring.sh file, essentialy forcing the classpath for the java command:
"${JAVA_HOME}/bin/java" ${JAVA_OPTS} -cp "/drive_letter/dir/to/spring/spring-x.x.x.RELEASE/lib/spring-boot-cli-x.x.x.RELEASE.jar" org.springframework.boot.loader.JarLauncher "$#"

How can I disable console messages when running maven commands?

I'm in the process of executing Maven commands to run tests in the console (MacOSX). Recently, development efforts have produced extraneous messages in the console (info, debug, warning, etc.) I'd like to know how to remove messages like this:
INFO c.c.m.s.c.p.ApplicationProperties - Loading application properties from: app-config/shiro.properties
I've used this code to remove messages from the dbunit tests:
ch.qos.logback.classic.Logger Logger = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger("org.dbunit");
Logger.setLevel(Level. ERROR);
However, I'm unsure how to disable these additional (often verbose and irritating) messages from showing up on the console so that I can see the output more easily. Additional messages appear as above and these:
DEBUG c.c.m.s.c.f.dao.AbstractDBDAO - Adding filters to the Main Search query.
WARN c.c.m.s.c.p.JNDIConfigurationProperties - Unable to find JNDI value for name: xxxxx
INFO c.c.m.a.t.d.DatabaseTestFixture - * executing sql: xxxxx
The successful answer was:
SOLUTION: Solution to issue IS adding a 'logback-test.xml' file to the root of my test folder. I used the default contents (as instructed by the documentation - thanks #Charlie). Once file exists there, FIXED!

Resources