not idle

Netbeans Classloaders

by Gregor Berginc

Netbeans classloader system consists of three types of classloaders, namely module classloader, system classloader and original classloader. Usually, module classloaders are used to load classes and resources from within the module itself. However, there are situations when you need to access classes and/or resources from other modules.

Imagine two modules, A and B. Class Ca from module A implements a logic to load and render an icon somewhere on the screen. Class Cb from module B extends Ca. Let’s look at a simplified example.

Here is a simple implementation of Ca in module A.

package module.a;
 
public class Ca
{
    public Ca(String resource)
    {
        Class c = Ca.class;
 
        Object result = c.getResourceAsStream(resource);
 
        // Do whather you need to do with the resource.
    }
}

And class Cb in module B.

package module.b;
 
import module.a;
 
public class Cb extends Ca
{
    public Cb(String resource)
    {
        super(resource);
    }
}

Module B also contains icons that need to be loaded and rendered by superclass Ca. For this to compile, module A first have to define public packages that are visible to other modules, and module B has to add a dependency on module A.

As you can see from the code above, Cb constructor passes the resource to its superclass. This is not a problem… Until we specify a resource that does not reside in module A! As soon as we request a resource from module other than module A, we are presented with a null pointer exception. That is because the module classloader only uses resources from the module.

System classloader to the rescue. In cases when this is required, we can use a system classloader instead of the module classloader. To get the system classloader, one should simply use appropriate lookup like in the example below.

package module.a;
 
public class Ca
{
    public Ca(String resource)
    {
        Class c = Ca.class;
 
        Object result = c.getResourceAsStream(resource);
 
        // If result is null, the resource might be from
        // a different module --> try using system 
        // classloader
        if (result == null)
        {
            ClassLoader cl = Lookup.getDefault().
                lookup(ClassLoader.class);
            result cl.getResourceAsStream(path);
        } // if
 
        // Do whather you need to do with the resource.
    }
}

And that’s it.

Leave a Reply