How to Load Resources from Classpath in Java with Example

Classpath in Java is not only used to load .class files, but also can be used to load resources e.g. properties file, images, icons, thumbnails, or any binary content. Java provides API to read these resources as InputStream or URL. Suppose, you have a properties file inside config folder of your project, and you want to load that properties file, how do you do that? Similarly, you have icons and thumbnails for your web applications on icons directory of your project, how do you load them? Answer is by using java.lang.Class’getResource() and getResourceAsStream() method. These method accepts path of resource as String and returns URL and InputStream respectively. You can obtain a reference of Class by calling either getClass() method or by using class literal. If you have an object, then you can call getClass() because its a non-static method, on the other hand, if you don’t have any object, you can simply use .class with name of any class e.g. Sample.class will give you reference of java.lang.Class. These methods are available from JDK 1.1 and you can even use them anywhere you have access to core Java library. If you are creating J2ME games or application, you can use these method to load icons and tiles for your game, and all other resource for your application as well.

How does getResourceAsStream works

Internally this method delegate the loading request of resource to its class loader. If you call getResourceAsStream() method on an object which is loaded by BootStrap ClassLoader then it will delegate it to ClassLoader.getSystemResourceAsStream(java.lang.String) method. We pass path of resource to this method but rules for searching resources associated with a given class are implemented by the defining class loader of the class. Since you can pass both absolute and relative path to Class.getResourceAsStream(), but ClassLoader.getResourceAsStream() takes an absolute path, that’s why an absolute resource name is constructed from the given resource name using following algorithm :

If the name begins with a ‘/’ (‘\u002f’), then the absolute name of the resource is the portion of the name following the ‘/’. Otherwise, the absolute name is of the following form:
modified_package_name/name where the modified_package_name is the package name of this object with ‘/’ substituted for ‘.’ (‘\u002e’).

This means, the resource name passed to the method should look like /com/abc/config/app.properties if the app.properties is stored in the com.abc.config package instead of the current class’s.

If you look at the code of java.lang.Class in Eclipse IDE by using short-cut Ctrl+T and typing java.lang.Class, you can see how this method works :

 public InputStream getResourceAsStream(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResourceAsStream(name);
        }
        return cl.getResourceAsStream(name);
}


This algorithm is implemented at resolveName() method, as seen below :

  /**
     * Add a package name prefix if the name is not absolute Remove leading "/"
     * if name is absolute
     */
    private String resolveName(String name) {
        if (name == null) {
            return name;
        }
        if (!name.startsWith("/")) {
            Class c = this;
            while (c.isArray()) {
                c = c.getComponentType();
            }
            String baseName = c.getName();
            int index = baseName.lastIndexOf('.');
            if (index != -1) {
                name = baseName.substring(0, index).replace('.', '/')
                    +"/"+name;
            }
        } else {
            name = name.substring(1);
        }
        return name;
    }

 

loading resources from classpath in Java
Main problem comes while loading resource using getResourceAsStream() method is NullPointerException, because this method return null if its not able to find the resource. In following example, we have a Eclipse project, and I have created a properties file called app.properties inside config directory. Now to load that file, I just need to pass “app.properties”, if I pass anything like “config/app.properties” or “/config/app.properties” getResourceAsStream() will return null, and code will subsequently throw NullPointerException as shown below :

Exception in thread "main" java.lang.NullPointerException
    at java.util.Properties$LineReader.readLine(Unknown Source)
    at java.util.Properties.load0(Unknown Source)
    at java.util.Properties.load(Unknown Source)
    at Test.main(Test.java:29)

to avoid this error you must check output of getResourceAsStream() before using it, defensive programming is there just because of this kind of methods.

Java Program to load Resource from Classpath

Here is our complete Java program to load images, resources, text file or binary file from classpath in Java, resource can be anything, what is important is that it must be accessible.

package test;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

/**
 * Java Program to demonstrate how to load resources e.g. properties file from
 * classpath. There are two ways to load resources in Java, one by using
 * getResourceAsStream() and getResource() method from java.lang.Class. Main
 * difference between these two methods are that one returns an InputStream
 * while other returns a URL object.
 *
 * @author Javin Paul
 */
public class ResourceLoader{

    public static void main(String args[]) {

        // loading resource using getResource() method
        InputStream in = Test.class.getResourceAsStream("app.properties");

        Properties config = new Properties();
        try {
            config.load(in);
            System.out.println(config.getProperty("name"));
            System.out.println(config.getProperty("version"));

        } catch (IOException e1) {
            e1.printStackTrace();
        }

        // loading resource using getResourceAsStream() method
        URL resourceURL = Test.class.getResource("app.properties");
        Properties appConfig = new Properties();
        try {
            appConfig.load(resourceURL.openStream());
            System.out.println(appConfig.getProperty("name"));
            System.out.println(appConfig.getProperty("version"));

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

Output:
SampleApp
1.0.0
SampleApp
1.0.0

If you look closely you will find that we have used both getResource() and getResourceAsStream() method to load resource from classpath in Java, in this case just properties file. First example looks more cleaner than second example because we don’t need to open an explicit stream, getResourceAsStream() method returns an InputStream, which can be used anywhere. That’s all on how to load resources from class-path in Java.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


9 × = eighteen



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close