apache karaf 怎么上传不是osgi的jar包

apache karaf 怎么上传不是osgi的jar包,第1张

打开eclipse,点新建-》其他,选择如图所示选择你要转换的jar包。填入项目名,目标平台选择,OSGi框架-》标准。最重要的一步来了,查看源jar包的MANIFEST.MF配置,查看是否Import-Package这一项。如果有这一项,把这一项全部复制到的所转换的bundle的MANIFEST.MF配置文件里。选中工程,右键-》导出,选择你要导出的bundle和生成bundle的目录。

Java通过Classloader加载Class,Classloader之间相互隔离。隔离真正的意思是:不同的Classloader可以加载相同的class定义,并且被jvm认定为不同的class。很多人对隔离有误解,认为不同的Classloader之间不能相互访问,这其实并不准确。可以这么理解:Classloader只是一个普通的Java类,加载的class集合是它的一个成员变量。如果一个Classloader中维护了另一个Classloader的引用,自然可以通过接口调用查找并使用另一个Classloader加载的类,双亲委派使用的正式这种机制。

双亲委派这名字乍一听好像是说你有父亲、母亲两个Classloader,你可以委派他们两个先去加载class,他们处理不了的你再处理。如果真这么理解就全错了。首先,他们不是两个,可能是n个;其次,他们不是你的父母,他们是整个jvm共享的Classloader;第三,他们谁的父母都不是,因为你和他们没有血缘(别人也没有),你不是双亲Classloader的子类。

双亲委派的英文为parent delegation,指的是每个Classloader都有一个getParent方法获取上一级的Classloader。查找类时,先调用parent Classloader查找,如果找不到在用自身的Classloader查找。层级关系如下:

双亲委派实际上只是引用关系,上述bootrasp、extension、application Classloader之间关系均属此类。再来看另外一张图:

bootrasp、extension、application Classloader在jvm中只有一个实例,多个用户自定义的Classloader共享此实例,完成公共部分加载。

在OSGI中,每一个Bundle有一个单独的Classloader实例。更具体点,BundleWiringImpl中定义了一个BundleClassLoader,每当加载一个bundle时,框架创建一个BundleClassLoader实例负责该bundle相关class的加载工作。

BundleClassLoader的加载顺序如下:

Bundle之间隔离,但如果存在import关系又可以委托给相应export的classloader处理。实现上无非是维护了多个import bundle的Classloader,查找时调用其find方法实现。

需要注意的是:查找时优先查找Import-Package、Require-Bundle中的类,随后才是查找Bundle自己的类。这里又引入另外一个疑问,Embed-Dependency使用问题。

简单来说,如果一个Bunlde 需要使用protobuf-java.jar,有如下两种使用方式:

按类加载的顺序,如果先加载Import-Package随后加载自身的Class,在外部存在protobuf-java,又有内嵌的protobuf-java时,如何做到使用自己的而非外部的呢?答案是在Embed-dependency中的jar并不会出现在Import-Package中。

最后再来讲一下,为什么每个bundle需要分配单独的Classloader,解决什么问题。在我看来,最主要的原因有如下两个:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11251931.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存