ClassLoader在jvm和tomcat中的区别

发现问题:

前段时间使用ClassLoader类的方法来加载classPath路径下的配置文件,其中用到getSystemResource(String name) 、getSystemResourceAsStream(String name) 、getSystemResources(String name) 这几个方法的时候出现问题。web

问题出如今,程序用main方法的方式运行的时候可以正常运行,可是使用tomcat运行的时候就会报空指针异常。tomcat

缘由:

两种方式运行的ClassLoader加载机制不一样,致使了不一样的结果。服务器

main方法运行是启动的本地的jdk来加载类,加载机制是:app

Java默认提供的三个ClassLoader

  1. BootStrap ClassLoader:称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库,如:rt.jar、resources.jar、charsets.jar等,这个是经过native方法调用C语言实现的。jvm

  2. Extension ClassLoader:称为扩展类加载器,负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目下的全部jar。spa

  3. App ClassLoader:称为系统类加载器,负责加载应用程序classpath目录下的全部jar和class文件。.net

     

  4. 因此classPath路径下的资源都是由AppClassLoader来加载的。指针





  5.  
  6.  

Tomcat的ClassLoader加载机制

tomcat实现了本身的一套类加载器,它的Extension ClassLoader与jvm是相同的,可是没有使用App ClassLoader来加载本身项目里的类和资源。code


 

整个Tomcat的classLoader分为了两条线,左边的一条线为catalinaLoader,这个是Tomcat服务器专用的,用于加载Tomcat服务器自己的class,右边的一条线则为web应用程序用的,每个web应用程序都有本身专用的WebappClassLoader,用于加载属于本身应用程序的资源,例如/web-inf/lib下面的jar包,classes里面的class文件。。。blog

而后上面也体现了总体的classLoader的双亲继承关系。。。。

详细能够看这里http://blog.csdn.net/fjslovejhl/article/details/21328347

这三个方法

getSystemResource(String name) 、getSystemResourceAsStream(String name) 、getSystemResources(String name)

内部实现的时候都是用到了ClassLoader system = getSystemClassLoader();的方法,获取的ClassLoader都是App ClassLoader因此在使用tomcat运行的时候就会取不到classPath路径下的资源,由于都是WebappClassLoader加载的。

解决办法:

使用    当前类.class.getClassLoader().getResource(String name) 、getResourceAsStream(String name) 、getResources(String name)这三种方法。

相关文章
相关标签/搜索