使用BND构建OSGi Bundle时如何只导出第三方依赖的包到MANIFEST.MF中而不解压到jar中?

本文是纯第三方依赖的Eclipse插件的构建和自动更新的后续。

背景

之前构建纯第三方依赖的Eclipse插件的时候,通过Export-Package导出了不少包(例如apache commons、xstream、slf4j等)给其他插件使用,因为导出包太多,导致Eclipse插件在查找类的时候出现了性能问题,所以现在想仅开放必要的内部包,公共组件的包由外部插件提供,一些必要的调用通过该插件内部的代码类来提供。所以做了两个修改:

  1. Export-Package中移除了公共组件的包,仅保留项目相关jar的包的导出。
  2. 代码工程中增加了src/main/java源码文件夹,通过自定义工具类实现对插件内部类的配置。

经过修改后重新打包,发现打包后的bundle jar中除了自定义的类、第三方jar之外,Export-Package中定义的导出包及其中的类也被解压到了bundle jar中,解压后的包和class以及jar都存在于bundle jar中,这样肯定是有问题的。

问题原因

通过查阅BND的资料,发现之前对Export-Package的理解有误,之前一直以为该配置对应的是Bundle MANIFEST.MF中的Export-Package,添加到该配置中的插件包及插件内部jar中的包可以供外部插件访问。其实BND中的Export-Package并不仅仅是这个功能,先贴一段BND中的解释说明:

<Export-Package>
The <Export-Package> instruction is a list of packages for the bundle to export. These packages are copied into the resulting bundle JAR file from the available classes (i.e., project classes, dependencies, and class path); thus, it is possible to include classes into your bundle that are not associated with source files in your project. <Export-Package> can be specified with package patterns using the '*' wildcard. Also, it is possible to exclude packages using negation by starting the package pattern with '!'. Thus, non-negated patterns indicate which of the available packages to include in the bundle, whereas negated patterns indicate which should not be included in the bundle.

The list of package patterns is ordered and earlier patterns are applied before later patterns. For example, if you specify "org.foo.,!org.foo.impl" the second pattern has no effect since all org.foo packages have already been selected by the first pattern. Instead, you should specify "!org.foo.impl,org.foo.", which will export all org.foo packages except org.foo.impl.

Following standard OSGi R4 syntax, package patterns can include both directives and attributes, which will be copied appropriately into the generated Export-Package manifest header. Besides explicitly listing package version attributes, BND will also determine package versions by examining the source JAR file or from packageinfo files in the package directory.

注意上述说明中的黑体部分。重点在第一段,第一段已经说明了添加到Export-Package中的包中的class会被复制到生成的bundle jar中,同时加入到MANIFEST.MF的Export-Package头中。
但是我们之前构建的bundle jar,并没有将Export-Package包中的class复制到bundle jar中,是本次增加了src/main/java后才出现解压class的现象,原因未知。

解决办法

BND官网的常见问题文档中,第一条即是该问题“当我嵌入bundle中一个依赖时为什么我在bundle jar中看见了重复的类?”,看来这个问题比较普遍_。先来看BND给的解释说明:

Having two copies of classes, both unpacked and embedded as jars, is a sign that your Embed-Dependency and Export-Package instructions are overlapping. Export-Package tells BND to pull in classes found in the named packages from the build classpath and add them to the bundle, Embed-Dependency tells BND to embed (or inline if enabled) whole artifacts in the bundle.

BND的意思是如果你在最终的bundle jar中看见了重复的class和它所在的jar,说明你在Embed-DependencyExport-Package中的定义重叠了。换句话说就是,你同时配置了Embed-DependencyExport-Package,Export-Package将包中的class解压到bundle jar,Embed-Dependency将jar复制到bundle jar中。
如果你仅仅是想在最终的bundle jar的MANIFEST.MF的Export-Package头中导出包,并不想同时将包中的class解压到bundle中,你需要使用<_exportcontents>替代Export-Package,具体做法:

  1. 移除<Export-Package>
  2. 在Embed-Dependency之后添加<_exportcontents>,例如:
<Embed-Dependency>*</Embed-Dependency>
<_exportcontents>org.apache.commons.*</_exportcontents>

参考资料

Apache Felix Bundle Plugin Frequently Asked Questions
使用BND构建包含纯第三方依赖的Eclipse插件

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容