`
klcwt
  • 浏览: 190099 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Tomcat webAppClassloader

阅读更多

     WebappClassLoader  继承了URLClassLoader里面加入缓存和安全。

     缓存:

          1.缓存了已经事先装载的Classes。

          2.缓存了错误信息,比如先前装载一个类报错,那么下次再load这个类的时候,就会到缓存中去查找

           (   ClassNotFoundException

 

 

 

 /**
     * Load the class with the specified name.  This method searches for
     * classes in the same manner as <code>loadClass(String, boolean)</code>
     * with <code>false</code> as the second argument.
     *
     * @param name Name of the class to be loaded
     *
     * @exception ClassNotFoundException if the class was not found
     */
    public Class loadClass(String name) throws ClassNotFoundException {

        return (loadClass(name, false));

    }


    /**
     * Load the class with the specified name, searching using the following
     * algorithm until it finds and returns the class.  If the class cannot
     * be found, returns <code>ClassNotFoundException</code>.
     * <ul>
     * <li>Call <code>findLoadedClass(String)</code> to check if the
     *     class has already been loaded.  If it has, the same
     *     <code>Class</code> object is returned.</li>
     * <li>If the <code>delegate</code> property is set to <code>true</code>,
     *     call the <code>loadClass()</code> method of the parent class
     *     loader, if any.</li>
     * <li>Call <code>findClass()</code> to find this class in our locally
     *     defined repositories.</li>
     * <li>Call the <code>loadClass()</code> method of our parent
     *     class loader, if any.</li>
     * </ul>
     * If the class was found using the above steps, and the
     * <code>resolve</code> flag is <code>true</code>, this method will then
     * call <code>resolveClass(Class)</code> on the resulting Class object.
     *
     * @param name Name of the class to be loaded
     * @param resolve If <code>true</code> then resolve the class
     *
     * @exception ClassNotFoundException if the class was not found
     */
    public Class loadClass(String name, boolean resolve)
        throws ClassNotFoundException {

        if (log.isDebugEnabled())
            log.debug("loadClass(" + name + ", " + resolve + ")");
        Class clazz = null;

        // Log access to stopped classloader
        if (!started) {
            try {
                throw new IllegalStateException();
            } catch (IllegalStateException e) {
                log.info(sm.getString("webappClassLoader.stopped", name), e);
            }
        }

        // (0) Check our previously loaded local class cache
        //在这里装载的时候使用了缓存,注意这个是local class 


        clazz = findLoadedClass0(name);
        if (clazz != null) {
            if (log.isDebugEnabled())
                log.debug("  Returning class from cache");
            if (resolve)
                resolveClass(clazz);
            return (clazz);
        }

        // (0.1) Check our previously loaded class cache
        //而这个就是class


        clazz = findLoadedClass(name);
        if (clazz != null) {
            if (log.isDebugEnabled())
                log.debug("  Returning class from cache");
            if (resolve)
                resolveClass(clazz);
            return (clazz);
        }

        // (0.2) Try loading the class with the system class loader, to prevent
        //       the webapp from overriding J2SE classes
        try {
            clazz = system.loadClass(name);
            if (clazz != null) {
                if (resolve)
                    resolveClass(clazz);
                return (clazz);
            }
        } catch (ClassNotFoundException e) {
            // Ignore
        }

        // (0.5) Permission to access this class when using a SecurityManager
        //安全机制


        if (securityManager != null) {
            int i = name.lastIndexOf('.');
            if (i >= 0) {
                try {
                    securityManager.checkPackageAccess(name.substring(0,i));
                } catch (SecurityException se) {
                    String error = "Security Violation, attempt to use " +
                        "Restricted Class: " + name;
                    log.info(error, se);
                    throw new ClassNotFoundException(error, se);
                }
            }
        }

        boolean delegateLoad = delegate || filter(name);
        
        // (1) Delegate to our parent if requested
        //代理装载类


        if (delegateLoad) {
            if (log.isDebugEnabled())
                log.debug("  Delegating to parent classloader1 " + parent);
            ClassLoader loader = parent;
            if (loader == null)
                loader = system;
            try {
                clazz = loader.loadClass(name);
                if (clazz != null) {
                    if (log.isDebugEnabled())
                        log.debug("  Loading class from parent");
                    if (resolve)
                        resolveClass(clazz);
                    return (clazz);
                }
            } catch (ClassNotFoundException e) {
                ;
            }
        }

        // (2) Search local repositories
        if (log.isDebugEnabled())
            log.debug("  Searching local repositories");
        try {
            clazz = findClass(name);
            if (clazz != null) {
                if (log.isDebugEnabled())
                    log.debug("  Loading class from local repository");
                if (resolve)
                    resolveClass(clazz);
                return (clazz);
            }
        } catch (ClassNotFoundException e) {
            ;
        }

        // (3) Delegate to parent unconditionally
        if (!delegateLoad) {
            if (log.isDebugEnabled())
                log.debug("  Delegating to parent classloader at end: " + parent);
            ClassLoader loader = parent;
            if (loader == null)
                loader = system;
            try {
                clazz = loader.loadClass(name);
                if (clazz != null) {
                    if (log.isDebugEnabled())
                        log.debug("  Loading class from parent");
                    if (resolve)
                        resolveClass(clazz);
                    return (clazz);
                }
            } catch (ClassNotFoundException e) {
                ;
            }
        }

        throw new ClassNotFoundException(name);
    }
 

    看看WebAppClassLoader是如何从缓存中装载的

 

    /**
     * Finds the class with the given name if it has previously been
     * loaded and cached by this class loader, and return the Class object.
     * If this class has not been cached, return <code>null</code>.
     *
     * @param name Name of the resource to return
     */
    protected Class findLoadedClass0(String name) {
        //resouceEntries是个hashmap


        ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
        if (entry != null) {
            return entry.loadedClass;
        }
        return (null);  // FIXME - findLoadedResource()

    }


  //看看缓存对象的代码 
  import java.net.URL;
import java.security.cert.Certificate;
import java.util.jar.Manifest;

/**
 * Resource entry.
 *
 * @author Remy Maucherat
 * @version $Revision: 302726 $ $Date: 2004-02-27 15:59:07 +0100 (ven., 27 f茅vr. 2004) $
 */
public class ResourceEntry {


    /**
     * The "last modified" time of the origin file at the time this class
     * was loaded, in milliseconds since the epoch.
     */
    public long lastModified = -1;


    /**
     * Binary content of the resource.
     */
    public byte[] binaryContent = null;


    /**
     * Loaded class.
     */
    public Class loadedClass = null;


    /**
     * URL source from where the object was loaded.
     */
    public URL source = null;


    /**
     * URL of the codebase from where the object was loaded.
     */
    public URL codeBase = null;


    /**
     * Manifest (if the resource was loaded from a JAR).
     */
    public Manifest manifest = null;


    /**
     * Certificates (if the resource was loaded from a JAR).
     */
    public Certificate[] certificates = null;
}


 

   安全机制

 

/**
     * The set of trigger classes that will cause a proposed repository not
     * to be added if this class is visible to the class loader that loaded
     * this factory class.  Typically, trigger classes will be listed for
     * components that have been integrated into the JDK for later versions,
     * but where the corresponding JAR files are required to run on
     * earlier versions.
     */
    protected static final String[] triggers = {
        "javax.servlet.Servlet"                     // Servlet API
    };

//这个在Tomcat4中有,在tomcat6.0中没有


private static final String[] packageTriggers = {
  "javax",                                     // Java extensions
  "org.xml.sax",                               // SAX 1 & 2
  "org.w3c.dom",                               // DOM 1 & 2
  "org.apache.xerces",                         // Xerces 1 & 2
  "org.apache.xalan"                           // Xalan
};




 

 

分享到:
评论

相关推荐

    spring-instrument-tomcat-4.3.14.RELEASE.jar

    Tomcat's WebappClassLoader is currently not instrumentable, so Spring provides a custom ClassLoader that can be used by placing spring-instrument-tomcat.jar in $TOMCAT_HOME/lib and putting a loader ...

    Tomcat 检测内存泄漏实例详解

    这个要从热部署开始说起,因为tomcat提供了不必重启容器而只需重启web应用以达到热部署的功能,其实现是通过定义一个WebappClassLoader类加载器,当热部署时就将原来的类加载器废弃并重新实例化一个WebappCl

    how-tomcat-works

    8.6 WebappClassLoader类 57 8.6.1 类缓存 58 8.6.2 载入类 59 8.6.3 应用程序 59 第9章 session管理 62 9.1 概述 62 9.2 Sessions 62 9.2.1 Session接口 62 9.2.2 StandardSession类 63 9.2.3 ...

    Problem with WebappClassLoader in background thread

    NULL 博文链接:https://pingfang.iteye.com/blog/1178075

    How Tomcat Works: A Guide to Developing Your Own Java Servlet Container

    8.6 WebappClassLoader类 57 8.6.1 类缓存 58 8.6.2 载入类 59 8.6.3 应用程序 59 第9章 session管理 62 9.1 概述 62 9.2 Sessions 62 9.2.1 Session接口 62 9.2.2 StandardSession类 63 9.2.3 ...

    commons-beanutils-1.7.0

    java.lang.SecurityException: class "org.apache.commons.collections.SequencedHashMap... at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Unknown Source)

    借助Ehcache缓存框架实现对页面的缓存Demo

    本web工程的发布不要使用Tomcat7,否则会出现如下异常: 2015-3-25 9:53:50 org.apache.catalina.loader.WebappClassLoader loadClass 信息: Illegal access: this web application instance has been stopped ...

    spring的jar包解决:DispatcherServlet

    Error loading WebappClassLoader org.springframework.web.servlet.DispatcherServlet java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet at org.apache.catalina.loader....

    Proxool-0.9.1

    十二月 02, 2013 8:19:43 上午 org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc SEVERE: The web application [/xxx] registered the JDBC driver [org.logicalcobwebs.proxool.ProxoolDriver] ...

    信息: Deploying web application directory lx01

    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1516) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1361) at org.apache.catalina....

    JettyWebSocketTest2

    在 onMessage 中,上下文类加载器将是 org.codehaus.plexus.classworlds.realm.ClassRealm 而不是 org.eclipse.jetty.webapp.WebAppClassLoader。 因此,从 Web 应用程序的 Jar 中查找类路径上的资源将失败。

Global site tag (gtag.js) - Google Analytics