首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

(转)tomcat下使用自定义类加载器遇到的有关问题

2013-11-30 
(转)tomcat下使用自定义类加载器遇到的问题??对于直接通过java命令启动的Java应用,classpath里的类都由系

(转)tomcat下使用自定义类加载器遇到的问题
??
对于直接通过java命令启动的Java应用,classpath里的类都由系统类加载器加载到进程中。我们产品中的自定义类加载器MyClassLoader在加载class文件的byte[]时,会检测到该类引入了接口Hash,MyClassLoader会将Hash的加载代理给父加载器(系统类加载器),系统类加载器在classpath中找到Hash的定义然后加载,接着整个加载操作就可以顺利的完成。
在tomcat环境下,类加载的机制就不同了,具体可见 http://blog.163.com/haizai219@126/blog/static/44412555200810111429791/
借用一图如下:
???????????????Bootstrap
?????????????????? |
? ? ? ? ? ? ? ? System
? ? ? ? ? ? ? ? ? ?|
? ? ? ? ? ? ? ? Common
? ? ? ? ? ? ? ?/ ? ? ? \
? ? ? ? Catalina ? ? ?Shared
? ? ? ? ? ? ? ? ? ? ???????? /... ...\
? ? ? ? ? ? ? ? webapp1 ? ? webappN?
在这种架构下,应用的类都由webappX类加载器来加载,而自定义的类加载器MyClassLoader的父加载器也就应该是webappX,那在加载网络传送过来的类定义的时候,也不会出现问题。最后在定位问题的时候,就是发现MyClassLoader的父加载器不是webappX,而是System,即上面提到的系统类加载器。
MyClassLoader(内部类)的实现如下:

}

? 查看ClassLoader的无参构造函数,可以看到一行代码this.parent = getSystemClassLoader();这就是说,如果自定义的classloader如果不指定父加载器,则会被默认设置为系统类加载器。这就是问题的所在。当MyClassLoader在加载Hash的实现类定义时,让父加载器(系统类加载器)去加载Hash接口定义。在tomcat的类加载机制下,系统类加载器实际上并不能加载应用功能相关的类,这就导致加载Hash失败。
修改的方法就是在创建MyClassLoader的时候,传入合适的父加载器。可以找一个使用了MyClassLoader的类,通过Class.getClassLoader()获取到所应该依附的父加载器。这样在tomcat或者普通的Java应用都可以解决加载出错的问题。

热点排行