使用Maven创建一个Bundle
SMX4使用了来自Apache felix的Maven bundle插件(Maven bundle plug-in),这个bundle插件是基于bnd工具的. 它可以通过内省打包到bundle内的类(classes)来自动构造OSGI bundle的manifest。
要使用此bundle插件,需要做如下事情:
1. 把这个bundle插件加入到你的项目的POM文件内。
2. 配置这个插件以便正确组装你的bundle的manifest。
搭建ESB OSGI项目需要做以下事情:
1. 将bundle插件加入到你的POM;
2. 告诉Maven去打包生成一个OSGI bundle。
在使用bundle插件之前,你必须增加Apache Felix的依赖(dependency),在增加这个依赖后,就可以在POM的plug-in部分加入bundile插件了。
增加OSGI bundle plugin-in 到POM
... <dependencies> <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.osgi.core</name> <version>1.0.0</version> </dependency> ... </dependencies> ... <build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <configuration> <instructions> <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName> <Import-Package>*,org.apache.camel.osgi</Import-Package> <Private-Package>org.apache.servicemix.examples.camel</Private-Package> </instructions> </configuration> </plugin> </plugins> </build> ...
Instructions元素包含了描述了bundle是如何构造的:
In order to instruct Maven to use the bundle plug-in you need to instruct it to package the results of the project as a bundle. You do this by setting the POM's packaging element to bundle.
所有的bundle插件的必需属性都有默认设置,我们也可以修改它们为我们想要的值。大部分的属性都定义在plug-in的instructions元素内。
下面是一些常用属性:
• Bundle-SymbolicName
• Bundle-Name
• Bundle-Version
• Export-Package
• Private-Package
• Import-Package
Bundle插件默认设定bundle的symbolic name属性值为groupId+”.”+artifactId,以下情况除外:
• 如果groupId只有一段(没有点),那么就用classes的第一个包名
• 如果artifactId和groupId的最后一段相同,那么使用groupId
• 如果artifactId以griupId的最后一段开始,那么相同的部分被去掉。
为了给bundle的symbolic name设定值,需要在plug-in的instructions元素下增加一个子元素Bundle-SymbolicName。
默认情况下,bundle的名称为${pom.name}。要设定bundle的名称需要在plug-in的instauctions元素下增加Bundle-Name子元素。
默认情况下,bundle的版本为${pom.version},所有‘-’均被替换为‘.’。要设定bundle的版本号需要在plug-in的instauctions元素下增加Bundle-Version子元素。
默认情况下,OSGI manifest的Export-Package列表是填充了所有你的project的class路径(与Bundle-SymbolicName.*匹配的)下所有packages。这些packeges也包括进了bundle。
重要: 如果在plug-in配置项内使用了Private-package元素,并且没有设定export的package列表,那么默认情况下认为没有packages被exported。只有被列在Private-Package元素内的packages才被包括进bundle,而且他们都将被export。
默认的行为会产生非常大的包,而且有些exported的包是应该private的。要更改export包列表,你可以添加一个Export-package子元素到plug-in的instructions元素下。
Export-Package元素定义了一个包列表,列表内的包将被包括进bundle并被exported。包的名称可以通过*匹配符来定义。
你可以通过在包名前加“!”排除指定的包,当想要排除某些包时,包列表中各个项的顺序是很重要的,处理列表时是按照顺序处理的,从开始就会忽略列出的排除项目。
默认情况下,包含在bundle内的所有packages都会exported。想要某些packages不被exported,需要在plug-in的instructions元素下加入Private-Package子元素。
Private-Package元素几乎和Export-Package元素一样。定义了一个package列表,bundle插件使用这个列表查找Project的classpath(包含在bundle内)下所有class,这些package包含在bundle,但不exported。
重要 :如果一个package既在Private-Package内,也在Export-Package内,且Export-Package在前面,那么这个Package将被加到bundle并且被Exported 。
默认情况下,bundle插件使用一个Package列表填充OSGI Manifest的Import-Package属性,Package列表内的package在bundle内被引用,但不包含进bundle。
虽然默认行为可以满足大部分典型项目,在某些情况下你会发现需要import某些packages,这些package不会被自动加到列表,默认行为也可能会导致不需要的packages被Imported。
要定义一个要被bundle插件imported 的package列表,需要在plug-in的instructions元素下增加Import-Packge子元素,Import-Packge子元素内package列表的语法和Export-Package,Private-Package元素相同。
重要 :当使用Import-Packge元素时,plug-in不会自动扫描bundle的内容,以确定是否有必须的import s,为了确保bundle内容被扫描,必须将 * 作为软件包列列表的最后一项。