Can you source one properties file inside another - java

I have a file where we store common properties.
Multiple applications are using these when creating beans while every application has their own properties file also. Is there a way to source the common file from the application specific files when working with Java?
I tried sourcing the file and that does not work. Here is what I tried.
common.properties
password=abcd
application.properties
. /etc/application_dir/common.properties
application_log_file=/tmp/app.log
I want to read only application.properties in my code and get the properties from common.properties loaded also.
One way is to add common.properties to classpath for the beans also but I want to check if there is a cleaner option like above with only changes in the properties file.

Short answer: no you can't. But here are some ideas that might help you solve your problem.
A Java Properties object can be created with another one to supply defaults.
You can call load or loadFromXML multiple times on the same Properties object to "overlay" the contents of one properties file over another.
Non-XML properties files can have comments introduced by a #. So you could invent a special comment for "sourcing" a property; e.g.
#source /etc/application_dir/common.properties
and then parse your properties file(s) to pull out the "source" directives before loading the properties files.
XML properties files can have <comment> elements which could be used (abused) in the same way.
No ... sorry ... I'm not going to provide code samples.

Related

Load all property files with unknown names from a directory in Spring Boot

I have a Spring Boot (2.6.5) application that has a build in default property file (contained in the jar).I also specify an external property file by using --spring.config.additional-location=/data/config/myapp.properties.
This works as expected, both files are loaded and properties of both files are used where the external pairs override the internal in the case of duplicate keys.
Now I want to split up the myapp.properties into multiple smaller property files. The reason for this is that they are created by a Kubernetes configMap, and some parts are used in multiple applications, so it makes sense to split those in smaller files instead of duplicating everything.
I tried to set the parameter to a directory, like --spring.config.additional-location=/data/config/ and then placing the various .properties files in this directory. However, when I do this, Spring will no longer load the files. So it seems that when I don't specify a specific filename, it only scans for application.properties.
How can I configure Spring to look for and load all files of type .properties in the given directory? I could specify each file individually, but that would require me to always keep track of the files that are present which is difficult to maintain.
Reference: features.external-config.files.wildcard-locations
In your case if you use --spring.config.additional-location=file:data/config/*/ then the files like data/config/first/application.properties and data/config/second/application.properties will be loaded.
Note: If you have a different config.name, like --spring.config.name=myapp
then all the directories should contain myapp.properties

What default values should the properties have in application.properties file in Spring

I am trying to figure out how to manage configuration profiles in my spring project.
I want to use different .properties files for different environments. There's a specific application-profileName.properties file for each environment and an application.properties file that is common for each environment. Sensitive data will only be contained in profile specific files.
I want to create a repository on GitHub. Only the common properties file will be added to the repository. Obviously, other people who want to run my project cloned from GitHub will have to create a properties file for their own profile, but then I need to somehow tell them which properties should be defined in the profile specific properties file. I don't want to list and describe this in the README, so I'm going to put stubs like this in the main properties file:
spring.datasource.url = YOUR_DATASOURCE_URL
spring.datasource.username = YOUR_DATASOURCE_USERNAME
spring.datasource.username = YOUR_DATASOURCE_PASSWORD
Thus, the person who cloned my project will be able to replace these values with his own in the main properties file, or create his profile specific properties file and override these values there.
Is this the right way to deal with the problem, and what are the common practices that apply in this situation?
Defining common properties across different profiles in the application.properties file is the correct way to go about it. You can have a setup like this:
src
main
java
-- your src files here --
resources
application.properties
application-sample.properties
pom.xml
If you want your code in GitHub to be useful to others, a clear documentation on how to use it should be given in the README.md file. But the call is left up to you. Remember that any popular Open Source project that has source code out there in GitHub became popular because people could understand the intend behind its creation. It is not always possible to read the code like a poem and understand what the original author intended to do.
You can mention
spring.profiles.active=yourprofilehere
inside your application.properties or you can ask user to create a new profile out of the sample profile provided and then pass the argument
--spring.profiles.active=yourprofilehere
as command line argument while running the jar built out of your codebase.
It would be great if you explain in README.md file that the person who clones will also have to edit pom.xml to include the new profile details if he intend to create a separate profile for himself.
P.S. I tend to remember what I wrote few weeks ago in my code only because it is immensely commented by myself. Otherwise I would end up asking which idiot wrote that.

How exactly works this properties file that "include" some other properties file?

I have the following doubt related a Java properties file.
Into a project I have a config.properties file that contains something like these lines:
Mailer=C:/Projects/MY-PROJECT/src/config/mailer.properties
Upload=C:/Projects/MY-PROJECT/src/config/upload.xml
Soap=C:/Projects/MY-PROJECT/src/config/soap.xml
Libretto=C:/Projects/MY-PROJECT/src/config/libretto.properties
So what is the exact meaning of these lines into a properties file? I think that is how I am including the content of 2 .properties file (mailer.properties and libretto.properties) and of 2 .xml file (upload.xml and soap.xml)
Is it right or is it a wrong interpretation?
Tnx
Properties is a very simple format and does not support any kind of import. Such logic (if required) must be implemented at application level.
This means that exact meaning of properties file snippet that you posted can be discovered by examining code of your application. I suppose that this file contains references to other files, so somewhere in your application exists code that parses this file, extracts paths to other files and reads them too.

Java Properties - Global and local properties

So I'm beginning to use the Java Properties class in order to set key-value pairs for my project. The way I'm designing my project is so that there are default properties which will be created using a config file as well as another config file for either overwriting or adding additional properties. The default config file will be in my Eclipse MainFramework project while the other config file will be in the local project where tests are stored.
MainFramework
Validation
TestProject1
TestProject2
In this example, MainFramework has the default config file and each TestProject may or may not have it's own local config file. Is there a way to have my desired functionality through Java's Properties class.
The java properties object is a Hashtable. If you read the properties for your main configuration file and then read a second properties file into the same object it will override the existing properties if they exist in both places, or add new ones if they don't already exist. Properties that are only found in the original file will remain as well.
How about using a 3rd party configuration library to achieve this?
Typesafe's config supports the usage of properties files, and can handle merging a global configuration with a subconfiguration, among many other features.
Apache commons configuration also supports property files as configuration sources and mechanisms for combining different sources.
I personally found Typesafe a bit easier to understand and use, but have a look at some examples to see what fits your style. They are both available through maven.

Simulate app.config for Java?

I know that you can use java.util.Properties to read Java properties files.
See: Java equivalent to app.config?
Is there a standard place to put this file? In .NET we put application.exe.config in the same directory as application.exe. The application looks for it here by default.
Java can be made to look for a properties file in the class path but I am struggling to understand the filename/path structure to use and how to use either a standard .properties format or XML format file.
Assuming I have an API packaged in org_example_api.jar (the root package is org.example.api). I don't want to put the properties file inside the jar as it should be editable by the user. I want the user to be able to put the required configuration properties in either a .properties or .xml file somewhere relative to the classpath so I can find it without needing to know anything about the ir file system structure.
Will this work on all systems:
/classpath/org_example_api.jar
/classpath/org/example/api/config.properties OR
/classpath/org/example/api/config.xml
Code:
java.util.Properties = ? //NEED SOME HELP HERE
This purely depends on the type of application you are developing.
1) If it is a web application the best place is inside the WEB-INF/classes/ folder.
2) If you are developing a standalone application there are many approaches. From your example I think the following structure will work.
/<dist>/org_example_api.jar
/<dist>/config.xml
/<dist>/run.sh
In the run.sh you can start the java application providing the current directory also in the classpath. Something like this.
java -cp .:org_example_api.jar ClassToExecute
3) If it is an API distribution it is up to the end user. You can tell the user that they can provide the config.xml in the classpath which should follow some predefined structure. You can look at Log4J as an example in this case.
The world is wide open to you here. The only best practice is what works best for you:
Whatever program the user is running can require the path to the properties file as an argument
Your application can be configured to look in the current directory for config.properties.
If the file can't be found, you could maybe fall back to the user.home directory, or fall back to wherever your application is installed.
Personally I usually have my applications attempt to read properties files from the classpath - but I'm not in a world where I have end-users update/change the file.
Whatever option you choose, just make sure you clearly document it for your users so they know which file to edit and where it needs to be!
You can put the properties file in a directory or JAR in your CLASSPATH, and then use
InputStream is = getClass().getResourceAsStream("/path/goes/here");
Properties props = new Properties();
props.load(is);
(I noticed you mentioned this in your OP, but others may find the code useful.)

Categories