I’m executing a jar and passing a properties file in args
java - jar file.jar props.properties
To read the properties file I’m using java.util.Properties.load. I want to know if there is a better way to do this with spring boot because properties file can exist in different locations or with different names but always the same properties.
I tried with PropertySource but I couldn’t find a way to set properties file dynamically
You can use:
java -jar app.jar --spring.config.location=file:///Users/home/config/jdbc.properties
More information here: https://www.baeldung.com/spring-properties-file-outside-jar
Related
I am new to Springboot and I am having trouble with externalizing my properties files.
I have multiple ".properties" files that I have kept in a subdirectory "config/". I have removed context-placeholders from my project and have included the comma-separated properties files while executing the jar.
eg. java -jar myjar.jar --spring.config.location=file:////config/PROP1.properties, file:///config/PROP2.properties -debug
I have few questions
Why are the files in the config directory not being read even after explicitly mentioning where to look?
I have my own dependencies in the project that have same-named properties files packed in its jar. Is that creating any sort of problem when SpringBoot tries to read the files from the config folder while executing my project jar?
Update
Now I am keeping only a single properties file suppose ABC.properties outside the jar in the same directory . I am using the name "ABC" instead of "application". I am using the below command
java -Dserver.log.dir=/path/to/log/dir -jar myjar.jar --server.port=9090 --spring.config.name=ABC --prop1=val1
I have overriden a property in my external property file but I don't see the overriden value being used when I run the application. My new questions are
Is there anything wrong with the command-line?
I have the following line in xml bean configuration
<context:property-placeholder location="ABC.properties" />. Is this causing any sort of problems to detect and use the external properties?
If the above is true and I have to remove the line how will SpringBoot understand from where the property values are to be imported?
(Not related directly to the question) Is there a order that I need to follow while giving command line arguments?
Spring boot has explicit indicate how to write this external configuration. See doc ref here: https://docs.spring.io/spring-boot/docs/2.5.2/reference/htmlsingle/#features.external-config.files
Basically, you need to specify the location like this:
--spring.config.location=classpath:/somefolder/somefile.properties
--spring.config.location=file:./somefolder/somefile.properties
From your command line, it seems that you are missing one dash, and also using a wrong format of file schema.
Q1: Why are the files in the config directory not being read even after explicitly mentioning where to look?
A1: If your config folder is beside your jar file, your command should be like
java -jar myjar.jar --spring.config.location=file:./config/PROP1.properties
meanwhile, you can also use the full path to target your config file.
Q2: If I don't mention the properties files names explicitly as an argument then they won't be picked up even when they are in the config directory
A2: No. See this doc, Spring Boot will try to find config files from the four places:
A /config subdir of the current directory.
The current directory
A classpath /config package
The classpath root
If spring.config.location is not set, files in these folders named application.properties will be treated as valid config file. You can change the accepted file name by setting property spring.config.name.
Q3 About Config File Priority
A3 As described in the doc mentioned earlier, if same name properties appear in different config files, locations higher in the list override lower items.
Another tip, it will be better to remove config files inside the jar file, so you can get a full view of configuration just in one place (the externalized config folder);
I need two application.properties in my Spring Boot App.
I know that using the annotation #PropertySource I can specify more than 1 property files.
I tried to use: #PropertySource({"classpath:application.properties","classpath:external.properties"})
The idea of it is having application.properties with the machine independent properties and this file will be included inside the war file.
The other file (external.properties), will leave in the machine, and won't be included in the war file. Here I want to leave properties like the database connection and so on.
I've already changed catalina.properties for adding the external.properties location into the classpath, but unfortunately when running on Eclipse it doesn't work (complains about the missing database properties.).
If the external properties file will be available in a known location on the machine, then have an environment variable, system property, or command-line argument set up with the path to the file. Then, reference the file in you #PropertySource annotation using file: rather than classpath:
Example: #PropertySource("file:${CONF_DIR}/external.properties")
References:
Spring boot docs on external configuration
PropertySource documentation
Blog post regarding PropertySource
Is there any way we can load .yml file using VM argument, like we load .properties file for log4j using -Dlog4j.configuration?
I looked for this but nothing useful found. All solutions are for Spring Boot. But I need to load yaml (from some directory which is not fixed) in an executable jar.
Sure. You can get any application parameters with
System.getProperty("my.property");
So if you start your application with
-Dmy.property=path/to/yaml/file
, in your code you can retrieve the value path/to/yaml/file as String and then you can load the file as YAML (for example, with SnakeYAML). The general case of loading YAML from a file is covered in SnakeYaml's documentation.
I am running my jar in the following way in unix
java -jar $classpath --spring.config.location=application.yml
And I am also using a properties file which I am configuring the following way:
#PropertySource("file:${DATASERVICE_PROPERTIES}")
Both application.yml and DATASERVICE_PROPERTIES have property
server.port
I want to use the server.port in application.yml.
I thought properties supplied via commandline has highest precedence(from below link), so why is server.port from DATASERVICE_PROPERTIES taken?
Spring Boot and multiple external configuration files
Properties supplied via command line override properties in src/main/resources/application.properties and in config/application.properties
Since you are specifying in the code the file to use this doesn't apply.
Why aren't you using on of the two property file location above ?
So you can remove your #PropertySource and your will be able to override your properties via command line .
By launching java with the -D option you can set System.properties.
Is there a way to specify a properties file as an option for java, which in turn read them as System.properties?
E.g.
java -Dfile ./alotof.properties
I'm building a webapp deployed in JBoss. The jboss xml configuration files accepts system properties as inline config {my.property}, which reads from the command line argument but this gets unruly as the number of properties grow.
You can read the properties file in bash (in run.sh file), parse properties and create the proper config line for JVM.
Here you can find 2 articles that can help you:
Reading Java-style Properties Files with Shell (permalink)
Reading java.properties file from bash
I don't know about giving a direct property file as an argument, but instead you can have startup class which loads at the bootstrap and overrides whatever property you want override from your property file using System.setProperty() method.
Java can't read system properties from a file, but JBoss can - use the SystemPropertiesService, configured through properties-service.xml in the deploy directory.