Reading configuration files in Java using various approaches
Introduction
- When we develop java applications, we parameterize our configuration by either passing them at runtime or keeping them separate from code by putting them in the configuration file.
- Config values can be anything like connection to server or how many time code should retry, what version to look for etc.
- Reading these files through code is a very common practice, it can either be a plan resource file read or abstracted with annotation, but one will find them in the code for sure.
- In this blog, my goal is to list down very simple approaches to reading config files in plain/vanilla java ( without any framework like spring boot or java ee )
Resource File
- Let’s say we have a JDBC connection config file that we would like to read to make our database connection.
- the database config file contains the bare minimum URL, user, and password. these values would be needed to make a JDBC connection.
jdbc-url="jdbc:mysql://dev-db-1:3306/u841536551_engineering_bl?enabledTLSProtocols=TLSv1.2"
db-username="root"
db-password="password"
- Let’s see how can we read this file in java.
Properties Class
- Java.util.properties provides properties util to store simple key-value parameter
- It provides helper methods like load, getProperty, and setProperty, which makes it a good candidate for setup our config data.
Reading Resource File
- Here we are defining the location of our resource file path. Since our application can reach to src file, we need to provide a relative path from the src folder.
- We read the file as FileInputStream and load it into the property. Now property will use this file and initialize the key-value pair as property.
- Once loading is done we can use the key to get the value of the property as shown in the below code
output
ClassLoader
- ClassLoader loads the files (java files, resource folder )in java project to JVM at runtime.
- We can use this ClassLoader class to get the resource file that we want to read from.
- In the below example we are using the getSystemResoureAsStream method to get the file that is under the resources folder, it returns the InputStream instance.
- Now we can use properties.load(inputstream) to load the key values from InputStream, we can do this because properties allow reading from InputStream.
- One of the other ways we can modify the above code is that we can use getSystemResource method on ClassLoader. This returns a URL Instance.
- Now, we can get a hold of URI from URL using toURI() helper, which now enables us to get a hold of the Path of the resource, because the Path Class takes uri and returns the path.
- Once we have the path of the resource we can use Files.readAllLines ( from java.nio.file.Files utility) to read the content of the file.
- Now we have a list of configs with us, which we can use to read and print it or load the properties instance with it to use further down in the code.
Using Third-Party Library
- A third-party library like google guava also provides a Resource class to read resources in Java Applications.
- First, add the below dependency in the pom.xml file and load/build the project so that you have a dependency in your project.
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
- Resources is the class that provides a helper method called getResource which can read config/resource files in resources folder in your java application.
- getResource method reads the URL. we need to use another method from the Resources class to read this resource into the String or we can use readLines method to get the List<String> object which contains each line in the file.
- Once we have list of string we can stream it and map it to key value pair and add it to java properties by using setProperty() method.
Code Repo
- Please find the git repository for this exercise here.
Conclusion
- We used Properties and Classloader to read resource files and setup them up as properties in the java application.
- Note that when we use a framework like spring boot there is a robust way to handle resource files using annotations themselves. That is for a future article.
- Also, keep in mind that some configuration values which are sensitive in nature like API key, username or password, or other credentials, they often not stored in the config file due to their sensitive nature. They are either overridden during the build process in the production environment from the local or remote production config file or they are kept in another storage system like a vault or database and read when needed.
- If you want to learn spring boot 3 and spring boot 6, please check out this best seller and highest rated course. [ 38 hrs content, 4.7/5 stars, 6+ students already enrolled]