osgi中第三方bundle的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了osgi中第三方bundle的问题相关的知识,希望对你有一定的参考价值。

2015年1月20日写到:

OSGi常见问题总结 :http://blog.csdn.net/ostrichmyself/article/details/7515653
IBM的另一个场景:http://www-01.ibm.com/support/docview.wss?uid=swg21568564
一个很多的文档:http://www.bouncycastle.org/specifications.html


头疼的问题:
银联给了个jar包,upacp_sdk-1.0.0.jar 此包用于签名,加解密。
在将这个jar包放到我们的程序里后,由于upacp_sdk-1.0.0本身引用了其他的类库(包括log4j-1.2.17,bcprov-jdk16-1.45,commons-codec-1.6,commons-lang-2.5,slf4j-api-1.5.11,slf4j-log4j12-1.5.11等),所以报错。但是我们的框架也有log4j,bcprov,commons等jar包,所以想不引用它的jar包,而用我们程序的jar包,但是愣是不能成功。upacp_sdk-1.0.0对log4j的引用是用maven引用的,指定了版本了(不知到maven对于指定的版本,是只能是那个版本,还是只要高于那个版本就可以?)。但是对于bcprov-jdk16-1.45这个jar包却是完全一样的(我们叫做bcprov-jdk16-145,放在了jdk下边),但是仍然不行。
做实验,新建一个普通的project,用到upacp_sdk-1.0.0.jar,将upacp_sdk-1.0.0.jar 的依赖包都放在lib下,只把他的bcprov-jdk16-1.45去掉,用jdk的。这样就可以调用成功。
但是新建一个plugin的project,在这么做的话,就说找不到:java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider。
怀疑,因为bcprov-jdk16-1.45并不是java原生的jar包(我猜的,1是因为,这个东西是在大家遇到问题之后从网上找解决方案,放到了jdk下边的;2是因为它的包名字是org.bouncycastle.jce.provider),在osgi工作时,bundle类加载器是分角色的(父类加载器,框架类加载器,java平台提供的应用程序加载器),我们用到bcprov-jdk16-1.45,就需要类加载器把这个bundle加载进来,但是由于bundle本身的类加载器并不能搜索到这个jar包(因为这个jar包在jdk下,而不在这个bundle里边),而应用程序加载器不认为这个jar包是原生的,所以不加载(应用程序加载器加载java.*开头的package)。那么用到这个类的时候就找不到。
以上仅仅是猜测,觉得是这个原因,但是对于好多原理还不清楚。不敢断言。尤其是我们的框架也用到了这个jar包,并且也没在lib下引用,也没在*.MF文件里引用,为什么我们的程序可以正常运行?当然,即便把jdk下的bcprov-jdk16-145去掉后,我们的程序报的错也不一样,我们报的错是missing。

在北京银行做的时候,也有一个关于加解密的东西,在eclipse里就可以正常运行,但是放到linux上就报错,说找不到什么东西。检查之后,jdk里也有,就是把包在import里引用了一下。

由于时间问题,可能不能继续研究这个问题了。如果需要我们这边调用银联的jar包来加密的话,给出解决方案:
新建立一个bundle,这个bundle引用upacp_sdk-1.0.0.jar(并且将其所有的依赖包加进来),进行签名的工作。别的bundle用的签名的功能时直接引用这个bundle的服务。这样将这个bundle的jar包,与我们的jar包隔离,以免互相影响。尤其是,jar包相近,版本不同。

如果有时间调查的话,调查以下几方面:
委派名单
org.osgi.framework.bootdelegation=sun.*,com.sun.*
添加隐式导出Package 的参数
org.osgi.framework.system.packages=javax.crypto.interfaces
java底层类和虚拟机怎么加载
执行环境


2015年1月20日22:57:29
http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fmisc%2Fbuddy_loading.html 这篇文章解决了签名的问题。
Third party libraries and classloading
Because OSGi makes use of multiple classloaders, the transparent usage of extensible / configurable third party libraries in eclipse requires the usage of an eclipse specific mechanism called "buddy loading". This mechanism allows a bundle to indicate that it needs assistance to load classes or resources when it can not find them among its prerequisites. Note that we call "extensible libraries", libraries that needs to see classes or resources provided by user code (for example log4j logger mechanism, hibernate,...).

To indicate its need for buddy loading, a bundle must modify its manifest and add the following header:

Eclipse-BuddyPolicy: <value>

<value> refers to the policy used to look for the classes. Here are the supported policies:

registered - indicates that the buddy mechanism will consult bundles that have been registered to it. Bundle willing to be registered to a particular bundle add in their manifest: "Eclipse-RegisterBuddy: <bundleSymbolicName>";
dependent - indicates that the classes/resources will be looked up transitively in all the dependent of the bundle;
global - indicates that the classes/resources will be looked up in the global pool of exported package;
app - indicates that the application classloader will be consulted;
ext - indicates that the extensiont classloader will be consulted;
boot - indicates that the boot classloader will be consulted.


其中:app,ext可以,其他的不行。

下面是“深入探讨 Java 类加载器”
http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html#toggle
下面是“戎马一生”写的“bootdelegation vs. org.osgi.framework.system.packages.ex”
http://rongmayisheng.com/post/bootdelegation-vs-org-osgi-framework-system-packages-extra

以上是关于osgi中第三方bundle的问题的主要内容,如果未能解决你的问题,请参考以下文章

在 OSGi 包中添加第三方 Maven 依赖项的最佳方法

为啥即使我的 maven 依赖项中有第三方依赖项,也只需要 OSGi 容器中的第三方依赖项?

如何使用'bnd-maven-plugin'在我的OSGi捆绑jar中添加所有第三方jar(可解析)?

OSGI依赖问题处理

OSGi:导出一个包而不导出同一个包中的几个类

我为啥不在osgi中使用spring