Eclipse RCP使用Spring时遇到的问题及解决过程

需求环境:

公司的JinbuBox客户端采用Eclipse RCP开发,整个工程只有一个Bundle, 包含所有的jar、资源等等,工程使用了Spring;

问题:在客户端需要更新时,可以采用Eclipse RCP的bundle更新机制。但是因为整个工程只有一个Bundle,所以如果更新就需要将整个应用全部更新一遍,而事实上其核心变动很小(自己的业务Class、及部分图片等资源)。因此,需要将工程拆分为不同的Bundle.

解决方案:

考虑到工程中的jar文件比较多,体积最大,所以将所有的jar作为一个独立的Bundle. 这个Eclipse有很好的解决方案,New Project→Plugin Development Project→plug-in from exsiting archieves,将所有的jar导入即可制作一个独立的Bundle:sharedjars。然后将所有的package都Export出去(注意,export是缺省的行为,但是可能是因为package太多,缺省的export行为会漏掉很多package,因此这里需要手动确认是否所有的package都被exported了)

因为需要使用Spring, 考虑到Osgi的classloader机制,将所有Spring的jar文件保留在原来的Bundle中,这样主Bundle通过required bundle引入sharedjars bundle,在runtime中设置spring.jar。

问题:

1、在运行时,多次提示说某某bundle已经被引入了,比如(javax.servlet.**)等等。这个主要是因为在Target platform中选的plug-ins有重复,只要将对应的取消就可以了;

2、Spring启动时,一些Bean不能创建

刚开始时以为是Spring即时加载某些bean时相关的Bean还没有构建,所以设置lazy-init为true,这样启动就没有问题了。

但是在运行时,却发现所有客户端的Spring Bean都不能访问,表象就是Spring的DI没有工作。

解决过程:

经过调试,发现在调用Spring Bean的地方,Thread.currentThread.getContextClassLoader()以及其上级ClassLoader中都没有加载Spring的Bean. 但是在启动时,加载Spring Context时是正常加载的,不过其ClassLoader与前面的ClassLoader是两个无相交节点的树。

奇怪了! 是,没错,OSGi的不同Bundle确实是不同的ClassLoader,但是我已经把所有Spring相关的代码、jar全部放到同一个Bundle中了呀?而且只有一个Bundle时,系统运行是没有问题的。这就说明这么引入Spring是没有问题的(Spring DM是不同Bundle之间将Spring的Bean作为Service相互引用,与这个需求没有太大关系)

尝试着通过其他方式获取Spring Bean,比如BeanLocator.getBean, 经过验证,这种方式是可以正常工作的。 一个苦工的做法会是将代码中所有XXXServiceUtil.xxxx的静态方法调用service都修改为先获取Spring Bean,然后再转型为对应的Service实例,然后再调用。但是,这不是根本办法。

又仔细想了想,在RCP应用中使用了Spring Http Invoker, 这是一种通过Proxy模式来访问服务器端Service的方法。 记得在Spring的AOP Proxy相关文档中曾经提过,AOP Proxy有两种方式,一种是JDK Proxy, 另外一种是CGLIB Proxy(when business object doesn't imlement an interface)。而在我的bundle中,将cglib.jar放到了另外的Bundle中,这样初始化Spring时,会通过Cglib的ClassLoader去加载Spring Bean Class,而因为Cglib放在Spring所在Bundle之外的bundle中,所以Spring的Bean就没有被正确地初始化。

赶紧试了一下,将sharedjars bundle中的cglib相关代码全部删掉,然后在主Bundle的runtime classpath中,把Cglib.jar加上。

运行,一切OK!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值