你为什么需要Bnd?
作者:皮特*柯林斯
翻译:草儿
刚刚收到一个谷歌文章提示,来自一个关于OSGi的博客。作者是Jilles van Gurp,首先对OSGi表示赞美然后提到这个工具。他的主要问题是必须在Eclipse插件开发环境里一个一个在Manifest中增加输入 ,这时一些人会抱怨manifest的格式繁杂。我非常同意他的观点。 Bnd这个工具基本上考虑到他所有的要求。
管理对其他绑定的依赖比在Java中处理输入包更繁琐。一般当我想用某些库的的时候,就下载它;把它放在系统环境类路径上;输入几个字符,使用ctrl+space暴露任何API。在OSGi中,这个更困难。你下载这个bundle(假设存在一个)然后需要决定你想用它暴露给的哪一个包 。
我同意Eclipse的Java开发平台(JDT)要比插件开发环境(PDE)工作起来更方便。然而,如果你用bnd,你就会精确地按照你所描述的方式工作。你能够象你以前一样使用库包,你没有必要用PDE。我仅仅用JDT工作。Bnd读取一个配置文档,该文档描述类路径应该放在结果bundle中的那一部分。 通配符和默认设置使这个配置描述最小化成为可能。Bnd到那时会核算目录和所要求的输出。
大多数库包实际上不用bundle封装。Bundles是一个新概念,它同旧有的jar文件(大多以第三方库的形式引入)不兼容。这不是一个不可逾越的限制。一个更合理的默认策略是把非OSGi jar文件作为bundles,简单地输出它的所有东西和把所有它要引进的放到引进路径上。从一个jar文件中抽取信息不可能很难。至少,我想有一个工具为我做这种工作。
好了,使用Bnd工具 你的祈祷再次生效了。这个工具有一个wrap函数能够为你做这个工作。然而,实际上因为很多JAR文件的依赖极端繁杂,所以这个可能变得困难。通常创建一个可选输入或者忽略输入从而bundles是可安装的是必要的。当你分析一个JAR文件时(Bnd能够帮你处理这个工作),你总会吃惊的看到很多无用的依赖出现。
最后,我讨厌必须处理繁杂的manifest文件的想法。我注意到要求manifest文件要以空行作为结束的缺陷依旧存在(如果这个遗漏了怪异的事情就发生了)。这个和在makefiles文件要用tab代替空格一样烦人。
啊哈哈,确实很麻烦,但是你使用Bnd后就不会在为这些小事而烦躁了。一个.bnd文件是一个属性文件。它能处理不限长度的行,使用反斜杠\扩展到下一行,没人会关心最后一行。你也能增加注释。Bnd读取这些属性文件,它用在Manifest类中建立的Java生成一个有效的manifest。以这种方式校验所有的头都为正确的值。.bnd文件看起来是多么简单:
Export-Package: aQute.service.*
Import-Package: javax.servlet.http;version="[2,3)", *
但是,Jilles还没有说完关于OSGi的批评:
当然伴随Java5.0来临,使用元注释完成这个是一个更好的方式。可以理解的是,OSGi需要与旧版本保持向后兼容,但是发展方式显然同新版本Java机制相背离。基本上,我想我基于import & export机制能够指定类和方法层次的约束。
我知道元注释最近变得流行,清晰地它们有它们的用处。然而,这也有关注点分离方面的考虑。我认为我们的行业已经明白人们不想把业务逻辑同基础架构混淆在一起的这种考虑。使用元注释在类或者方法层次指定你的约束显而易见会弄乱你的代码。我认为依赖总是复杂到超过人类能够管理的程度。需要更好的工具,让用户在代码中手工管理这些依赖是极端错误的倾向。所以我不能肯定元注释是一个解决方案。如果输入包在源文件里有版本信息的话(或者在manifest或者在包目录中的包信息文件里),Bnd能够找到输入包的版本信息 。尽管它不能处理版本范围,但是这种方式至少是简单并能保持一致性。关于怎样处理版本范围(允许在类路径上存在同包的多版本并分析他们的不同点),我有一些想法。但是,需要时间--
另一个问题是包中没有真正包含Java中首类表示形式。它们在Classes文件中按名调用(在包声明中),但是并没有它们自己的规范。这意味着增加包层次的元注释是困难的(你能够使用package-info.java 文件完成它)。
就像前面我诉说的,我还不能肯定元注释是不是最好的方案,因为它会把业务逻辑同基础架构相混淆。在OSGi中,你能用manifest文件(或者.bnd文件)在包中增加属性。
- Bnd也被以Felix Maven-bundle 插件形式用在Maven构建工具中,。
- Bnd 也是一个eclipse插件, 它在为.bnd 文件 和 .jar 文件的上下文菜单里增加了入口。
- 你能添加来自系统文件的任何地方或者来自一个URL的资源。这并不需要先创建所有资源的目录结构, JAR在运行中构建。
- 资源能够包含被代替的变量引用。
- 你能够很容易得在你的JAR文件中从类路径上添加包。如果你用另一个bundle的一小部分而不想创建额外的依赖,这个用起来非常方便。
- Bnd也能在输出中创建uses语句 。这uses语句表明使用什么包。整个架构使用这些信息创建一致的类空间。
- 你能内联其他的JAR文件或者目录。
- 更多的功能.
我没有说Bnd是完美无缺的。我希望我能花一些时间以我喜欢的方式对它进行扩展:处理依赖的图形编辑器;更好的分析支持;集成Eclipse构建器等等。
Peter Kriens
凡是有该标志的文章,都是该blog博主Caoer(草儿)原创,凡是索引、收藏
、转载请注明来处和原文作者。非常感谢。