Externalized Configuration in Spring boot - java

I have a external configuration file(out side jar). I try to run and expected
that value in external file will override value in internal file(application.properties in \resource\ - in jar file).
I read Documentation and try this:
java -jar ccgame-1.0.jar --spring.config.location=classpath:/application.properties,file:/production.properties
This not working.
My jar file at \target\ directory and my production.properties too(at \target\)
How can I resolve my problem?
Where should I put external config file ?
And what I have to do ?

Starting from Spring Boot 2.0 it's possible to use property spring.config.additional-location. With this property, you can set external config file, but properties from that config will only override the corresponding ones from internal config, leaving other properties unchanged.
More about it in docs.
If you need to completely override the whole config, then continue to use spring.config.location property instead.

By convention, Spring Boot looks for an externalized configuration file – application.properties or application.yml – in 4 predetermined locations in the following order of precedence:
/config subdirectory of the current directory
The current directory
Classpath /config package
The classpath root
You can place your application.properties in any of the 4 locations without needing to give the location of application.properties while executing the jar. If you want to given any other custom location , then you will have to provide the path of the config location while executing the jar:
java -jar -Dspring.config.location=<path-to-file> myProject.jar
Source: https://www.baeldung.com/spring-properties-file-outside-jar

Related

springboot external configuration - profile specific configuration

According to the SpringBoot documentation, the order of configuration is as:
Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
Application properties outside of your packaged jar (application.properties and YAML variants).
Application properties packaged inside your jar (application.properties and YAML variants).
On my project I have a profile called "prod" and the following files:
application.yml (inside the jar)
application-prod.yml (inside the jar)
And I also want to override some of the properties using an external file. Since according to the docs, an external application.yml will be overridden by the internal application-prod.yml, I need to make sure that the external file is considered as a profile specific config file.
I have tried to use:
-Dspring.config.location=<my path>/application-prod.yml
and I have also tried:
-Dspring.config.location=file:<my path>/application-prod.yml
In all cases I get the value from the internal application-prod.yml
If I totally remove the internal config file then I get the value from the external (so I know that the config picks up the file).
I understand that this external file is considered as the equivalent to the generic application.yml and not a profile specific.
How can I configure it to be considered as a profile specific external config?
Found the answer:
You need to use a Directory externally to set the profile specific configuration files, not using the file directly and it needs to end in /. So it has to be:
-Dspring.profiles.active=prod
-Dspring.config.location=/<some-path>/config/ (any path that ends in /)
and in there have a :
application-prod.yml

Spring boot deployed as WAR on tomcat, How to Externalize application.properties for different profiles(Dev,Test,Staging,Prod)

I am in a scenario where I am deploying by spring boot as a WAR on tomcat. Here in this application I have application.properties which has database username/password , some URL which help in consuming rest services(urls vary depending on the environment). Now I need to get the DB credentials and URL's depending on the environment it is deployed to. how to achieve it.
On external container ex tomcat
You can pass configuration using Jndi variable in context.xml
This var override local property defined in application.properties
Or pass -Dspring.profiles.active=env
in tomcat startup script ,for select environment specific application.properties
if you prefer to have configuration inside the war
As per 24. Externalized Configuration it should be enough to place a profile specific properties e.g. application-dev.properties on the classpath. The property precedence is:
...
Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).
Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).
Application properties outside of your packaged jar (application.properties and YAML variants).
Application properties packaged inside your jar (application.properties and YAML variants).
...
This can however work slight differently if you are packaging as JAR as per 24.3 Application Property Files. The property precedence is:
A /config subdirectory of the current directory
The current directory
A classpath /config package
The classpath root
according to the discussion with Karol, I guess using properties sources referencing file system path should be ok:
#Configuration
#PropertySource("${mywebapp.config.dir}/application.properties")
public class SpringConfig {
}
And just path JVM args at the startup of tomcat like
-Dmywebapp.config.dir=file:/etc/mywebapp
This way you can deploy one application.properties different for each environment.
As for your comment:
#PropertySource(value={"file:C:/Users/foo/apache-tomcat-8.5.28/webapps/application.properties}"})
as it's a windows system path may you have to double backslash your path: C:\\Users\\foo ...
I am able to read the properties file from tomcat/webapp location
for every environment I can ask system engineers to drop the file at the location,
I dont know if its a good solution. Please suggest
#PropertySource(value={"file:C:/Users/foo/Downloads/apache-tomcat-8.5.28/webapps/application.properties"})

Why is Spring Boot's resource precedence ignoring my external properties files?

