`
22cgreen
  • 浏览: 53504 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

tomcat类加载器之WebappClassLoader

阅读更多
我们一直迷惹为什么我们放在web-inf/classes和web-in/lib下的类和包怎会被tomcat找到执行,这也是我们为什么常常把自己项目开发的
类和第三方包放在这两个地方,以前我们一直认为java只从classpath中加载类,或者dir.ext中加载类及lib中加载系统类包。
但是tomcat是否有自己的加载方式,比如,tomcat能加载自己目下的核心类包,tomcat的核心类包放在apache-tomcat-6.0.14\lib
为什么会这样,原因在于tomcat定义自己的类加载器,tomcat类加载器所在的包为:
org.apache.catalina.loader
而其中就有.WebappClassLoader
这个类就分管web-inf/class 和web-inf/lib下的类加载。此类继承了,
public class WebappClassLoader
    extends URLClassLoader
    implements Reloader, Lifecycle
   
    并重写的URLClassLoader中的方法,如:findClass方法等,findClass被重写后作用就是在web-inf/class 和web-inf/lib
    查找用户提供的类全路径的类,如:dlp.oa.chen.Test
    如果WebappClassLoader得到这样一个路径名后会把其转换成dlp/oa/chen/Test.class
    然后加上起始前缀,也就是web-inf/classes
    物理路径为:D:/apache-tomcat-6.0.14/webapps/dlp_oa/WEB-INF/classes
    最后得到真正路径大致就是D:/apache-tomcat-6.0.14/webapps/dlp_oa/WEB-INF/classes/dlp/oa/chen/Test.class
    因此WebappClassLoader会以这样的方式找到类文件并加载,
   
    接下来会有几个问题:
    1.那么类加载器怎么知道是在class中还是lib中呢。
    2.如果class中和lib中存在同样的类,而且包也相同,结果会怎样?
    3.我们加载的类中肯定有new 之类的方法,那加载中的类中的方法引用类,他是被谁加载的,他是怎样取得路径的呢?
   
    1.很显然加载会先在lib中找,如果找不到再到class中去找。这里存在一个优先级的问题。
    2.第二个问题依仍于第一个问题,很显然执行最先找到那个类。前题是类中的方法相同,不然可能无法真正引用,或引用时不对。
    3.第三个问题,在测试中发现我们发现在用自定义类加载器加载的类中用new方式加载类的话一样是用加载他自的加载器加载,
    也就是说new 方法会用他当前的类的加载器来加载新类,他也会调用我们的自定义的加载器方法findClass(name),只不过这里
    我们要注决的就是name必须为全路径,也就包名加类名,在类加载器中,我们只能如下:
    这里不能直接D:\\apache-tomcat-6.0.14\\webapps\\web_test\\WEB-INF\\classes\\com\\chen\\pub\\
    因为new 时类会有包名,很显然基础路径最多只能到包名的前一层目录。因为程序中是用.号来引用包的。
    如:com.chen.pub.Test,事实上在传成真实路径时会把.号变成\
    -------------------------------------------------------------------------------------------------------------------
    public static final String drive="D:\\apache-tomcat-6.0.14\\webapps\\web_test\\WEB-INF\\classes\\";
public static final String fileType=".class";

public Class findClass(String name){
  byte[] data=loadClassData(name);
  return defineClass(name,data,0,data.length);
}

private byte[] loadClassData(String name) {
if(name.indexOf(".")>=0)
name = name.replace('.', '\\');
System.out.println("====="+name);
  FileInputStream fis=null;
  byte[] data = null;
  try {
   fis = new FileInputStream(new File(drive+name+fileType));
   ByteArrayOutputStream baos=new ByteArrayOutputStream();
   int ch=0;
   while((ch=fis.read())!=-1){
    baos.write(ch);
   }
   data=baos.toByteArray();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return data;
}
   
分享到:
评论
1 楼 fangzhu19880123 2011-07-21  
1.很显然加载会先在lib中找,如果找不到再到class中去找。
一般情况下,如果classes目录下有class文件,则lib下的此class文件就会失去作用(N次的教训得出的结论)
所以感觉你这写的有点问题

相关推荐

    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 ...

    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 ...

    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 ...

    Problem with WebappClassLoader in background thread

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

    JettyWebSocketTest2

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

    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....

Global site tag (gtag.js) - Google Analytics