Including profiles in spring boot 2.4.0 version - java

As a developer, I use the default dev profile in my local development environment. Here is part of my application-dev.properties file:
# Profiles
spring.profiles.include=auth
Previously I used Spring Boot 2.3.0.RELEASE and the spring.profiles.include property included auth profile at runtime.
But after I migrated to Spring Boot 2.4.0, I don't get the auth profile enabled. spring.profiles.include property doesn't seem to work as before.
Please tell me how I can configure my profiles so that I get the same result as before migration. (I would not like to use profile groups here)
Thanks in advance!

In case your configuration processing has changed in incompatible ways and you wish to use the "legacy" processing way, you can re-enable it by setting:
spring.config.use-legacy-processing=true
or alternatively, using YAML:
spring:
config:
use-legacy-processing: true
which should revert the configuration processing to the 2.3.x equivalent. Do note, however, that this property exists solely to ease the migration of profile configurations from 2.3.x to 2.4.x and will likely be deprecated and removed in a future major release1, so you should still try to migrate ASAP. To understand the reason for this change and some additional information, read on.
Of note in 2.4.0 are the following two paradigms:
So in Spring Boot 2.4 we’re planning to make two significant changes to the way the properties and YAML files are loaded:
Documents will be loaded in the order that they’re defined.
Profiles can no longer be activated from profile specific documents.
This change has in fact made the what-overrides-what-when logic considerably simpler to digest, but leads to having to disable some functionality. For example:
my.prop: test
---
spring.profiles: prodprops
my.prop: prod
---
spring.profiles: prod
# no longer works - activating a profile from a profile-specific document!
spring.profiles.include: prodprops
would lead to an exception as the configuration attempts to activate a profile from a profile-specific document, which is not allowed anymore.
To cover this use case (and others), profile groups have been added as a feature. This means that to enable your previous behaviour, you would need to create a profile group as follows:
spring.profiles.group.<group>=dev, auth
or alternatively, in YAML:
spring:
profiles:
group:
<group>: dev, auth
Where <group> is the name of your chosen profile group. Note that you can define multiple groups, all of which should have different names. If you then start your application using the <group> profile, all the profiles that are part of that group should be activated.
As a side-note, Spring Boot 2.4.0 additionally added support for multi-document properties files, which look as follows:
test=value
spring.profiles.active=local
#---
spring.config.activate.on-profile=dev
test=overridden value
Note the document separator (#---). This allows you to have similar overriding logic in .properties files as in .yml files.
Again, this and other information is provided in the relevant update post.
1 If prior deprecations are any indicator, the property should be removed in 2.5.0 at the earliest or 2.6.0 at the latest, with the latter being more likely (and a deprecation as of 2.5.x).

You can use spring.config.import using classpath:
spring.config.import=classpath:application-DEV.yml,classpath:application-auth.yml

Although we have an accepted answer above. But I would share my solution via multiple files.
I'm having multiple config files in my project
./
application.yml
application-auth.yml
application-mockauth.yml
application-datasource.yml
The body of application-auth.yml or application-datasource.yml are the same as we're implementing before spring boot 2.4. Minor adjustment will be located inside application.yml
spring:
profiles:
group:
"dev": "datasource,mockauth"
"prod": "datasource,auth"
Instead of spring.profiles.include, you will group related config with environment name (dev, prod...).

You can also use spring.config.import to import configuration from other file according this documentation Config file processing in Spring Boot 2.4.

Related

Spring Config Server delivering config file but not activating profiles

I have a config server.
I'm migrating from 2.2 to 2.6 and I've seen that properties file are changed.
I have a situation that I don't think is covered (or maybe I misunderstood).
My situation is that I've a Config server that deliver:
application.properties --> containing properties shared by every microservices
application-dev.properties --> containing properties specific for dev profile
application-test.properties --> containing properties specific for test profile
application-production.properties --> containing properties specific for production profile
microservicesName.properties --> containing specific properties
microservicesName-mysql.properties --> if I use mysql profile
microservicesName-h2.properties --> if I use h2 profile
Before 2.4 I used to put in microservices application.properties path to fetch configuration from config server and in application.properties delivered by config server:
spring.profiles.include=dev,mysql
if for example I would like to activate for all microservices dev and mysql.
Now, I've converted include to groups. E.G.:
spring.profiles.groups.myConf=dev,mysql
(tried also with array notation --> spring.profiles.groups.myConf[0]=dev and [1]=mysql)
and adding to every microservices
spring.profiles.active=myConf
Watching for the config server logs, it deliver the configuration properly. My problem is that I have some Bean annotated with profile E.g.:
#Profile('h2')
or
#Profile('dev')
but these beans are not activated and application not start (also, in startup-logs profiles=[myConf])
The only solution that I found is to insert in every microservice application.properties
spring.profile.active=dev,mysql
but this don't look very comfortable because I've a lot of microservices.
Which is the proper way?
P.s.: I tried also to not touch anything and use simply
spring.config.use-legacy-processing=true
in all .properties but no luck.
After some month, with Spring Boot 2.6.6, and Spring Framework 5.3.18, this bug is solved.

How to merge application.properties with application-default.properties and include in other test profiles with Spring Boot >2.4

We would like to merge src/main/resources/application.properties with additional default properties when running tests which in turn should be included by other (test) properties files activated via specific profiles in our Spring Boot application.
Up until Spring Boot 2.4 this worked quite well by having all common test properties in src/test/resources/application-default.properties to keep things DRY. Those were then automatically merged with the ones from src/main/resources/application.properties by Spring [1]. This allowed us to have our own set of default properties without requiring tests to specify an #ActiveProfiles("default").
Other (test) profiles could then have their own application-<profile>.properties with spring.profiles.include=default and then further extend the defaults.
With Spring Boot 2.4 I'm struggling with the new "rules":
I can no longer load application-default.properties from application-<profile>.properties since spring.profiles.include is no longer allowed in non profile-specific documents [2].
I don't want to introduce a src/test/resources/application.properties since I don't want to repeat everything from src/main/resources/application.properties. Also I don't want to load any activate any test-related profiles in the app's properties.
It looks like one solution could be to explicitly add spring.profiles.include=default to src/main/resources/application.properties to force the application to include the properties file with default properties which will work as before when it comes to running the actual application but consider src/test/resources/application-default.properties when running the tests.
Is this the way to go or are there smarter solutions to tackle this problem and still keep the properties free of redundancies?
spring.profiles.active=dev
add this config in application.properties file

How to integrate spring profiles in Spring Boot 2.4+ application.properties

My current spring boot 2.3 and below config files are
application.properties
application-dev.properties
application-qa.properties
application-prod.properties
application-local.properties
I have to include the profile onlyLocal in my local profile and I have to include cloudProfile in all other profiles.
For spring boot 2.4+, I found that putting the below in my application.properties file works:
spring.profiles.group.local=local,onlyLocal
spring.profiles.group.dev=dev,cloudProfile
spring.profiles.group.qa=qa,cloudProfile
spring.profiles.group.prod=prod,cloudProfile
My question is, is there a better/cleaner way?
Using groups to aggregate multiple profile files into one profile is perfectly sound and agrees very nicely with the intentions of the Spring Boot team: https://spring.io/blog/2020/08/14/config-file-processing-in-spring-boot-2-4
Generally, you should think about whether the complexity of profile groups is really worth it. If the profiles cloudProfile and onlyLocal only yield a handful of properties, then it might make more sense to just copy them into the respective properties files. If the two profiles do contain a lot of properties, then the complexity is warranted and allows you to avoid duplication.
Another mechanism to import properties files into other properties files is using spring.config.import. But it's really doing the same with a different mechanism.

Separate properties file for multiple environments

I am trying to have separate property files for prod and dev environment.
I have two property files application-prod.properties, application-dev.properties placed in classpath:/config
I added VM option -Dspring.profiles.active=dev
According to what I understand from the documentation and many other references on the web, on accessing Spring Environment as environment.getProperty("") the property in "application-dev.properties" should be loaded. However, I am getting null and as it seems the property files are not read by Spring.
I also tried defining both the files in #PropertySource. Doing this, the file defined second is picked up and the corresponding property is returned. Spring is not choosing the file based on the active profile.
Am I missing something?
I also came across a issue raised through some SO questions, but I am not sure if it refers to the same problem.
Right, so documentation you are pointing to is from Spring Boot project. That is not the same as Spring Framework. If you are not using Spring Boot, -Dspring.profiles.active=dev wouldn't work.
You have two options:
Introduce Spring Boot to your project ans turn on auto-configuration (#SpringBootApplication or #EnableAutoConfiguration).
Use plain Spring Framework features like PropertyPlaceholderConfigurer, but it doesn't give you same flexibility as Spring Boot features and you will need to create some boilerplate code to handle various envs.

How to tell which spring-boot Autoconfigurers have been activated?

in a Spring Boot application, I am worried about AutoConfigurations also being triggered by transitive dependencies.
Specific autoconfigurations can be switched off as described here Disable Spring Boot AutoConfiguration for transitive dependencies
But how can I know which AutoConfigurations have been activated? There does not seem to be a consistent logging of activations on startup. I just noticed VelocityAutoConfiguration has been activated in my application, I can disable that, but it makes me worried about other autoconfigurations being activated without my knowledge and intent.
Definitely pay attention to those transitive dependencies.
There's about 5 or more different ways you can enable or view the #EnableAutoConfiguration report. The report will show you:
what's enabled
what's disabled
what's excluded
configurations that are unconditional
As an application argument
--debug
As a VM argument
-Ddebug
As an environment variable
export DEBUG=true // UNIX based
set DEBUG=true // Windows based
By adding a property to your application.properties
debug=true
Adjusting the log level in your application.properties
logging.level.=debug
Adjusting the log level of the report generator class in your application.properties
Spring Boot 1.x
logging.level.org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer=debug
Spring Boot 2.x
logging.level.org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener=debug
Starting your application with --debug will log an auto-configuration report that shows every auto-configuration class that was considered during startup and whether or not it was activated. Every class listed as a positive match has been activated and every class listed as a negative match has not been activated.
If your application's using Spring Boot's Actuator (it has a dependency on org.springframework.boot:spring-boot-starter-actuator), then, as mentioned in the question comments, you can also access the report over HTTP using the /autoconfig endpoint.

Categories