alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Groovy example source code file (RootLoader.java)

This example Groovy source code file (RootLoader.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Groovy tags/keywords

class, class, classloader, classnotfoundexception, classnotfoundexception, exception, hashmap, map, net, network, rootloader, rootloader, string, url, url, urlclassloader, util

The Groovy RootLoader.java source code

/*
 * Copyright 2003-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.codehaus.groovy.tools;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map;
import java.util.HashMap;

/**
 * This ClassLoader should be used as root of class loaders. Any
 * RootLoader does have it's own classpath. When searching for a
 * class or resource this classpath will be used. Parent
 * Classloaders are ignored first. If a class or resource
 * can't be found in the classpath of the RootLoader, then parent is
 * checked.
 * <p/>
 * <b>Note: this is very against the normal behavior of
 * classloaders. Normal is to first check parent and then look in
 * the resources you gave this classloader.
 * <p/>
 * It's possible to add urls to the classpath at runtime through
 * {@link <a href="#addURL(URL)">addURL(URL)}
 *      <p/>
 *      <b>Why using RootLoader?
 *      If you have to load classes with multiple classloaders and a
 *      classloader does know a class which depends on a class only
 *      a child of this loader does know, then you won't be able to
 *      load the class. To load the class the child is not allowed
 *      to redirect it's search for the class to the parent first.
 *      That way the child can load the class. If the child does not
 *      have all classes to do this, this fails of course.
 *      <p/>
 *      For example:
 *      <p/>
 *      <pre>
 *       parentLoader   (has classpath: a.jar;c.jar)
 *           |
 *           |
 *       childLoader    (has classpath: a.jar;b.jar;c.jar)
 *       </pre>
 *      <p/>
 *      class C (from c.jar) extends B (from b.jar)
 *      <p/>
 *      childLoader.find("C")
 *      --> parentLoader does know C.class, try to load it
 *      --> to load C.class it has to load B.class
 *      --> parentLoader is unable to find B.class in a.jar or c.jar
 *      --> NoClassDefFoundException!
 *      <p/>
 *      if childLoader had tried to load the class by itself, there
 *      would be no problem. Changing childLoader to be a RootLoader
 *      instance will solve that problem.
 *
 * @author Jochen Theodorou
 */
public class RootLoader extends URLClassLoader {

    private Map<String, Class> customClasses = new HashMap();

    /**
     * constructs a new RootLoader without classpath
     *
     * @param parent the parent Loader
     */
    private RootLoader(ClassLoader parent) {
        this(new URL[0], parent);
    }

    /**
     * constructs a new RootLoader with a parent loader and an
     * array of URLs as classpath
     */
    public RootLoader(URL[] urls, ClassLoader parent) {
        super(urls, parent);
        // major hack here...!
        try{
            customClasses.put("org.w3c.dom.Node",super.loadClass("org.w3c.dom.Node",false));
        } catch (Exception e) { /* ignore */ }
    }

    private static ClassLoader chooseParent() {
        ClassLoader cl = RootLoader.class.getClassLoader();
        if (cl != null) return cl;
        return ClassLoader.getSystemClassLoader();
    }

    /**
     * constructs a new RootLoader with a {@link LoaderConfiguration}
     * object which holds the classpath
     */
    public RootLoader(LoaderConfiguration lc) {
        this(chooseParent());
        Thread.currentThread().setContextClassLoader(this);
        URL[] urls = lc.getClassPathUrls();
        for (URL url : urls) {
            addURL(url);
        }
    }

    /**
     * loads a class using the name of the class
     */
    protected Class loadClass(final String name, boolean resolve) throws ClassNotFoundException {
        Class c = this.findLoadedClass(name);
        if (c != null) return c;
        c = (Class) customClasses.get(name);
        if (c != null) return c;
        
        try {
            c = oldFindClass(name);
        } catch (ClassNotFoundException cnfe) {
            // IGNORE
        }
        if (c == null) c = super.loadClass(name, resolve);

        if (resolve) resolveClass(c);

        return c;
    }

    /**
     * returns the URL of a resource, or null if it is not found
     */
    public URL getResource(String name) {
        URL url = findResource(name);
        if (url == null) url = super.getResource(name);
        return url;
    }

    /**
     * adds an url to the classpath of this classloader
     */
    public void addURL(URL url) {
        super.addURL(url);
    }

    private Class oldFindClass(String name) throws ClassNotFoundException {
        return super.findClass(name);
    }

    protected Class findClass(String name) throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }
}

Other Groovy examples (source code examples)

Here is a short list of links related to this Groovy RootLoader.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.