A Dependent Spring boot project application.properties not injecting default values - java

I have two spring boot projects, Project A and Project B, each with its own application.properties.
When the project is run individually the values from application.properties are injected properly. But when I am using one of the Project B as a dependency in Project A, the default values defined in application.properties of B are not being injected and I have to define the same properties again in the .properties file of A which is kind of redundant.
How do I avoid this? I want the default values in the properties file of B to be injected and I would only want to define the properties for B when I want to override the default values. Sorry for my english

AFAIK, there is no out-of-box solution for this. I would recommend two solutions and you can go with one more feasible for you:
Take out all properties common for all projects and put them in a seperate properties file, use them with #PropertySource.
Use spring cloud config to store common(or all) properties. You can also have some custom logic there to pick the correct property among multiple property files.

It's hard to say without your code provided. I guess you can try to use multiple .properties files for Project A application like following:
#PropertySources({
#PropertySource(name = "propsA", value = "classpath:propsA.properties"),
#PropertySource(name = "propsB", value = "classpath:propsB.properties")
})
public class ApplicationA {

Related

How to set properties value in multi-module project?

I have a multi-module Spring Boot Gradle project. I have properties in each module yml file that point to database: user, pass, url.
It's working solution, but it's difficult to change project database. Every time I want switch database user or url, I must change 10+ yml files.
How to avoid this?
You could bind the properties in a class (see here: https://www.baeldung.com/configuration-properties-in-spring-boot) and inject the class where needed.

SpringBoot library project does not see main app properties

I have a setup like this:
Main SpringBoot project with application-default.properties which on our deployment server are partially overwritten by a deployment specific properties.
Shared SpringBoot library project which has its own properties.
And when I run my main project with the library project attached (via gradle sourceControl gitRepository) I can see that the properties in the library project are empty.
How can I make the library project use the properties passed down from the main application ?
If you want to merge properties, please consider this official page.
Option 1 - default properties in library
As I found previously (probably, it is fixed), if you have jar1 and jar2 (sorted alphabetically) and both of them have application.properties file, only first will be used. They aren't merged. So please be carefully there.
However you can use #PropertySource in your library, e.g. put default properties there into the custom file name (for example - defaults-for-jar2.properties or something like this, to avoid automatic loading by Spring).
In this case:
Property load logic outside of your library will be the same with current.
Your library will load file from #PropertySource and next they will be overridden (if you have this) by your application.
Option 2 - configuration properties
If you use Kotlin and Spring, you can use ConfigurationProperties. And you can define the default values there. Moreover, IntelliJ Idea will highlight the default and possible values (according to the type, because you can use not only String, but any custom enum class, Duration class, etc.).
Just from that link:
#ConstructorBinding
#ConfigurationProperties("blog")
data class BlogProperties(var title: String, val banner: Banner) {
data class Banner(val title: String? = null, val content: String)
}
#SpringBootApplication
#EnableConfigurationProperties(BlogProperties::class)
class BlogApplication {
// ...
}
Please note:
You should mention your settings data class in the library configuration.
You should configure kapt properly to have Intelli Sence in IDEs.

How to override Spring Boot library properties?

I would like to override the library properties that I've written in project that is using it. I'm using this Spring guide on creating library: https://spring.io/guides/gs/multi-module/
I would like to know how to override for example my.properties file in the project that uses my library.
Is it even possible?
Do not add application.properties files to a library. It could cause a myriad of problems. If you want to set a default property do it like this:
#ConfigurationProperties("foo")
public class FooConfig {
private int bar = 999;
// getter / setter
}
Every application should configure the library values for itself in its own application.properties file.
Seems you cannot. Since Spring itself also cannot
In the sample above we have configured the service.message for the test using the default attribute of the #SpringBootTest annotation. It is not advisable to put application.properties in a library because there might be a clash at runtime in the application that uses it (only one application.properties is ever loaded from the classpath). You could put application.properties in the test classpath, but not include it in the jar, for instance by placing it in src/test/resources.
Spring Boot property order precedence is described here:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
From the link:
Spring Boot uses a very particular PropertySource order that is designed to allow sensible overriding of values. Properties are considered in the following order:
The order is 1-17 then. For example, 4 on the list (command-line arguments) overrides 15 on the list (your application.properties file) and so on.
Depends on how the library property file specifies properties. If the properties are looked up from environment/system first, then you can override in your code. If hard-coded, then not.
For example:
prop=${ENV_VAR:abc}
You can set ENV_VAR environment variable, or env-var system variable in your code to override the value of prop. If you don’t, the default value abc will be used.

application.properties file from child application not override application.properties file in main application

I am new to spring boot,I have a confusion that , when all the property source in spring application like application.properties , my.properties,application-{profile}.properties goes into Environment, then why don't they get override. if there are some common key in two different properties file.
e.g., If I create one child project and have one application.properties in it and having propety let say 'name=child' and create the jar of this project and add this jar to my main project and main project also having an application.properties file with same key but different value, let say
'name=parent'
if I use Envionment class in spring and get env.getProperty(key) then it is showing parent.
Acc to me it should be 'child' because if all property are going to same place then two same key with different value cannot exist.
And also I have confusion of Ordering of properties file. Does it mean if it get property in first file then it will not got to second file to search for that propety?
Spring boot has an order for evaluating all property sources. They are listed here: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
So basically, Spring knows about all the properties it needs to source. It will then evaluate where to get them. In your case, it evaluates your {profile}.properties file first. If it can't find what it needs, then it will go into your regular application.properties. So if you are expecting your application.properties values to overwrite the {profile} one, it's not going to.

tokenize application.conf in play java app

I want to tokenize a few keys in my application.conf file to use variables from another properties file. How can I do so? Here is an example.
my-play-project/conf/application.conf
db.default.url=${env.db.url}
db.default.driver=${env.db.driver}
db.default.user=${env.db.user}
db.default.pass=${env.db.password}
my-play-project/conf/env/devlab/project.properties
db.url=myoracleserver.lab.org:1521
db.driver=oracle.thin
db.user=myname
db.password=mypassword
my-play-project/conf/env/devlab2/project.properties
db.url=myoracleserver2.lab.org:1521
db.driver=oracle.thin
db.user=myname
db.password=mypassword
Q. Is there a way to set devlab/project.properties to be part of system resolvable properties?
Play's configuration uses Typesafe Config. There are several ways of combining configuration together on the classpath and at runtime.
Creating multiple application.conf and application.properties files and putting them all on the classpath (i.e. in different JARs). The configuration will be combined. See Standard Behavior.
Using includes to pull in files with different names.
Using substitutions to pull in values from other config files.
Using substitutions to pull in environment variables or system properties.

Categories