案例:类型转换错误(classcastexception)

项目里发生很有意思的事,在利用axis2框架设计服务端时,moduleB包里包含一个classA
service包里包含一个classA,两个签字完全一样。系统运行起来后,两个classA都加载到内存中。然后调用service包里的服务impl时,某个类向上转型为classA,即发生了classcastexception!

临时的解决办法是将共有的classA放到axis2顶层的class路径中,这样就保证无论初始化module还是service仅加载一次classA。注意,同一classloader只加载相同签名的class仅一次。

现在,axis2所处容器运行了另一个web工程,该工程会请求axis2中的webservice。该场景,在两个工程的顶层class中各保存一个classA文件。启动tomcat后,axis2加载moduleB,axis2中某一classloader加载了类classA。
url请求该web的一个servlet,该servlet转而请求axis2 中的服务,此时由于服务的service包中没有classA,我们将classA保存在web工程class路径内。因此又在web的class路径中加载一次。而执行webservice的调用方法从某个类向上转型到classA却未发生classcastexception。注意此时web向axis调用走的是local协议!

现在有若干疑问:
1、为什么同样的类不同场景下同样得加载两次,却不同得发生classcastexception
2、local协议下去执行服务调用为什么会在web工程内加载服务包应有的class类,而不是去到axis2中去寻找?和local协议有关么?
3、classloader加载是按照层次代理模式加载的,那么在该jvm内,这几个classloader的关系是怎样的呢?

经过验证后,发现和local协议无关,即使http协议也会发生此,但是。当web工程和axis2分别处于不同的jvm中时(不同的tomcat实例),web工程是不会去加载classA的!(这是显而易见的),这时在web工程路径也不会去存放classA的文件。
当二者处于同一jvm内时,客户端(webclient)调用webservice的服务时,会将服务包(service.aar)加载到自己的classloader里,即他"认为"自己也是服务端,因此当发现服务包里没有classA时,就到自己的class目录中去找。二者处于不同jvm时,客户端是无论如何也不可能去加载service的实现类的,毋庸置疑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值