总结和对比一下(jboss,tomcat,jetty)容器的classloader机制
?总结和对比一下(jboss,tomcat,jetty)容器的classloader机制容器jboss(4.05)tomcat(6.0.30)jetty(7.1.20)支持child/parent first设置(默认值)Java2ClassLoadingCompliance=false delegate=false_parentLoaderPriority=false过滤package配置FilteredPackages
默认值: javax.servlet,org.apache.commons.loggingpackageTriggers
默认配置:org.apache.commons.loggingsystemClasses
默认配置:java.?
javax.
org.xml.
org.w3c.
org.apache.commons.logging.
org.eclipse.jetty.continuation.
org.eclipse.jetty.jndi.
org.eclipse.jetty.plus.jaas.
org.eclipse.jetty.websocket.
org.eclipse.jetty.servlet.DefaultServlet.
特殊性
1. UseJBossWebLoader=false时,过滤packages才能生效
2. UseJBossWebLoader=true时,不支持过滤packages
3. jboss 5.0以后UseJBossWebLoader参数将不支持
1. 在执行child/parent判断之前,会委托system classloader装载系统class,比如jdk的lib库1. 多了一个serverclass配置,如果是serverclass优先采用child first
2. systemclass默认的配置,多了javax,org.xml,org.w3c配置。
相关文档svn url : http://anonsvn.jboss.org/repos/jbossas/tags/JBoss_4_0_5_GA_CP18svn url :?http://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk
官方classloader机制:?http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html
svn url :?http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/tags/jetty-7.2.0.v20101020/
classloader 官方文档:?http://docs.codehaus.org/display/JETTY/Classloading
???最后(相关问题分析)?
问题1:是一个jar sealed问题, 官方说明: http://download.oracle.com/javase/tutorial/deployment/jar/sealman.html
?
?
说白了就是jdk在jar层面上做的一层控制,避免出现两个不同版本的实现类同时在应用中被装载。
理清了sealed的含义,再看一下出错的堆栈:com.sun.media.jai.util,这个类是jai相关处理
jai_core.jar jai_codec.jar jai_imageio.jar几个jar包的META-INF/MANIFEST.MF中都定义了sealed :true。而我们的应用中刚好有两个jar包,那为什么在jboss运行中没问题,jetty运行却出了问题。
?
最后的原因:
1. 我们使用的是javax.media.jai.JAI.create(String opName,ParameterBlock args),该类刚好依赖了com.sun.media.jai.util.ImagingListenerImpl等相关类。
2. 注意看jetty的特殊性,针对javax.media.jai.JAI是属于systemclass,所以会优先使用jdk去装载,而com.sun则通过应用容器装载,很巧的是公司的jdk下的jre/lib/ext下刚好增加了jai的相关jar,最终导致了sealed冲突。
?
解决方案:
?? 处理起来相对暴力,增加配置systemclass配置,添加jai的相关package,所有的jai都采取parent first加载。
xml加载的问题,原因也跟jetty的特殊性相关。大家都知道xml解析类有很多种
xerces crimson jdk rt.jar j2ee.jar真TMD令人纠结啊,应用容器中一旦同时依赖了这几个xml类库,那麻烦问题就来了。这个SAXParserFactory.newInstance(String factoryClassName, ClassLoader classLoader)在jdk1.6.18版本中有,而在其他的几个包中却没有该接口方法。
?
该问题的原因:
?
解决方案:
处理方式也比较粗暴,如果该方法存在歧义,那干脆不用这方法不就得了,最后换用了无参的newInstance()方法。但这时得注意了,不同xml类库,对应的xml impl默认配置不一样。比如jdk的配置:就会以他自己的为默认值
?
?
所以最后为了统一使用,通过设置环境变量:
?
问题3:该问题是由问题2引出的,正因为设置了xml解析器为xerces,导致在jetty启动的时候出现了一些问题。这次主要的原因就跟共享lib库有关了。
?
最终原因分析:
?
解决方案:
是一个mail邮件发送时发现的问题,从堆栈信息描述看也很见到,对应的javax.mail.event.TransportListener没找到
mail的lib库也是挺让人纠结的
1. xml一样有多个lib库:j2ee.jar,javamail。
2. 但有一点又不同的是j2ee.jar中只有接口申明没有对应的实现类
3. 更纠结的是j2ee-1.4新版本和老的javamail版本接口上还存在差异性(这个是别人告诉我的,个人没仔细验证)
?
看到这,各位看官需要多淡定一下,真是很让人纠结啊
?
最终原先分析:
?
解决方案:
1. 没必要参合j2ee.jar,直接在原先的工程里添加javamail的依赖,最后在应用中引入javamail的包。
?
?
?
??结尾