org.jboss.web.tomcat.service.WebAppClassLoader.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.web.tomcat.service.WebAppClassLoader.java

Source

/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2006, Red Hat Middleware LLC, and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.web.tomcat.service;

import java.net.URL;

import org.apache.catalina.loader.WebappClassLoader;
import org.jboss.logging.Logger;
import org.jboss.proxy.compiler.IIOPStubCompiler;

/**
 * Subclass the tomcat web app class loader to override the filter method to
 * exclude classes which cannot be override by the web app due to their use in
 * the tomcat web container/integration.
 * 
 * @author Scott.Stark@jboss.org
 * @version $Revision: 85945 $
 */
public class WebAppClassLoader extends WebappClassLoader {
    static Logger log = Logger.getLogger(WebAppClassLoader.class);

    private String[] filteredPackages = { "org.apache.commons.logging" };

    public WebAppClassLoader() {
    }

    public WebAppClassLoader(ClassLoader parent) {
        super(parent);
    }

    public String[] getFilteredPackages() {
        return filteredPackages;
    }

    public void setFilteredPackages(String[] pkgs) {
        this.filteredPackages = pkgs;
    }

    /*
     * (non-Javadoc)
     * @see org.apache.catalina.loader.WebappClassLoader#addURL(java.net.URL)
     */
    @Override
    public void addURL(URL url) {
        super.addURL(url);
    }

    @Override
    public URL[] getURLs() {
        return new URL[0]; // Optimize away the Memory Allocation
    }

    /*
     * (non-Javadoc)
     * @see org.apache.catalina.loader.WebappClassLoader#findClass(java.lang.String)
     */
    @Override
    public Class findClass(String name) throws ClassNotFoundException {
        boolean trace = log.isTraceEnabled();
        if (trace)
            log.trace("findClass(" + name + ") called");

        try {
            return super.findClass(name);
        } catch (ClassNotFoundException cnfe) {
            // try to dynamically generate the class if it is a stub
            int start = name.lastIndexOf('.') + 1;
            if (name.charAt(start) == '_' && name.endsWith("_Stub"))
                return generateStub(name);
            throw cnfe;
        }
    }

    /**
     * <p>
     * Generate iiop stubs dynamically for any name ending in _Stub.
     * </p>
     * 
     * @param name   a <code>String</code> representing the stub fully-qualified class name.
     * @return   the <code>Class</code> of the generated stub.
     * @throws ClassNotFoundException    if the stub class could not be created.
     */
    private Class generateStub(String name) throws ClassNotFoundException {
        boolean trace = log.isTraceEnabled();
        int start = name.lastIndexOf('.') + 1;
        String pkg = name.substring(0, start);
        String interfaceName = pkg + name.substring(start + 1, name.length() - 5);

        // This is a workaround for a problem in the RMI/IIOP
        // stub loading code in SUN JDK 1.4.x, which prepends
        // "org.omg.stub." to classes in certain name spaces,
        // such as "com.sun". This non-compliant behavior
        // results in failures when deploying SUN example code,
        // including ECPerf and PetStore, so we remove the prefix.
        if (interfaceName.startsWith("org.omg.stub.com.sun."))
            interfaceName = interfaceName.substring(13);

        Class intf = super.loadClass(interfaceName);
        if (trace)
            log.trace("loaded class " + interfaceName);

        byte[] code = IIOPStubCompiler.compile(intf, name);
        if (trace)
            log.trace("compiled stub class for " + interfaceName);

        Class clz = super.defineClass(name, code, 0, code.length);
        if (trace)
            log.trace("defined stub class for " + interfaceName);

        super.resolveClass(clz);
        try {
            clz.newInstance();
        } catch (Throwable t) {
            ClassNotFoundException cnfe = new ClassNotFoundException(interfaceName, t);
            throw cnfe;
        }
        if (trace)
            log.trace("resolved stub class for " + interfaceName);
        return clz;
    }

    /**
     * Overriden to filter out classes in the packages listed in the
     * filteredPackages settings.
     * 
     * @param name
     * @return true if the class should be loaded from the parent class loader,
     *         false if it can be loaded from this class loader.
     */
    protected boolean filter(String name) {
        boolean excludeClass = super.filter(name);
        if (excludeClass == false) {
            // Check class against our filtered packages
            int length = filteredPackages != null ? filteredPackages.length : 0;
            for (int n = 0; n < length; n++) {
                String pkg = filteredPackages[n];
                if (name.startsWith(pkg)) {
                    excludeClass = true;
                    break;
                }
            }
        }
        log.trace("filter name=" + name + ", exclude=" + excludeClass);
        return excludeClass;
    }
}