Loading Properties File in Java

0

In this example we will see how to construct a Properties object by loading the property files from different sources using multiple class loaders. Given a resource name, it mostly tries to find the resources from the application’s classpath. The current Thread ClassLoader is given preference. Next preference is given to the class loader that has loaded the current class an then to the system class loader.

We want to load application.properties. For example sake, we have one application.properties in the classpath.

src/application.properties:

article=java properties loader
blog=xyz

And the second application.properties is in a jar file.

jar/application.properties:

blog=javarticles.com

The jar command that bundles the properties file as a jar file.

createJar.bat:

jar cfe app.jar app application.properties

We will create a custom class loader based on the above jar file.

CustomClassLoader:

package com.javarticles.properties;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

public class CustomClassLoader extends URLClassLoader {

    public CustomClassLoader(ClassLoader parent) throws MalformedURLException {
        super(new URL[] { new File(System.getProperty("user.dir")
                + "/jar/app.jar").toURI().toURL() }, parent);
    }
    
    public CustomClassLoader() throws MalformedURLException {
        super(new URL[] { new File(System.getProperty("user.dir")
                + "/jar/app.jar").toURI().toURL() });
    }

}

We will then set the custom class loader as the current thread’s context loader. Our example contains two instances of custom loader. The first one has the default parent which is the system class loader.

In the second instance, we set the parent to null which means its not going to delegate the call to its parent, so it will only return the resource found in the jar file and not the one in classpath.

Method findPropertyUrls() will return a collection of URLs matching the resource name. If no resources could be found, then this will be empty. Once we have the resources, we will iterate through each URL, open the stream, and load the properties file.

InputStream in = url.openStream();
properties.load(in);

PropertyLoaderExample:

package com.javarticles.properties;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Properties;

public class PropertyLoaderExample {
    Properties properties;
    
    public static void main(String[] args) throws MalformedURLException {
        Thread.currentThread().setContextClassLoader(new CustomClassLoader());
        PropertyLoaderExample propLoaderExample = new PropertyLoaderExample();
        propLoaderExample.load("application.properties");
        System.out.println("-----------------------------------------------------------");
        System.out.println("Fetch properties");
        propLoaderExample.printProperty("blog");
        propLoaderExample.printProperty("article");
        System.out.println("-----------------------------------------------------------");
        System.out.println("Reload properties with custom loader's parent set to null");
        Thread.currentThread().setContextClassLoader(new CustomClassLoader(null));
        propLoaderExample = new PropertyLoaderExample();
        propLoaderExample.load("application.properties");
        System.out.println("-----------------------------------------------------------");
        System.out.println("Fetch properties");
        propLoaderExample.printProperty("blog");
        propLoaderExample.printProperty("article");
    }
    
    void printProperty(String key) {
        System.out.println(key + "=" + properties.getProperty(key)); 
    }

    public void load(final String propertiesFileName) {
        final Properties properties = new Properties(); 
        Collection propertyUrls = findPropertyUrls(propertiesFileName);
        System.out.println("-----------------------------------------------------------");
        System.out.println("Start load property resources");
        for (final URL url : propertyUrls) {
            System.out.println("Load " + url);
            InputStream in = null;
            try {
                in = url.openStream();
                properties.load(in);
            } catch (final IOException ioe) {
                System.out.println("Unable to " + url.toString() + " exception " +  ioe);
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (final IOException ioe) {
                        System.out.println("Unable to close " + url.toString() + " exception " + ioe);
                    }
                }
            }
        }
        this.properties = properties;
    }
    
    private static Collection findPropertyUrls(final String resource) {
        System.out.println("Find property resources");
        final ClassLoader[] classloaders = {Thread.currentThread().getContextClassLoader(), 
                PropertyLoaderExample.class.getClassLoader(), ClassLoader.getSystemClassLoader()};
        final Collection propResources = new LinkedHashSet();
        for (final ClassLoader cl : classloaders) {
            if (cl != null) {
                System.out.println("class loader is " + cl);
                try {
                    final Enumeration resourceEnum = cl.getResources(resource);
                    while (resourceEnum.hasMoreElements()) {
                        URL url = resourceEnum.nextElement();
                        System.out.println("Add resource " + url);
                        propResources.add(url);
                    }
                } catch (final IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return propResources;
    }

}

As you can see in the first case where the custom classloader’s parent is the default class loader, the resource found in claspath is loaded first and then the resource from the jar file which is why the property file in jar overrides the key/value pair of the resource found in classpath.

In the second case, the custom class loader’s parent is set to null which means the resource in jar file will be loaded first and then the resource found in the classpath.

Output:

Find property resources
class loader is [email protected]
Add resource file:/C:/javarticles_ws/javaPropertyLoaderExample/bin/application.properties
Add resource jar:file:/C:/javarticles_ws/javaPropertyLoaderExample/jar/app.jar!/application.properties
class loader is [email protected]
Add resource file:/C:/javarticles_ws/javaPropertyLoaderExample/bin/application.properties
class loader is [email protected]
Add resource file:/C:/javarticles_ws/javaPropertyLoaderExample/bin/application.properties
-----------------------------------------------------------
Start load property resources
Load file:/C:/javarticles_ws/javaPropertyLoaderExample/bin/application.properties
Load jar:file:/C:/javarticles_ws/javaPropertyLoaderExample/jar/app.jar!/application.properties
-----------------------------------------------------------
Fetch properties
blog=javarticles.com
article=java properties loader
-----------------------------------------------------------
Reload properties with custom loader's parent set to null
Find property resources
class loader is [email protected]
Add resource jar:file:/C:/javarticles_ws/javaPropertyLoaderExample/jar/app.jar!/application.properties
class loader is [email protected]
Add resource file:/C:/javarticles_ws/javaPropertyLoaderExample/bin/application.properties
class loader is [email protected]
Add resource file:/C:/javarticles_ws/javaPropertyLoaderExample/bin/application.properties
-----------------------------------------------------------
Start load property resources
Load jar:file:/C:/javarticles_ws/javaPropertyLoaderExample/jar/app.jar!/application.properties
Load file:/C:/javarticles_ws/javaPropertyLoaderExample/bin/application.properties
-----------------------------------------------------------
Fetch properties
blog=xyz
article=java properties loader

Download the source code

This was an example about loading properties file in java.

You can download the source code here: javaPropertyLoaderExample.zip

About Author

Ram’s expertise lies in test driven development and re-factoring. He is passionate about open source technologies and loves blogging on various java and open-source technologies like spring.
You can reach him at [email protected]

Comments are closed.