Finding Items in the Classloader

I recently had a project in which I needed to implement a plug-in framework to provide extensibility.

My goal was to have plugins that are automatically identified by the application so that the simple act of adding the plugin jar file to the application’s classpath would allow the application to pick up and register the plugin.

I’m sure this isn’t rocket science, but I didn’t find any examples on the web.

In order to make this work, I implemented a standard for my application plugins. Each plugin jar file must contain a META-INF/plugins.xml file which defines the plugins contained in the jar. I won’t get into the details here. The plugins.xml file is read by the plugin manager which handles registration of plugins and serves as a factory.

The trick was in identifying all of the various plugins.xml files on the classpath. In order to do this, I wrote the following code:

   /**
     * @param resource   Name of resource(s) to find in classpath
     * @return List<URL> containing URLs to each instance of resource in classpath
     */
    public static List<URL> getResources(String resource)
    {
        List<URL> lst = new ArrayList<URL>();
        try
        {
            Classloader loader = Thread.currentThread().getContextClassLoader();
            Enumeration resources = loader.getResources(resource);
            while (resources.hasMoreElements())
            {
                lst.add((URL)resources.nextElement());
            }
        }
        catch (IOException e)
        {
            log.error("Error loading resources from classloader", e);
        }
        return lst;
    }

Having written this utility, I can call:

   List<URL> urls = getResources("META-INF/plugins.xml");

and retrieve a list containing the paths to the plugins.xml files in all of the plugin jars in the current thread’s classloader.

Since each of the elements in the list is a URL, it’s a simple matter to retrieve and process all of the plugin configurations in the application.

Note that in order for this to work on Oracle’s OAS App Server, or on OC4J, I was required to put the plugins.xml file inside the META-INF directory rather than at the top of the jar file. I don’t think that Tomcat had that limitation, but I’d recommend placing it in META-INF as that seems to work with both containers.

Leave a Reply

Your email address will not be published. Required fields are marked *