As part of a Spring Boot project I need to load certain properties file which, by default, is located under de src/main/resources directory. Also, I need to be able to, instead, load an external properties file (located at the root directory of the project). If this external file exists, the file path should be passed as command line property.
The file structure would be like this:
/app_project
Net.properties (external file)
/src
/main
/resources
Net.properties (default file)
The thing is that the dependency that makes use of those properties wouldn't work unless you copy/overwrite the contents of the external file into the file under the /resources directory.
UPDATED
So far I've tried:
loading the file as an external resource and loading it into a Properties object (https://docs.oracle.com/javase/7/docs/api/java/util/Properties.html)
saving the properties as System Properties
modifying the resource handler to look into other directories by overriding th addResourceHandlers() to include the location
Explicitly including the location of the file in the CLASSPATH with the -cp argument (as #veysiertekin suggested)
Loading it as a #PropertySource (as suggesed by #Nikolay Shevchenko)
Overriding the Spring Boot's config location with the spring.config.location (as suggested by #gWombat)
With all these methods I've tried, the file is indeed read and loaded but, at some point, and every time, the app resorts to the file under src/main/resources .
I suspect it may have to do with the precedence of the file (as described here https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html), but I just couldn't figure out what's happening.
Thanks in advance for your help.
Try smth like
#PropertySources({
#PropertySource(name = "default", value = "classpath:default.properties"),
#PropertySource(name = "external", value = "classpath:external.properties", ignoreResourceNotFound = true)
})
public class YourSpringBootApplication {
...
}
Based on the official doc, you can try to use the propertyspring.config.additional-location to add additional config file , or spring.config.location to override default file location.
You should pass those properties as program arguments so that Spring can use them on application startup.
When spring-boot project is running, it checks files under the builded jar file. You need to add your external file to classpath before running the application:
java -cp 'path-to/spring-boot-application.jar:Net.properties' test.SpringBootApplicationMain

spring boot: add new yml files to application config

i want developers to be able to locally override some configuration properties. (let's say we work on google drive and everyone should test it on its own account).
i don't want to override properties using command line (because it has to be set inside every IDE configuration and on every CLI run).
what i want is: application should use all the standard spring boot config files (application.yml etc) and also look for e.g. local.yml (on the classpath) or some file inside user.home. and those additional files should override other settings.
how to add new yml resources and order them correctly?
edit: i know spring's default orders and locations. question is about adding new ones
If you look in the Spring Boot documentation about the locations for configuration files (http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config), you can see, that they are loaded from the following places (amongst others):
Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
Application properties outside of your packaged jar (application.properties and YAML variants).
There are two default locations where they are loaded from ( see http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-application-property-files):
A /config subdirectory of the current directory.
The current directory
Current directory in this case means the working directory for the Java process (Usually the directory where the JAR is located, or in case of running with in the IDE, usually the project root folder). So the developers just can place their own configuration files in that places and they are automatically loaded (and will override properties within the JARs). Add that files to .gitignore (or .svnignore or ...) and they won't accidentally committed into your repository.
There's a new way to do this, after Spring Boot v2.4, by using spring.config.import: https://spring.io/blog/2020/08/14/config-file-processing-in-spring-boot-2-4#importing-additional-configuration
By adding this part to your application.yml file, you should be able to import the additional configuration:
spring:
config:
import: local.yml
The article also has this section:
Imports can be considered as additional documents inserted just below the document that declares them. They follow the same top-down ordering as regular multi-document files: An import will only be imported once, no matter how many times it is declared.
So the contents of local.yml should be handled as if they were appended to the end of application.yml, thereby allowing you to override any property in application.yml.
From Spring Boot Documentation : Application property files:
SpringApplication will load properties from application.properties files in the following locations and add them to the Spring Environment:
A /config subdirectory of the current directory.
The current directory
A classpath /config package
The classpath root
The list is ordered by precedence (properties defined in locations higher in the list override those defined in lower locations).
This also goes for yaml, so you everyone can add application.yml under config directory, under the directory you run the spring boot jar from.
You can also customize the extra configuration file to be local.yml if you'd like by using spring.config.location:
--spring.config.location=classpath:/application.yml,classpath:/local.yml
Note however:
spring.config.name and spring.config.location are used very early to determine which files have to be loaded so they have to be defined as an environment property (typically OS env, system property or command line argument).
To provide the configuration from external config file in spring-boot application -
-Dspring.config.location=file:/home/vfroot/Workspace/project/MODULE_HOME/application.yaml
this command can be run with terminal:
mvn clean install -Dspring.config.location
= file:/home/vfroot/Workspace/MODULE_HOME/application.yaml
or need to set in Eclipse VM argument.
Also to set the active profiles :
-Dspring.profiles.active=dev
Well, since i am new in Spring Boot & Restfull Web Services. However, i managed to add a new .yml file to mange database and server port.
Instructions that i followed:
Project File.
Other Sources
src/main/resources
default package
right click on "default package"
add new YAML FILE
Or of YAML File option not available
5. right click on "default package"
6. then in categories: other --> File Types: YAML File

Add configuration directory to classpath using spring boot

I would like to add a configuration directory to the classpath for a spring boot application at start up, so it can load xml files from the configuration directory.
ie /var/application/config contains
test.xml, dev.xml
The xml will contain mapping information that is required by the application; this is different from application.properties.
I would like to load them at startup.
I am using ClassPathResource to load the files.
Please advise.
You can define your own classpath by the command-line. Lets suppose your jar is myapp.jar and you wand add one extra directory /var/application/config/, so you can execute with the following command line:
java -cp myapp.jar:/var/application/config/ -Dloader.main=myapp.Application org.springframework.boot.loader.PropertiesLauncher
ps: if you are using Windows use ; instead of : to separate your classpath items.
From the Spring Boot Reference Guide, add your config location:
java -jar myproject.jar --spring.config.location=classpath:/var/application/config/

Categories

Resources