jboss4.0.5-GA在使用RMI时的大坑
去年3月份解决的,最近要转岗时清闲点了才有时间写,罪过罪过..
故事的起因是这样的..
我们公司使用jboss4.0.5-GA..APP的classloader一直用Jboss的classloader(UCL3),它会和jboss本身的classloader共享一片仓库缓存(ULR)...这种模式下,jboss容器本身需要的一些jar包和APP需要的一些jar包如果出现同名的话,就会优先加载jboss本身提供的(因为容器启动的时候就已经先被加载了)..
比较经典的case就是jboss中用到了commons-lang-2.1.jar,而我们的APP使用了commons-lang-2.4.jar..编译一切正常,但运行时抛了一个找不到method的异常..一查发现APP用到了StringUtils.join(Collection collection, String separator) 方法,这个方法在2.3版本才有,而当时应用运行时因为先加载了2.1版本,导致运行时挂掉..
详情可见附件中当年分享的PPT
后来引入wurfl的时候又出现了类似的问题..一怒之下就想把APP的classloader和容器的classloader隔离掉..
隔离的方法很简单,修改一下这个配置,把true改成false就行
<!-- A flag indicating if the JBoss Loader should be used. This loader
uses a unified class loader as the class loader rather than the tomcat
specific class loader.
The default is false to ensure that wars have isolated class loading
for duplicate jars and jsp files.
-->
<attribute name="UseJBossWebLoader">true</attribute>
修改完后解决了几个问题后应用终于顺利运行..
但性能测试的时候发现页面的响应速度大大下降..
经过各种排查,最后定位到是做
RMI请求的时候变慢了..后来biubiu推荐了wireshark去查看request和response的包...对比修改前后发现,独立classloader后网络包中出现了大量的jar包全路径..
继续跟踪代码终于发现RMI请求会调用WebAppClassLoader这个类中getURLs()方法,这个方法会返回WEB-INF/lib和WEB-INF/classes所有文件的全路径..
最后直接修改WebAppClassLoader的getURLs()方法,返回了一个空白对象,问题解决...
解决后想给jboss提bug,发现已经早有人提了..https://issues.jboss.org/browse/JBAS-5022
按照这个bug的记录,从JBossAS-5.0.0.CR2开始就不会有这个问题了..
但在之前版本使用RMI的朋友们就得注意了..