ClassLoader在jvm和tomcat中的区别

发现问题:

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

问题出现在,程序用main方法的方式运行的时候能够正常运行,但是使用tomcat运行的时候就会报空指针异常。

原因:

两种方式运行的ClassLoader加载机制不同,导致了不同的结果。

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

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

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

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

     

  4. 所以classPath路径下的资源都是由AppClassLoader来加载的。





     
  5.  
Tomcat的ClassLoader加载机制

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


27001940_uN6n.jpg

 

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

然后上面也体现了整体的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)这三种方法。

转载于:https://my.oschina.net/u/1760932/blog/666744

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值