Hessian/Java反序列化采用自定义的Classloader

Hessian/ Java反序列化采用自定义的Classloader
对于采用OSGi来做系统的人而言,ClassLoader的问题必然是头号需要解决的问题,如果又是个需要远程通讯的OSGi应用的话,那么反序列化的classloader问题几乎可以肯定是会碰到的,来看看在如今流行的两种序列化、反序列化协议: java/ hessian中如何使用自定义的classloader。
java/ hessian并不提供直接的传入ClassLoader类来改变反序列化时采用的ClassLoader, hessian采用的为使用当前线程的上下文ClassLoader来加载反序列化的类, java则采用堆栈上最近的一个ClassLoader类来加载,可以认为就是调用类所在的ClassLoader来加载,但在OSGi应用中,通常采用以上默认的行为来反序列化加载类是会出问题的,因此需要采用自定义的。
先来看看 java的, Java在ObjectInputStream.readObject时最后采用的是resolveClass方法来加载类:
protected Class<?> resolveClass(ObjectStreamClass desc)
    throws IOException, ClassNotFoundException
    {
    String name = desc.getName();
    try {
        return Class.forName(name, false, latestUserDefinedLoader());
    } catch (ClassNotFoundException ex) {
        Class cl = (Class) primClasses.get(name);
        if (cl != null) {
        return cl;
        } else {
        throw ex;
        }
    }
    }惊喜的是,resolveClass是protected的,:),还好,还留下了这一手,于是毫不客气,写一个继承ObjectInputStream的子类,然后覆盖resolveClass方法即可,到这步了就可以随意用自己的ClassLoader来实现加载了。
OK, java的解决了,来看 Hessian的, Hessian在加载类的时候采用了下面的代码:
if (type.startsWith("[")) {
      Deserializer subDeserializer = getDeserializer(type.substring(1));
      deserializer = new ArrayDeserializer(subDeserializer);
    }
    else {
      try {
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
     
    Class cl = Class.forName(type, false, loader);

    deserializer = getDeserializer(cl);
      } catch (Exception e) {
      }
    }看过这段代码后,就明白,要替换,最明显的一种做法是替换当前线程的上下文classloader,而这通常有一定的风险,因为可能会有很多代码使用到线程的上下文classloader,另外一种可选的做法就是继承SerializerFactory,覆盖其中的getDeserializer方法,从而实现对加载类的ClassLoader的控制,这种方式风险就比较小了。
为了能实现使用自定义的classloader后可以加载到所有bundle export package中的类,在自定义classloader所在的Bundle中需要加上DynamicImport-Package,这样可以比较简单的实现。
在Equinox中,则还可以选择实现ClassLoadingHook,这样可以比较简单的实现和其他外部容器的集成以及更加自如的控制classloader,:)
在解决了classloader的问题后,通常来讲,使用OSGi带给你的更多的就是享受,而非痛苦了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值