`
DavyJones2010
  • 浏览: 154785 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Tomcat 5.0.18 ClassLoader source code insight

阅读更多

All the functionality of ClassLoader is nested in org.apache.catalina.loader.WebappClassLoader

1) Structure of WebappClassLoader

public class WebappClassLoader
    extends URLClassLoader
    implements Lifecycle{
  /**
     * The cache of ResourceEntry for classes and resources we have loaded,
     * keyed by resource name.
     */
    protected HashMap resourceEntries = new HashMap();
    /**
     * The list of not found resources.
     */
    protected HashMap notFoundResources = new HashMap();
    public Class loadClass(String name, boolean resolve);
    protected Class findLoadedClass0(String name);
    public Class findClass(String name);
    protected Class findClassInternal(String name);

    // This method is derived from java.lang.ClassLoader; it will invoke native method searching JVM for classes loaded by current class loaders
    // It will return the loaded class if and only if the class is previously loaded(call defineClass method) by current class loader instance
    protected final Class<?> findLoadedClass(String name);
    // This method is derived from java.lang.ClassLoader, it will invoke native method  and it is the only way of converting byte[] into Class<?>; even if in our self defined ClassLoader.
    protected final Class<?> defineClass(String name, byte[] b, int off, int len,
                                         ProtectionDomain protectionDomain);
}

2) Overrides loadClass() on URLClassLoader

public Class loadClass(String name, boolean resolve){
  // (0) Check local class cache
  clazz = findLoadedClass0(name);
  if (clazz != null) {
      return (clazz);
  }
  // (0.1) Check ClassLoader inherent cache, call native method
  clazz = findLoadedClass(name);
  if (clazz != null) {
      return (clazz);
  }

  // Here we can guarantee that target class hasn't been loaded by WebAppClassLoader before, but whether it has been loaded by System/Ext/Bootstrap ClassLoader is unknown
  // Try to find class from bootstrap/ext/system ClassLoader's inherent cache, if cannot find, try to load .class from class path; throw exception when cannot be load either
  try {
       clazz = system.loadClass(name);
       return (clazz);
   } catch (ClassNotFoundException e) {
        // Ignore
   }

  // Here we are sure that the target class hasn't loaded by current application before.
  // We will try to load it from container's WEB-INF/libs

  // delegateLoad means WebappClassLoader will use parent first model, if false, means WebappClassLoader will use child first model.
  boolean delegateLoad = delegate || filter(name);

  // load class with parent
  if (delegateLoad) {
    try{
      clazz = parent.loadClass(name);
      if (clazz != null) {
         return (clazz);
      }
    }catch(ClassNotFoundException e){
      // swallow e
    }
  }
  // load class with child(It is the end of parent delegation, and it is the start of child first)
  try {
      clazz = findClass(name);
      if (clazz != null) {
          return (clazz);
      }
  } catch (ClassNotFoundException e) {
      ;
  }

  // load class with parent(It is then end of child first model)
  if (!delegateLoad) {
      ClassLoader loader = parent;
      try {
         clazz = loader.loadClass(name);
          if (clazz != null) {
              return (clazz);
          }
      } catch (ClassNotFoundException e) {
          ;
      }
  }
  // All possible tries has failed, throw exception
  throw new ClassNotFoundException(name);
}

// get class from WebappClassLoader customized class cache
protected Class findLoadedClass0(String name) {
  ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
  if (entry != null) {
        return entry.loadedClass;
  }
  return (null);  // FIXME - findLoadedResource()
}

3) How tomcat class reload works? Take a look at WebappClassLoader.stop()/start() as it implements interface Lifecycle;

// All ClassLoader did is clear its local class cache because we do not have the access to inherited java.lang.ClassLoader's inherent cache.
// reload is realized by calling stop() and start(), then loadClass() loading all classes under WEB-INF/lib
// loadClass(name) will first check local class cache which will return null, then it will check inherent cache, that would return "null" because 
// every time we restart, our WebappClassLoader is newly instantiated(the old instance is discarded)
public void stop(){
  started = false;
  notFoundResources.clear();
  resourceEntries.clear();
  repositoryURLs = null;
}
public void start() throws LifecycleException {
  started = true;
}

   The logic where a new WebappClassLoader instance is created every time the container is restarted:

// WebappLoader
public void start(){
  classLoader = createClassLoader();
  classLoader.setResources(container.getResources());
  classLoader.setDebug(this.debug);
  classLoader.setDelegate(this.delegate);
  // ...
  if (classLoader instanceof Lifecycle)
    ((Lifecycle) classLoader).start();
}
/**
* Create associated classLoader.
*/
private WebappClassLoader createClassLoader()
  throws Exception {
  Class clazz = Class.forName(loaderClass);
  WebappClassLoader classLoader = null;

  if (parentClassLoader == null) {
    parentClassLoader = Thread.currentThread().getContextClassLoader();
  }
  Class[] argTypes = { ClassLoader.class };
  Object[] args = { parentClassLoader };
  Constructor constr = clazz.getConstructor(argTypes);
  classLoader = (WebappClassLoader) constr.newInstance(args);

  return classLoader;
}

 

 

Summary:

1) We do not have direct access to native class cache defined by JVM. But we can make a little tweaks to realize class loading:

    1> We can suppose the native class cache keeps a map of Map<String, Class> with key of ClassLoader.instance.hashCode[classname+instancecode], and value of loaded class.

    2> The class would be recorded into native cache when the class loader's instance calls defineClass(), and the cached class would be returned only when current class loader instance calls findLoadedClass0();

 

分享到:
评论

相关推荐

    jakarta-tomcat-5.0.18

    jakarta-tomcat-5.0.18.exe

    tomcat安装包jakarta-tomcat-5.0.18.exe

    Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,目前最新版本是6.0.20(截止到2009-03-20)。  Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和...

    How Tomcat Works 中文版+源码+书里面对应tomcat源码(4.1.12 5.0.18)和编译后文件

    源码部分包括了Tomcat 4.1.12和5.0.18两个版本,这两个版本分别代表了Tomcat发展的不同阶段。4.1.12是Tomcat 4系列的一个稳定版本,5.0.18则是Tomcat 5系列的重要版本,引入了许多新特性和性能优化。源码的提供使得...

    HowTomcatWorks书籍代码

    HowTomcatWorks书籍课程...书籍剖析了Tomcat 4.1.12和Tomcat 5.0.18--一个免费的、开源的、深受大众欢迎的、代号为Catalina的servlet容器,并讲解其容器的内部运行机制。通过迭代实现一个简化版软件来讲述相应原理。

    mysql5.0.18

    mysql5.0.18

    Windows 2008 NLB Apache2.2 Tomcat 5集群安装配置指导手册

    1. 环境准备:需要有两台安装Windows 2008 R2操作系统的服务器,每台服务器需要安装JDK 1.6.20、Tomcat 5.0.18和Apache 2.2.3软件。两台服务器的IP地址分别为***.***.***.*和***.***.***.*,虚拟IP地址为***.***.***...

    mysql-5.0.18

    MySQL 5.0.18 是 MySQL 数据库管理系统的一个历史版本。MySQL 是一款开源、免费的关系型数据库管理系统,广泛应用于互联网行业中,特别是网站和应用程序的数据存储。它的特点是速度快、稳定性好、易于使用,并且支持...

    深入剖析Tomcat

    Tomcat4.1.12和Tomcat5.0.18版本是书中具体剖析的对象。Tomcat的内核代号为Catalina,是一个免费的开源servlet容器,也是目前最受欢迎的servlet容器之一。 Tomcat的内部结构分为多个组件,作者提出通过创建每一个...

    How Tomcat Works 中文版.pdf

    该书基于Tomcat 4.1.12和5.0.18两个版本,深入讲解了其servlet容器的架构和运作原理,尤其是代号为Catalina的核心组件。 Tomcat是一个开源的Java应用服务器,主要用于部署和运行基于Servlet和JavaServer Pages (JSP...

    mysql-5.0.18源码 卷1

    mysql-5.0.18源码,共两部分,这是分卷1.

    Easy Touch 5.0.18 unity最新版本插件

    《Easy Touch 5.0.18:Unity的高效交互工具》 在Unity游戏开发领域,易用性和玩家体验是至关重要的因素。Easy Touch 5.0.18是一款专为Unity设计的最新版本插件,它极大地提升了游戏的触摸交互功能,为开发者提供了...

Global site tag (gtag.js) - Google Analytics