OSGi実装であるApache Felixを触る機会があったので、Eclipse上で動作させる方法をメモしておきます。
1. Apache Felixのダウンロード公式サイトから downloads->Felix Framework Distributionをダウンロードします。
現時点での最新版は2.0.4。 Windows環境なので、zip版をダウンロードして、任意の場所に展開します。
2. Projectの作成続いてEclipseでJavaプロジェクトを作成します。
File -> New -> Java Project
Project name: felix-tutorial
として[Next]をクリック。
次のパネルでは
Default output folder: felix-tutorial/target/classes
として[Finish]をクリック。
次にプロジェクトのプロパティでソースフォルダをsrc/main/javaとsrc/main/resourcesに変更します。
ここら辺は後々Mavenプロジェクト化するときのことを考えてのことなので、
Mavenを使わない場合ではデフォルトのままで問題ないです。
3. Felixのコピー1.でダウンロードしたzipファイルを展開するとfelix-framework-2.0.4というディレクトリが作成されますが、
この配下のbin、bundle、confを2.で作成したプロジェクトの直下にコピーします。
コピーしたら、 bin/felix.jarをビルドパスに追加してください。
4. Felix Shellの起動次に Eclipse上でFelix Shellを起動します。
Run -> Run ConfigurationsでJava Applicationに起動構成を追加します。
Name: felix-tutorial - run
Project: felix-tutorial
Main class: org.apache.felix.main.Main
※Include system libraries when searching for a main classにチェック
Classpathタブを開いて、User Entriesにfelix.jarが追加されていることを確認してください。
追加されていない場合は[Add JARs]をクリックして追加してください。
ここまでが完了したら、[Apply]をクリック、[Run]をクリックしてください。
Console に「Welcome Felix」とメッセージが表示されれば成功です。
このとき、プロジェクト直下にfelix-cacheというディレクトリが作成されますが、これはFelixが利用するディレクトリです。
5. バンドルの作成Felixのチュートリアルそのまま。
- package net.masa.felix.tutorial1;
-
- import org.osgi.framework.BundleActivator;
- import org.osgi.framework.BundleContext;
- import org.osgi.framework.ServiceEvent;
- import org.osgi.framework.ServiceListener;
-
-
-
-
-
- public class Activator implements BundleActivator, ServiceListener {
-
- @Override
- public void start(BundleContext context) throws Exception {
- System.out.println("Starting to listen for service events.");
- context.addServiceListener(this);
- }
-
- @Override
- public void stop(BundleContext context) throws Exception {
- context.removeServiceListener(this);
- System.out.println("Stopped listennig for service events.");
-
- }
-
- @Override
- public void serviceChanged(ServiceEvent event) {
- String[] obj = (String[]) event.getServiceReference().getProperty(
- "objectClass");
- if (ServiceEvent.REGISTERED == event.getType()) {
- System.out.println("Service of type " + obj[0] + " registered.");
- } else if (ServiceEvent.UNREGISTERING == event.getType()) {
- System.out.println("Service of type " + obj[0] + " unregistered.");
- } else if (ServiceEvent.MODIFIED == event.getType()) {
- System.out.println("Service of type " + obj[0] + " modified.");
- }
- }
-
- }
package net.masa.felix.tutorial1;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
/**
* @author namiki
*
*/
public class Activator implements BundleActivator, ServiceListener {
@Override
public void start(BundleContext context) throws Exception {
System.out.println("Starting to listen for service events.");
context.addServiceListener(this);
}
@Override
public void stop(BundleContext context) throws Exception {
context.removeServiceListener(this);
System.out.println("Stopped listennig for service events.");
}
@Override
public void serviceChanged(ServiceEvent event) {
String[] obj = (String[]) event.getServiceReference().getProperty(
"objectClass");
if (ServiceEvent.REGISTERED == event.getType()) {
System.out.println("Service of type " + obj[0] + " registered.");
} else if (ServiceEvent.UNREGISTERING == event.getType()) {
System.out.println("Service of type " + obj[0] + " unregistered.");
} else if (ServiceEvent.MODIFIED == event.getType()) {
System.out.println("Service of type " + obj[0] + " modified.");
}
}
}
次にMANIFEST.MFを作成します。
src/main /resources/META-INF/tutorial1の配下にMANIFEST.MFを作成します。内容は以下の通りです。
Manifest-Version: 1.0
Bundle-Name: Service listener example
Bundle-Description: A bundle that displays messages at startup and when service events occur
Bundle-Vendor: Apache Felix
Bundle-Version: 1.0.0
Bundle-Activator: net.masa.felix.tutorial1.Activator
Import-Package: org.osgi.framework
バンドルの実体はjarなので、jarファイルを作成するためにここではantを利用します。
プロジェクト直下にbuildディレクトリを作成し、build.xmlを作成します。内容は以下の通りです。
- <project name="felix-tutorial" default="jar" basedir="..">
- <property name="src.dir" value="src/main/java">
- <property name="resources.dir" value="src/main/resources">
- <property name="manifest.file" value="${resources.dir}/META-INF/tutorial1/MANIFEST.MF">
- <property name="classes.dir" value="target/classes">
- <property name="dist.dir" value="target/jar">
- <property name="jar.name" value="tutorial1.jar">
-
- <target name="jar" depends="prepare">
- <jar jarfile="${dist.dir}/${jar.name}" basedir="${classes.dir}" manifest="${manifest.file}" update="false">
- </jar></target>
-
- <target name="prepare">
- <mkdir dir="${dist.dir}">
- <delete>
- <fileset dir="${dist.dir}">
- <include name="${jar.name}">
- </include></fileset>
- </delete>
- </mkdir></target>
- </property></property></property></property></property></property></project>
もうちょっと考えなければいけませんが今は簡単のためにこれで。
6. バンドルのインストールFelix Shellで以下のコマンドを実行します。
start file:/c:/%workspacepath%/felix-tutorial/target/jar/tutorial1.jar
%workspacepath% には自分のworkspaceのパスを入れてください。
実行してコンソールに「Starting to listen for service events.」というメッセージが表示されれば成功です。
停止・アンインストールについては、Felix Shellでpsコマンドを実行してIDを確認し、
stop %ID%
uninstall %ID%
で行うことができます。 Felix Shellを停止する場合hはshutdownコマンドを実行します。
追記:build.xmlの表示がおかしいですね。
「Blogger SyntaxHighlighter」が悪さをしてそうなんですが、
回避方法が不明なのでそのままにしておきます。
本来は、property要素は1行で記述していますし、target要素も適宜終了させています。