I'd like to completely externalize my config files so that every *.properties file is in /etc/foo/.
But I don't want everything in one big application.properties so I split certain parts away into individual *.properties files.
How can I tell #PropertySource that it should resolve the location of the given property file exactly as it would do for its application.properties i.e. search for it in every directly (could be multiple) that I specified with "--spring.config.location"?
My class would ideally look this way:
#Configuration
#PropertySource("dpuProfiles.properties")
#ConfigurationProperties("dpu.profiles")
public class DpuProfilesConfiguration {
...
}
It does work if I explicitly specify "file:/etc/foo/dpuProfiles.properties".
I couldn't get "${spring.config.location}/dpuProfiles.properties" or similar substitution with EL working. Makes probably no sense either as the variable could contain multiple directories.
You can do it by specify the the config(s) directory in your -classpath and point it from classpath to your #PropertySource
For your case it will be
CLASSPATH=just_added_as_an_example_jar.jar:/etc/foo/
-classpath "$CLASSPATH"
But you need to change the #PropertySource value as follows
#PropertySource({"classpath:dpuProfiles.properties"})
#ConfigurationProperties({"classpath:dpu.profiles"})
Note - The above example is to run from script.
Related
I have application.yml, and I have a second file. It can be named anything, but I need to load from both of them. They won't have overlap, so overwriting is not a concern. Unfortunately, I cannot use profiles to separate the data and need two files.
For the file structure, I have:
src
main
resources
application.yml
layer2
secondFile.yml
I have tried:
Adding spring.config.additional-location to my application.yml. This never seems to load the second file. I have tried with both classpath and file, but I could be doing it wrong.
In the Application.java, changing main to use System.setProperty("spring.config.location", "{file and classpath attempts}"), as well as creating a new set of properties and passing them in to the SpringApplication before running it.
Is there something I am missing? I could be formatting the classpath or file selection wrong, but I am not sure how to go about testing that.
For the first style of attempt, application.yml is just:
spring:
config:
additional-location: "optional:classpath:/layer2/secondFile.yml"
Now I run JAR with this argument:
-Dspring.config.location=/opt/application-properties/application.yml
I want to add another one property file to location. How to do it?
If you read the documentation, i.e. section 2.3. Application Property Files of the Spring Boot Reference Documentation, you will find:
If you do not like application.properties as the configuration file name, you can switch to another file name by specifying a spring.config.name environment property. You can also refer to an explicit location by using the spring.config.location environment property (which is a comma-separated list of directory locations or file paths).
So, to explicitly answer the question:
To add another one property file to location, separate them with commas.
Example:
-Dspring.config.location=/path1/application1.yml,/path2/application2.yml
I'm really new to Spring and got some questions.
One is.. in my Java class i've got a declaration of an absolute Directory path, where some Images are saved. Now if I want to send my Project to a co-worker or a friend, he needs to change the ImagePath in my Java Code. So I want to use a generalized technique for it, that there is a File where you can just edit the Path and the Project just works like it should.
I have heard of the method where you set up an application.yml and a Configuration Class, but I actually don't know, what to write in these Files.
There are two options for your problem:
One is to use a relative path like src/main/resources and put the images there.
Another option is to set the file path in application.properties file like:
my.images.directory.path=path
And now you can use this property in your classes using #Value:
For Example:
#Value( "${my.images.directory.path}" )
private String imagePath;
Same thing you can also set in a application.yml file.
Also, there are other ways to set the property in the properties file and use it, which you can refer over here.
Hope that helps.
Spring has a number of options when it comes to externalising configuration. In your case, the best option would be to add a property to the application.yml file. Ensure that you add this file to the classpath of your application. Alternatively you can specify the location of this file using spring.config.location command line argument.
Here is a simple application.yml file,
images:
path:/usr/images
You can then create a configuration bean in your application to inject this property.
#Component
public class MyConfig {
#Value("${images.path}")
public String name;
}
Now replace hardcoded path in your application with MyConfig.name.
For a full list of options for externalising configuration, check out this link.
You can use #PropertySource as well. Add a file in /src/main/resources, let's say config.properties containing properties.
config.properties file
images.dir=/path/to/images/dir
In java class, say #Controller add #PropertySource as shown in test code and you will be able to access the property.
You will only be required to update the file
#PropertySource("classpath:config.properties")
#Controller
public class TestController {
#Value("${images.dir}")
private String defaultDb;
...
}
I am working with Java and spring boot. I was wondering how to add Property placeholders into .yml files. I've found some crisp examples but I am not sure where are the Property placeholders are being instantiated in. Is it in system env variables, a file, etc..?
Bootstrap.yml
spring:
cloud:
config:
username: ${my.stored.files.username}
password: ${my.stored.files.password}
label: ${spring.cloud.find.label}
uri: ${spring.cloud.config.uri}
enabled: false
failFast: true
User is using Property placeholders, but where did the user declared them?
Where is this .yml reading the values from? (same question as above)
Is there a document that explains the connection?
This web application will be pushed to cloud foundry using "cf push", Which will automatically pick manifest.yml file to configure. If possible a cloud foundry example would be great.
Understanding/ Sample Application.properties file
app.name=MyApp
app.description=${app.name}
User was able to use ${app.name} because it is defined. I am confused on the example above. How and where is the user getting "${my.stored.files.username}.
Where is that being defined? I assumed it would be in system.properties or environment variables. Can anyone confirm?
After intensive research, I was able to find that when I use placeholders in .yml files it reads that values from environment variables. Which was part of my theory in the beginning, but no one has confirmed.
Answer for local environment
spring:
cloud:
config:
username: ${my.stored.files.username}
password: ${my.stored.files.password}
label: ${spring.cloud.find.label}
uri: ${spring.cloud.config.uri}
enabled: false
failFast: true
*In environment variables *
set key as: my.stored.files.username
set value as: UsernameSample
Then
When you run application, yml will read like so.
config:
username: ${my.stored.files.username}
//gets replaced with UsernameSample
This is the link that solved my problem link
For Cloudfoundry
You would have to create cups or manually add these variables onto the service.
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files
SpringApplication loads properties from application.properties files in the following locations and adds 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).
You can also use YAML ('.yml') files as an alternative to '.properties'.
If you do not like application.properties as the configuration file name, you can switch to another file name by specifying a spring.config.name environment property. You can also refer to an explicit location by using the spring.config.location environment property (which is a comma-separated list of directory locations or file paths). The following example shows how to specify a different file name:
$ java -jar myproject.jar --spring.config.name=myproject
The following example shows how to specify two locations:
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
spring.config.name and spring.config.location are used very early to determine which files have to be loaded. They must be defined as an environment property (typically an OS environment variable, a system property, or a command-line argument).
If spring.config.location contains directories (as opposed to files), they should end in / (and, at runtime, be appended with the names generated from spring.config.name before being loaded, including profile-specific file names). Files specified in spring.config.location are used as-is, with no support for profile-specific variants, and are overridden by any profile-specific properties.
Config locations are searched in reverse order. By default, the configured locations are classpath:/,classpath:/config/,file:./,file:./config/. The resulting search order is the following:
file:./config/
file:./
classpath:/config/
classpath:/
When custom config locations are configured by using spring.config.location, they replace the default locations. For example, if spring.config.location is configured with the value classpath:/custom-config/,file:./custom-config/, the search order becomes the following:
file:./custom-config/
classpath:custom-config/
Alternatively, when custom config locations are configured by using spring.config.additional-location, they are used in addition to the default locations. Additional locations are searched before the default locations. For example, if additional locations of classpath:/custom-config/,file:./custom-config/ are configured, the search order becomes the following:
file:./custom-config/
classpath:custom-config/
file:./config/
file:./
classpath:/config/
classpath:/
This search ordering lets you specify default values in one configuration file and then selectively override those values in another. You can provide default values for your application in application.properties (or whatever other basename you choose with spring.config.name) in one of the default locations. These default values can then be overridden at runtime with a different file located in one of the custom locations.
After doing some research and experiments I found out placeholders can be both environment variables and command line arguments. The syntax for properties file worked in YAML file too. Environtment variable has already been explained by #Jesse. If you lets say pass command line argument:
--my.stored.files.username=UsernameSample or --username=UsernameSample, the configuration attribute would be filled as expected
my:
stored:
files:
username: ${username:defaultUsername}
I hope this might be helpful to someone having a similar issue.
ddsultan's answer works for me. just in case someone like me need to set placeholder value in idea. Edit run configuration, click Modify options, then check "Program options", in the newly added field, input the place holder value, for example "--section=4".
Please use {{your key}} as a place holder in case of .yml file
We are using a spring boot application, where properties are loaded from application.yml file instead of application.properties, located at src/main/resources/ which looks like below:
config:
host: localhost:8080
server: 123
And they are being pulled in a .java file like this
#ConfigurationProperties( prefix="config")
public class ConnectionImpl implements Connection{
#Value("${config.host}")
private Stringhost;
}
I am able to retrieve properties this way.
But we are trying to move the config properties from application.yml to a different .yml file which is located at a different location. (src/main/resources/env-config).
Now I am not able to retrieve properties same way, i.e, using #Value annotation. Is there any other annotation I need to add ?
From the documentation:
SpringApplication will load properties from application.properties (or application.yml) 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 class path root
If you don’t like application.properties as the configuration file name you can switch to another by specifying a spring.config.name environment property. You can also refer to an explicit location using the spring.config.location environment property (comma-separated list of directory locations, or file paths).
The default search path classpath:,classpath:/config,file:,file:config/ is always used, irrespective of the value of spring.config.location. This search path is ordered from lowest to highest precedence (file:config/ wins). If you do specify your own locations, they take precedence over all of the default locations and use the same lowest to highest precedence ordering. In that way you can set up default values for your application in application.properties (or whatever other basename you choose with spring.config.name) and override it at runtime with a different file, keeping the defaults.
You need to supply a command line argument that tells SpringApplication where specifically to look. If everything in resources/ is added to the classpath root, then your command line would look like:
java -jar myproject.jar --Dspring.config.location=classpath:/env-config/service-config.yml
If you have a general application.yml under resources/, the properties in there will still be loaded but will take a lower precedence to the properties file specified on the command line.
Your question doesn't really say what you intend to do, but if you want to have a different configuration for different environments (e.g. development, test, production), there is a simple solution for that.
Place your config files in a file hierarchy like this inside your project:
src/
main/
resources/
application.yml
application-development.yml
application-test.yml
application-production.yml
When you now start your application with
java -jar mySpringApplication.jar -Dspring.profiles.active=development
the configuration from application.yml will be taken as a "base layer", overridden by the configuration in application-development.yml. By this, you can have "default" settings for all environments in application.yml and environment-specific configuration in the application-ENV.yml files. The same works for test and production.
No.
You'll be in a much better position if you avoid hard-coding file path like that within your code base. #ConfigurationProperties used to have a locations attribute but it's deprecated and already removed in 1.5.
In Spring Boot, you configure the Environment which is a single source of truth for your configuration. Rather than having settings buried in code, you should configure Spring Boot to read the files that you want. Read the documentation for spring.config.location. If you want to do this in a more transparent manner, perhaps EnvironmentPostProcessor is what you need