往事如风
记录工作中的点点滴滴 留住那些淡淡的回忆
posts - 6,  comments - 3,  trackbacks - 0

最近在做一个项目,综合使用了jboss的microcontainer,jetty和自己定义的war包,war包中还会用到spring,因为牵涉到多个容器,同时又有自己的自定义类,所以classloader环境异常复杂,ClassNotFound问题搞得头都大了,最后综合各种因素,设计了如下的一个classloader层次:

cl.png

其中,红色部分是系统(也就是启动java程序加载Main函数的classloader),主要的设计考量有以下几点:

1、使用自定义的ExtClassLoader(加载java的ext目录下的jar包)把程序加载的class完全和系统加载的class隔离开,这样即使在eclipse容器中启动都不会有类冲突。

为什么不从系统的ExtClassLoader作为自定义classloader数的根有两个考虑,第一个是系统ExtClassLoader有可能不存在,第二个就是如果使用同一个ExtClassLoader中,在处理JNDI、XML和URL解析等java扩展功能时会遇到后加载的handler部分导致不同classloader树加载的同一个类的ClassCastException,具体参见这些模块的源代码。

2、WarClassLoader除了系统类和Common类(目前只有log相关类)以外的类都从war包的WEB-INFO和classes下加载。

3、所有执行War包中代码的线程ThreadContextClassLoader都设置为WarClassLoader,以供Spring和Webx中的相关工具类使用这个classloader结构的后门来加载war包中的类,典型例子是Webx中ResourceLoaderService就是使用ContextClassLoader来加载类的。

4、RialtoClassLoader也就是这个项目的容器加载器和WarClassLoader不在同一个树路径上,可以避免程序使用类和war使用类的class冲突,典型的是Spring容器相关代码。

5、CommonClassLoader加载的类需要严格控制,否则可能会导致运行期类冲突,例如Spring的相关jar包绝对不可以出现在这个classloader作用范围内。

总之,ClassLoader采用父分派机制,后来增加的Thread ContextClassLoader在这个体系上增加了一个后门,带来了灵活性,也带来了很多令人困扰的问题,在做容器类的项目时难免会遇到class loader层次设计的问题,这里抛砖引玉,欢迎达人拍砖。

posted on 2010-07-14 19:18 井底青蛙,常望天空 阅读(1057) 评论(0)  编辑  收藏 所属分类: java

只有注册用户登录后才能发表评论。


网站导航:
 

<2010年7月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

常用链接

留言簿

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