Bnd - Bundle Tool
介绍
BND工具可用于创建符合OSGi R4规范的Bundle和检测Jar文件是否符合OSGi R4规范。其主要功能有:
z显示Bundle的manifest信息和其所包含的Jar文件;
z将Jar文件打包为Bundle;
z按照OSGi R4规范把类路径下的文件打包为OSGi Bundle;
z检测Bundle中的manifest信息是否符合OSGi R4规范。
BND工具包含了:
z命令行工具
z Eclipse插件
z Ant Task
z Maven插件
背景
通常情况下jar文件是通过Sun jar tool、ant jar task或maven packager打包生成的,所有的工具采用的为同样的方式,开发人员复制需要打包到jar的文件到目录中,然后打包这个目录,很明显这个方法是可行的。
Bnd采用的是不同的处理方式,它根据classpath来组装需要打包的java classes和packages。使用Bnd工具可从源代码、目录或者其他的jar文件中创建出jar文件,你不需要将文件复制来复制去,当需要的时候Bnd可以根据元信息到它所需要的文件。
Bnd在生成jar时根据3个不同的参数来生成:
Export-Package、Private-Package和Include-Resource
Private-Package和Export-Package的值由很多带语法的语言片段组成的,这些语言片段由表达式、属性和描述组成,就像OSGi的属性和描述。例如:xquery比较数据和
Export-Package: com.acme.*;version=1.2
每个语言片段按照顺序应用到classpath中的每个package上,顺序的意思就是如果有一个更先的语言片段符合package的话,那么后面的语言片段就不会生效了。
如果语言片段中的属性和描述都符合package,那么对于此package的描述就生效了。
Private-Package和Export-Package的不同在于Export-Package是可以带版本的,如果package既属于Private-Package,又属于Export-Package,那么这个package会作为Export-Package而生效。
语言片段可以使用”!”开头,这种情况下!后的包不会被打入jar文件中,例如:
Export-Package: !com.acme.impl,com.acme.*;version=1.2
这类过滤性质的语言片段也是按顺序生效的,如果带!的语言片段写在最后,那么由于com.acme.*已经生效了,最后打包出来的还是会有com.acme.impl。
Include-Resource参数可以用来定义需要复制哪些资源文件到Jar中,这可以用来打包licenses、images等等资源文件,参数里的语言片段可以是目录、文件或者jar。如文件需要预先处理,可采用{}的方式来定义,如{}。
创建jar时,bnd会分析classes,并将其中引用到了但不在jar中的packages列入import list。这些import
list信息对应的放入Import-Package项中。正常情况下,Import-Package的参数为*,也就是说所有引用的packages都会被导入。但有些时候可能需要忽略其中的个别引用的package,那么可通过把import中的package 定义为optional或取消import该package,例如:
Import-Package: !com.acme.*, *;resolution:=optional
bnd文件由很多的属性构成,以大写字母开头的属性会作为元信息复制到manifest文件中,小写字母开头的属性则作为变量而使用。
Jar创建后,bnd会校验创建的结果,主要是依据mainfest文件来进行详细的校验,以确认bundle的有效性。bnd程序比传统的jar更高一级,除了jar的打包之外它还提供了一些其他的功能,它更强调以packages的角度来进行打包,而不仅仅是文件的角度,Bnd的打包方式保证了在打包生成Bundle时就可以检查出Bundle是否符合OSGi R4规范。
如打包生成的jar文件已存在并且没有文件需要更新,则bnd不会产生新的打包文件。
可以以几种方式来使用bnd:命令行、ant task、maven插件和Eclipse插件。
快速上手
resttemplate post请求json参数
假设我们需要在Eclipse中创建一个bundle,Eclipse中的每个java工程都是有类路径和源码的,因此Bnd可以获取到所有的classes,但它仍然无法知道你想怎么样组建jars/bundles,这就需要编写一个bnd file来告诉它,bnd file的文件名默认为bundle的symbolic name加.bnd来构成,例如ample.bnd就是一个典型的bnd文件的文件名,只要文件名不是bnd.bnd,那么.bnd前的字符串就会作为Bundle的symbolic name。
以aQute OSGi tutorial Chat为例,来创建一个bundle,这个bundle中有两个package:
z aQute.service.channel
typedef的用法cz aQute.tutorial.chat
aQute.service.channel包须对外提供,其他包则保持私有的状态,所有源码中引用到的不在classpath中的包都必须导入,要达到这个要求,bnd文件的写法如下所示:
Export-Package: aQute.service.channel; version=1.0
Private-Package: aQute.tutorial.chat
你要做的就只有这些,在Eclipse中,你可以选择这个bnd文件,然后点击右键选择其中的Make Bundle,将会创建一个包含以下目录和文件的jar:
META-INF
properties是什么文件MANIFEST.MF
aQute/service/channel
Channel.class
aQute/tutorial/chat
Chat$ChannelTracker.class
Chat.class
也可以通过命令行运行:
bnd aQute.tutorial.chat.bnd
来看看产生的jar文件里的manifest.mf文件,在命令行中可以通过bnd aQute.tutorial.chat.jar来查看,或直接使用winzip打开jar文件来看:
Manifest-Version: 1
Bundle-Name: aQute.tutorial.chat
Private-Package: aQute.tutorial.chat
Import-Package: aQute.service.channel;version=1.0,
org.osgi.framework; version=1.3,
org.acker;version=1.3
Bundle-ManifestVersion: 2
Bundle-SymbolicName: aQute.tutorial.chat
Export-Package: aQute.service.channel;version=1.0
Bundle-Version: 0
就像你所看到的,bnd补充了很多的头信息。第一个头信息:Manifest-Version是jar文件必须的;Bundle-Name 是根据Bundle-SymbolicName来生成的,因为在bnd文件中未指定;Private-Package头信息指定了不对外提供的packages;Import-Package头信息是bnd根据classes所引用的packages来生
成的,可以看到,bnd还提取了所
引用的package的版本信息,这些版本信息是从这些package的jar文件的manifest中获取的;Export-Package 显示了需要对外提供的package。在生成jar文件时,bnd会校验这些头信息是否符合OSGi规范,如不符合则会提供错误信息或警告信息。
Bnd文件格式
Bnd文件的格式和manifest.mf非常相似。尽管它是以properties文件的方式来读取的,还是可以使用':'作为分隔符。唯一要注意的就是bnd文件是不支持以空格开头的,每行的长度不限,key和value前后的空格都会被去除,请参见Properties来了解更多关于此格式的信息。
bnd文件具备几种不同的参数类型:
类型举例说明
Manifest headers  Bundle-
Description: ...
当首字母大写时,bnd会复制这些信息到manifest
中作为头信息。
Variables  Version=3.0  当首字母小写时bnd视其为变量。元信息可通过宏方
式来获取变量的值,变量是不会被复制到manifest
中的。请参见Macros。
Directives  -include: deflts.bnd  声明以'-'开头。声明是为了告诉bnd需要做一些特
殊的处理。请参见Directives
Bnd Directives
声明参数格式说明
-classpath  LIST把list中的文件加到bundle的classpath
中。这些文件的路径必须是相对bnd文件的
相对路径,且为jar文件或目录,例如:
-
classpath= acme.jar, junit.jar, bin  -donotcopy  REGEX当复制文件到jar中时,可以通过此参数来
控制不需要复制的文件。例如,CVS文件和
SVN文件不需要复制到jar中的,可以这么
写来实现:
-donotcopy= (CVS|.svn|.+.bak|~.+)
-include  LIST这个属性用来指定需要打入jar的文件。文
件路径为相对bnd文件的相对路径。如果引
用的是外部的文件,则外部文件中的文件路
径为相对该外部文件的相对路径。Includes
对于统一放置Bundle-Vendor和Bundle-
Copyright这样的属性值非常的有用。如果
文件的扩展名为mf,那么这个文件将作为
manifest文件进行解析。如果有很多个同样
的变量,只有最后一个变量会生效。文件名
可使用{user.home}这样的变量。如果文件不
存在,将会产生错误。如果文件名以'-'开
头,那么当文件不存在的时候将会忽略此错
误。例如:
-include= ${user.home}/deflts.bnd,
META-INF/MANIFEST.MF
-failok  true | false 在某些情况下,出现错误也不应该导致打包java和javaweb区别
退出。例如测试用例在打包时通常也需要运
行。如果这个参数设置为true,那么无论出
现什么错误都会产生bundle的jar文件,并
将错误信息列在错误文件中。如failok设置
为false,那么只要出错就不会产生Bundle
的jar文件。例如:
-failok= true
Export-Package  LIST of
PATTERN Export-Package列出了Bundle需要对外提供的package。参见ExportPackage.
Include-Resource  LIST of
iclause  Include-Resource使得Bundle可包含多个资源文件的路径。参见Include Resource.
Private-Package  LIST of
PATTERN Private-Package中列出了Bundle中需要包含但不对外提供的package。参见Private Package.
Import-Package  LIST of
PATTERN Import-Package列出了Bundle所需引用的package。参见Import Package.
Conditional-Package  LIST of 这是一个用来补充Private-Package的参
PATTERN数,使用这个参数后就指定了需要打包到
Bundle中的package,而且也只有这些
package会打包到Bundle中。
Bundle- SymbolicName  用户可设置Bundle-SymbolicName。默认情况下为bnd文件去除.bnd后的文件名,如bnd文件的文件名为bnd.bnd,那么就默认为bnd文件所在的目录名。也可使用${project}作为其名称。
Bundle-Name  如未设置Bundle-Name,将会将Bundle-Name
赋值为Bundle-SymbolicName的值。
Bundle- ManifestVersion  2  Bundle-ManifestVersion被设置为固定值
2。
Bundle-Version  VERSION  bundle的版本,如未设置此值,则默认为
0。
Service-Component  LIST of
component
参见Service Component Header.
Export-Package
bnd定义允许使用模式(经过修改的正则表示式)的方式来定义此参数。定义中所有的模式作用于classpath中的每个包。如模式为过滤模式(以!开头)并且与classpath中package匹配,那么打包时就会忽略此package。其他方式定义的Export-Package的package都会复制到目标bundle中。模式包含dire
ctives和属性,参数中的模式是按顺序生效的,排在前面的模式优先后面的模式而生效。下面的例子为对外提供除以'com'开头外的classpath中的所有的packages。默认的Export-Package为'*',对于非常大的bundles而言是很有效的。如果输出的packages有相关的版本信息(packageinfo文件的元数据信息中),那么这些版本信息将会自动添加到Export-Package中。
node工作流引擎Export-Package= !com.*, *
输出的package自动的列入Import-Package中,这个特性可通过在Export-Package中添加一个特殊的directive 来取消:-noimport:=true,例如:
Export-Package= com.acme.impl.*;-noimport:=true, *
Private-Package

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。