OSGI(2)_创建OSGi Hello World工程
OSGI bundle工程
在学完《走近Java模块化系统OSGi》后我们已对osgi有初步的印象,今天我们将从一个hello world来具体地接触osgi。
我们将采用maven来构建一个简单的bundle,不熟悉maven的同学请先了解一下再继续。我们还会使用servicemix来做运行时平台,至于IDE,则不限。
首先是maven项目的pom.xml,如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:pom="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<groupId>com.ponder.Demo</groupId>
<artifactId>demo1</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>Demo:demo1:1.0</name>
<url>http://Demo.ponder.com/demo1/</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>${project.build.finalName}.jar</Class-Path>
<Built-By>Ponder</Built-By>
<Bundle-ManifestVersion>2</Bundle-ManifestVersion>
<Bundle-Name>${project.groupId}.${project.ArtifactId}</Bundle-Name>
<Bundle-SymbolicName>${project.name}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Bundle-Vendor>${project.groupId}</Bundle-Vendor>
<Bundle-Activator>com.ponder.Demo.demo1.activator</Bundle-Activator>
<Export-Package>com.ponder.Demo.demo1;version="1.0"</Export-Package>
<Import-Package>org.osgi.framework</Import-Package>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>4.2.0</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
在这个POM里,我们使用了Maven-jar-plugin插件,这个插件在这个课程中十分重要,它负责了OSGI bundle的Manifest.mf的构建。
而另一个选择就是Maven-Bundle-plugin,也能实现同样的目的,而且更强大,甚至能够自动生成bundle的manifest.mf里的数据项,但我不推荐,因为我认为Manifest.mf里的数据项的定制是一个设计问题,我们不能指望一个机器去“艺术地”设计,而Maven-jar-plugin给我们更大的*度,更"纯粹"。
OSGI Activator
我们先定义一个类com.ponder.Demo.demo1.activator:
package com.ponder.Demo.demo1;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
/**
*
* @author han
*/
public class activator implements BundleActivator{
@Override
public void start(BundleContext context) throws Exception {
System.out.println("Hello world!");
}
@Override
public void stop(BundleContext context) throws Exception {
System.out.println("Stop bundle!");
}
}
这个类实现了OSGI的BundleActivator接口,这个接口有两个方法:start和stop,顾名思义,start就是bundle在启动时需执行的方法,而stop则是bundle停止时需执行的方法。
我们可以回头看看OSGi入门,关于bundle的生命周期的图,可以帮助我们理解activator的意义。
下面,我们尝试构建这个bundle,利用maven的mvn package指令,我们可以得到一个jar包:demo1-1.0.jar
我们再从http://servicemix.apache.org 下载一个Servicemix,目前稳定版本是5.4.0;在文件夹里解压servicemix,我们可以看到servicemix的目录结构:
我们将demo1-1.0.jar放到deploy文件夹里,然后运行bin\servciemix.bat( windows)或bin/servicemix(linux).
从上图,我们可以看到出现了“Hello world!"的字样,这个是activator的start方法的执行结果。
我们输入一个命令:list ,可以列出当前部署在servicemix上的bundle,我们部署的bundle demo1也在其中,每个bundle的前面都有一个bundle ID, 现在demo1的bundle ID是211
我们再输入一个命令:stop 211 ,就可以停止demo1这个bundle,我们可以看出,它执行了activator里的stop方法,输出了 “stop bundle!"的字样。
我们再执行一次list命令,可以看到bundle从原来的Active状态变成了Resolved的状态。
最后,我们用压缩软件(winrar、winzip)打开demo1-1.0.jar,从包里的META-INF里,可以找到一个MANIFEST.MF文件,查看一下MANIFEST.MF:
大家可以参照以上屏幕截图,结合manifest.mf文件的内容,理解一下manifest.mf的作用.