OSGI(2)_创建OSGi Hello World工程

来源:互联网 发布:优化产业结构什么意思 编辑:程序博客网 时间:2024/06/05 21:59

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的意义。

lifecycle2.png

下面,我们尝试构建这个bundle,利用maven的mvn package指令,我们可以得到一个jar包:demo1-1.0.jar

我们再从http://servicemix.apache.org 下载一个Servicemix,目前稳定版本是5.4.0;在文件夹里解压servicemix,我们可以看到servicemix的目录结构:

servicemixfolder.png

我们将demo1-1.0.jar放到deploy文件夹里,然后运行bin\servciemix.bat( windows)或bin/servicemix(linux).

demo1run.png

从上图,我们可以看到出现了“Hello world!"的字样,这个是activator的start方法的执行结果。

我们输入一个命令:list ,可以列出当前部署在servicemix上的bundle,我们部署的bundle demo1也在其中,每个bundle的前面都有一个bundle ID, 现在demo1的bundle ID是211

我们再输入一个命令:stop 211 ,就可以停止demo1这个bundle,我们可以看出,它执行了activator里的stop方法,输出了 “stop bundle!"的字样。

demo1-2.jpg

我们再执行一次list命令,可以看到bundle从原来的Active状态变成了Resolved的状态。

demo1-3.png

最后,我们用压缩软件(winrar、winzip)打开demo1-1.0.jar,从包里的META-INF里,可以找到一个MANIFEST.MF文件,查看一下MANIFEST.MF:

demo1-4.png

大家可以参照以上屏幕截图,结合manifest.mf文件的内容,理解一下manifest.mf的作用.

原创粉丝点击