Tycho与Maven-Bundle-Plugin的对比 Maven与OSGi天生就是冤家:Maven通过pom.xml
描述一个产物的全部,而OSGi将这项工作交给了MANIFEST.MF
。
如果仅仅是一些定义信息还好说,但是Maven和OSGi都希望能够描述产物的依赖关系,在使用Maven开发OSGi bundle的时候,就导致了一个问题:
依赖关系到底是在pom.xml
中描述,还是在MANIFEST.MF
中描述?
前面提到的Tycho 的思路是由MANIFEST.MF
自行管理bundle的依赖关系,pom.xml
只记录使用maven进行构建时需要的信息,比如maven工程的父子关系、打包时需要的bundle仓库及要发布的目标平台等。
Tycho的这种机制对Eclipse IDE比较友好,在开发期间完全使用IDE的机制进行开发和调试,只有在打包部署时才依赖maven。
Apache Felix Maven-Bundle-Plugin 则使用另一套机制:使用Maven-Bundle-Plugin,在开发时可以没有MANIFEST.MF
文件!Maven-Bundle-Plugin在pom.xml
中复制了一套MANIFEST.MF
的元数据,完全可以通过pom.xml
文件中的定义生成出完整的MANIFEST.MF
文件。
Maven-Bundle-Plugin的这种机制使得工程完全的”maven化”,更适合传统非OSGi开发人员的使用习惯。但是无法很好的利用IDE的开发和调试功能,比如,你可能需要自己搭建一个运行环境从IDE中调用。
两种方式可谓各有千秋。但是Tycho明显基于Equniox和Eclipse,比如,Tycho可以配置Eclipse p2站点作为bundle库。如果要使用Tycho开发和调试Felix,需要搭建一个Eclipse风格的p2站点,将Felix runtime和需要的各种bundle都放到该站点中并发布,然后在Tycho中引用该站点 。更详细的说明可以参考这里 。
而Felix Maven-Bundle-Plugin对于各种OSGi runtime的支持是相同的,由于完全基于maven,使用任何IDE开发bundle的效果都差不多。通常,Felix系的平台,如Karaf、Geronimo、Camel、ServiceMix、Fuse等,其例子都是使用Maven-Bundle-Plugin构建的。
由于前文已经说明了如何用Tycho开发OSGi ,下面只给出使用Maven-Bundle-Plugin的例子。
Maven-Bundle-Plugin的pom例子 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>thinkinside.demo.osgi</groupId> <artifactId>simple-bundle</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <executions> <execution> <id>generate-resources</id> <goals> <goal>manifest</goal> </goals> <configuration> <instructions> <Bundle-Name>${project.name}</Bundle-Name> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-Activator>test.bundle.internal.Activator</Bundle-Activator> <Export-Package>***</Export-Package> <Import-Package>***</Import-Package> <Private-Package>***</Private-Package> </instructions> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.3.1</version> <configuration> <archive> <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile> </archive> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.osgi.core</artifactId> <version>1.4.0</version> </dependency> </dependencies> </project>
使用Maven-Bundle-Plugin构建bundle,就是构建一个简单的jar。不同之处在于:要通过pom.xml中的信息生成符合OSGi要求的MANIFEST.MF
文件并打包到jar中。这通过两个插件来完成:
org.apache.felix:maven-bundle-plugin
在项目生命周期的”generate-resources”阶段,根据<instructions>
标签内定义的信息生成MANIFEST.MF
文件。这里可以配置OSGi所需要的全部元数据。
org.apache.maven.plugins:maven-jar-plugin
配置其在打包是使用前面生成的MANIFEST.MF
文件
由于OSGi bundle通常会使用OSGi API,这里添加了org.apache.felix:org.osgi.core的依赖。当然也可以换成其他的OSGi运行时,比如Equinox。
此时,使用mvn package
生成的jar包中,MANIFEST.MF
文件内已经添加了配置好的bundle信息。
当然,使用maven-bundle-plugin的目标(Goals) 可以进行更细致的控制。
在Eclipse中运行和调试 本来,传说中的Pax Cursor 可以在Eclipse中基于各种OSGi runtime运行和调试bundle,但是天朝的网络中似乎不存在ops4j.org
这个域名。
好在我们可用一个Java Project的方式建立起Felix的环境,通过Eclipse对bundle进行运行和调试。 由于这里 有非常详细的说明,故不再赘述。
其实,我们还可以基于maven构建,而不是使用Java Project的方式。使用maven的好处是这种方法可以用于任何支持maven的IDE。
Felix runtime的主要内容包括:
其中:
bin/felix.jar 启动的jar, MainClass是org.apache.felix.main.Main
bundle/ 存放可用的bundle,Felix runtime中内置了4个必需的bundle
conf/conf.properties 启动配置。类似于Eclipse的configuration/config.ini
。Felix配置项可以参考官方网站中的内容
知道了Felix runtime的构成,就可以用maven构建出相同的结构,并插入到项目周期的适当位置。pom如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>thinkinside.demo.fuse</groupId> <artifactId>felix-launcher</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Felix Launcher</name> <properties> <felix.bundlerepository.version>1.6.4</felix.bundlerepository.version> <felix.gogo.version>0.10.0</felix.gogo.version> <felix.framework.version>4.2.1</felix.framework.version> </properties> <build> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>2.4.1</version> <configuration> <filesets> <fileset> <directory>bundle</directory> </fileset> </filesets> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.2</version> <executions> <execution> <id>copy</id> <phase>generate-resources</phase> <goals> <goal>copy</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.gogo.command</artifactId> <version>${felix.gogo.version}</version> </artifactItem> <artifactItem> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.gogo.runtime</artifactId> <version>${felix.gogo.version}</version> </artifactItem> <artifactItem> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.gogo.shell</artifactId> <version>${felix.gogo.version}</version> </artifactItem> <artifactItem> <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> <version>4.2.0</version> </artifactItem> </artifactItems> <outputDirectory>bundle</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.main</artifactId> <version>${felix.framework.version}</version> </dependency> <dependency> <groupId>org.ops4j.pax.url</groupId> <artifactId>pax-url-assembly</artifactId> <version>1.6.0</version> </dependency> </dependencies> </project>
该pom在标准的生命周期中增加了两项工作:
在generate-resources
阶段,创建bundle文件夹,复制必需的4个bundle
在clean
阶段,清除bundle文件夹
最后,还需要一个配置文件。在工程目录建立/conf/config.properties
文件,并进行基本配置:
1 2 3 4 felix.auto.deploy.action=install,start felix.log.level=1 org.osgi.framework.storage.clean=onFirstInit
配置完成了,先执行mvn compile
生成需要的资源。此时使用命令mvn exec:java -Dexec.mainClass="org.apache.felix.main.Main"
即可以启动Felix runtime:
在Eclipse中,将这个工程作为Java Application
运行,选择org.apache.felix.main.Main
作为Main Class,就可以进行运行和调试。