Hatena::ブログ(Diary)

Fly me to the Juno! このページをアンテナに追加 RSSフィード

2010-01-16

Pax Constructを使って、Web Consoleを立ち上げてみる(その2)

HTTP Serviceが立ち上がった事を確認した後は、Web Consoleを入れてみましょう。下記の二つのBundleを、pax-import-bundleを使って追加してみてくだし。

    <dependency>
      <groupId>org.apache.felix</groupId>
      <artifactId>org.osgi.compendium</artifactId>
      <version>1.4.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.felix</groupId>
      <artifactId>org.apache.felix.webconsole</artifactId>
      <version>2.0.4</version>
    </dependency>

その1で後からコマンドでシステムプロパティを設定してましたが、もちろんpom.xmlに書いた方がいいので、追加しましょう。provision/pom.xmlとかではなく、直下のpom.xml、すなわち./pom.xmlを開いてシステムプロパティを追加します。

  <properties>
    
    <org.apache.felix.http.jettyEnabled>true</org.apache.felix.http.jettyEnabled> 
    <org.osgi.service.http.port>8080</org.osgi.service.http.port>
    <org.osgi.service.http.port.secure>8443</org.osgi.service.http.port.secure>
  </properties>

その後、再度起動してみましょう。うまくいくとhttp://localhost:8080/system/consoleにアクセスするとwebconsoleが開くはずです。

インタフェースのみを提供するBundleの意味

ここで追加したorg.osgi.compendiumですが、サービスに関してはインタフェースのみ提供しています。試しにConfigurationタブを開いてみてください。今は下記のようなページが開かれるはずです。

f:id:kompiro:20100117012545p:image

続いて、ConfigAdminの実装を提供するBundle:org.apache.felix.configadminをstopしてみましょう。

  • felixを使ってる場合はpsコマンドを実行し、"Apache Felix Configuration Admin Service"とかかれているBundleのIDを調べ、stop [id]コマンドを実行
  • equinoxを使っている場合はssコマンドを実行し、"org.apache.felix.configadmin"と書かれたBundleのIDを調べ、stop [id]コマンドを実行

そして、再度http://localhost:8080/system/console/configMgrを開くとこんな感じで "Configuration Admin Service not available"と表示されます。

f:id:kompiro:20100117013411p:image

これは、Bundleがインストールされていない状態でも同じです。org.osgi.compediumがserviceのインタフェースを提供しているため、なんとか動いているのです。

それじゃFelix Web Consoleを最小構成はどんなの?

なるほど。org.osgi.compediumがインタフェースを提供しているのであれば、最小構成があるはず!と思って調べてみたら、下記の4つがあればとりあえず動くことがわかりました。

  • org.apache.felix.http.bundle
  • org.osgi.compendium
  • org.apache.felix.webconsole
  • org.apache.felix.configadmin

org.apache.felix.configadminが必要なのは、org.apache.felix.http.bundleの起動時に参照されるサービスだからです。

次回は実際にサービスはどうやってつくっていくのか、Declartive Serviceを使った連携を見ていきます。*1

*1:ServiceTrackerやServiceListener方式はもう古いんですって

2010-01-14

Pax Constructを使って、Web Consoleを立ち上げてみる(その1)

今度はPax Constructを使ってFelix Web Consoleを起動するところまでやってみた。Felix Web Consoleについて触れると、稼働中のOSGiコンテナの状況をブラウザを使ってみることができます。

f:id:kompiro:20100114075545p:image

例えばServiceの稼働状況、参照関係、とかもみられます。Felixを起動すると一緒に立ち上がっているShellコンソールも操作できちゃいます。

f:id:kompiro:20100114075746p:image

便利ですね。

まずはHTTPServiceを立ち上げる。

それじゃPax Constructを使って、まずはHTTP Serviceを立ち上げてみます。HTTP Serviceは、HTTPサービスをOSGiコンテナ上に載っけたものです。HTTP ServiceはFelix Projectで用意されています。(詳細な説明ページはこちら)このサブプロジェクトから提供されているBundleはいくつかあります。

  • org.apache.felix.http.bundle - 下記に書いてくBundleをひとまとめにしたBundle
  • org.apache.felix.http.jetty - 組み込みJettyサーバを利用したHTTP Service実装
  • org.apache.felix.http.whiteboard - いろんなHTTP Service実装でも使えるホワイトボードです。ホワイトボードと聞くとビックリですが、いろんなBundleがServletやらFilterを登録できる機能の事っす。
  • org.apache.felix.http.bridge - APサーバをホストに使ったHTTP Service 実装(ブリッジモード).proxyと一緒に使わないと使えません。
  • org.apache.felix.http.proxy - APサーバの内部にWARとしてデプロイするとして必要なProxyを提供

ということで、org.apache.felix.http.bundleをインポートしてみましょう。まず、今回用のBundle実行プロジェクトを作ります。

$ pax-create-project

pax-create-project -g groupId -a artifactId [-v version] [-o] [-- mvnOpts ...]

groupId (examples) ? org.kompiro
artifactId (myProject) ? webconsole
version (1.0-SNAPSHOT) ? 

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [org.ops4j:maven-pax-plugin:1.4:create-project] (aggregator-style)
[INFO] ------------------------------------------------------------------------
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12 seconds
[INFO] Finished at: Thu Jan 14 07:25:05 JST 2010
[INFO] Final Memory: 10M/18M
[INFO] ------------------------------------------------------------------------

ちょっと怒られたけど、無事webconsoleの実験環境の作成完了。作成直後の環境はこんな感じ

/webconsole$ ls -R
.:
pom.xml  poms provision

./poms:
compiled pom.xml wrappers

./poms/compiled:
pom.xml

./poms/wrappers:
pom.xml

./provision:
pom.xml

続いてprovision/pom.xmlを開いてみましょう。

<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">

  <parent>
    <groupId>org.kompiro</groupId>
    <artifactId>webconsole</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <modelVersion>4.0.0</modelVersion>
  <groupId>org.kompiro.webconsole.build</groupId>
  <artifactId>provision</artifactId>

  <name>webconsole - imported bundles</name>

  <packaging>pom</packaging>

  

</project>

今は何もないのが分かっていただけるでしょうか。このpom.xmlですが、実はpax-import-bundleを実行すると、インポートされるBundleが追記されていくことが分かりました。試しにorg.apache.felix.http.bundleをインポートします。

$ pax-import-bundle -g org.apache.felix -a org.apache.felix.http.bundle -v 2.0.4
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building org.kompiro.webconsole (OSGi project)
[INFO]    task-segment: [org.ops4j:maven-pax-plugin:1.4:import-bundle] (aggregator-style)
[INFO] ------------------------------------------------------------------------
...
[INFO] [pax:import-bundle]
[INFO] Importing Apache Felix Http Bundle to org.kompiro.webconsole.build:provision:pom:1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8 seconds
[INFO] Finished at: Thu Jan 14 07:27:16 JST 2010
[INFO] Final Memory: 8M/17M
[INFO] ------------------------------------------------------------------------

もう一回provision/pom.xmlを開いてみると・・・。

<project>
... 中略 ...
  

  <dependencies>
    <dependency>
      <groupId>org.apache.felix</groupId>
      <artifactId>org.apache.felix.http.bundle</artifactId>
      <version>2.0.4</version>
    </dependency>
  </dependencies>

</project>

追加されてました。試しに起動してみましょう。

$ pax-provision
[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   org.kompiro.webconsole (OSGi project)
[INFO]   webconsole - plugin configuration
[INFO]   webconsole - wrapper instructions
[INFO]   webconsole - bundle instructions
[INFO]   webconsole - imported bundles
[INFO] ------------------------------------------------------------------------
[INFO] Building org.kompiro.webconsole (OSGi project)
[INFO]    task-segment: [org.ops4j:maven-pax-plugin:1.4:provision] (aggregator-style)
[INFO] ------------------------------------------------------------------------
... 中略 ...
Welcome to Felix
================

-> [INFO] Started bridged http service

起動しましたね。Bundleの稼働状況はどうでしょう。

ps
START LEVEL 6
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (2.0.1)
[   1] [Active     ] [    5] Apache Felix Http Bundle (2.0.4)
[   2] [Active     ] [    1] Apache Felix Shell Service (1.4.1)
[   3] [Active     ] [    1] Apache Felix Shell TUI (1.4.1)

動いているみたいです。ドキュメントによると8080ポートでサーバが立ち上がってるらしい。つないでみると・・・

f:id:kompiro:20100115004723p:image

動いてないじゃん。一回Bundleを再起動してみましょう。

-> stop 1
-> start 1
-> org.osgi.framework.BundleException: Activator start error in bundle org.apache.felix.http.bundle [1].
... 中略 ...
        ... 19 more
java.lang.NoClassDefFoundError: org/osgi/service/cm/ManagedService

ということで、足らないパッケージがあるみたいです。今回は"org.osgi.service.cm"をExportしているBundleがありません。このパッケージを持っているのはConfig Adminなので、インストールします。

$ pax-import-bundle -g org.apache.felix -a org.apache.felix.configadmin -v 1.2.4
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building org.kompiro.webconsole (OSGi project)
[INFO]    task-segment: [org.ops4j:maven-pax-plugin:1.4:import-bundle] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [pax:import-bundle]
Downloading: http://repo1.maven.org/maven2/org/apache/felix/org.apache.felix.configadmin/1.2.4/org.apache.felix.configadmin-1.2.4.pom
[INFO] Importing Apache Felix Configuration Admin Service to org.kompiro.webconsole.build:provision:pom:1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9 seconds
[INFO] Finished at: Thu Jan 14 07:35:36 JST 2010
[INFO] Final Memory: 8M/17M
[INFO] ------------------------------------------------------------------------

このpax-import-bundleですが、Maven Repositoryに存在しないBundleも存在するものとして扱うのが玉に瑕ですが、便利です。それでは立ち上げてみましょう。Felixだと足らない要素をみるコマンドが見当たらないので、Equinoxに切り替えます。

$ pax-provision -f equinox
[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   org.kompiro.webconsole (OSGi project)
[INFO]   webconsole - plugin configuration
[INFO]   webconsole - wrapper instructions
[INFO]   webconsole - bundle instructions
[INFO]   webconsole - imported bundles
[INFO] ------------------------------------------------------------------------
... 中略 ...
osgi> ss

Framework is launched.

id      State       Bundle
0       ACTIVE      org.eclipse.osgi_3.5.1.R35x_v20090827
1       RESOLVED    org.apache.felix.http.bundle_2.0.4
2       ACTIVE      org.apache.felix.configadmin_1.2.4

おや?org.apache.felix.http.bundleが起動しない。足らないものはなんだろう。

osgi> diag 1
initial@reference:file:../bundles/org.apache.felix.http.bundle_2.0.4.jar/ [1]
  Direct constraints which are unresolved:
    Missing imported package org.osgi.service.log_1.3.0.
    Missing imported package org.slf4j_0.0.0.

ふむ。org.osgi.service.logとorg.slf4jがないのか。再度pax-import-bundleでこれらのBundleを取得しよう。

osgi> exit

ってな感じで、足らないBundleを追加していきます。*1ここから示すBundleをインポートしてみてください。直接provision/pom.xmlのDependencyに追記するのでもいいですが、コマンドを叩いてみた方が面白いです。-gはgroupId、-aはartifactId、-vはバージョンに対応します。

    <dependency>
      <groupId>org.apache.felix</groupId>
      <artifactId>org.apache.felix.log</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>org.slf4j.simple</artifactId>
      <version>1.5.10</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.5.10</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>1.5.10</version>
    </dependency>

それでは再度felixを起動してみます。

$ pax-provision
[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   org.kompiro.webconsole (OSGi project)
[INFO]   webconsole - plugin configuration
[INFO]   webconsole - wrapper instructions
[INFO]   webconsole - bundle instructions
[INFO]   webconsole - imported bundles
... 中略 ...
Welcome to Felix
================

Auto-properties start: org.osgi.framework.BundleException: Fragment bundles can not be started.
-> [INFO] Started bridged http service

スタートしました。Bundleの状況をみてみましょう。

ps
START LEVEL 6
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (2.0.1)
[   1] [Active     ] [    5] Apache Felix Http Bundle (2.0.4)
[   2] [Active     ] [    5] Apache Felix Configuration Admin Service (1.2.4)
[   3] [Active     ] [    5] Apache Felix Log Service (1.0.0)
[   4] [Active     ] [    5] slf4j-api (1.5.10)
[   5] [Resolved   ] [    5] slf4j-simple (1.5.10)
[   6] [Active     ] [    1] Apache Felix Shell Service (1.4.1)
[   7] [Active     ] [    1] Apache Felix Shell TUI (1.4.1)

すべて起動しています。実は、org.apache.felix.http.bundleは、bridge modeも内蔵しているので、組み込みモードで実行するにはシステムプロパティを設定する必要があります。それを設定してみて、Apache Felix Http Bundleを再度起動してみてください。

-> sysprop org.apache.felix.http.jettyEnabled true
Set org.apache.felix.http.jettyEnabled=true
-> stop 1
-> start 1

再度http://localhost:8080/にアクセスすると、Jettyのエラーが表示されるはずです。ちょっと長くなったので、今日はこの辺で。

*1:Bundleをグループ単位で扱うprofileと言う便利な仕組みがPaxシリーズにありますが、これは後日紹介します。

2010-01-09

Pax Examの使い方

Pax Constructの次はPax Exam、ということで試してみました。今回は404 Not Foundを参照しながらやってみました。

Pax Examの目的

Pax ExamはOSGi環境における試験用の環境を構築してくれるものです。*1例えばPax Examを用いてベースとなるOSGiコンテナを切り替えてもBundleが読み込まれるかとか、Bundle間連携がうまくいくかとか、そういうテストを行います。個々のBundleに閉じたテストも行うことはできますが、それは通常のJUnitを使ったテストで十分です。なぜなら、個々のBundle単体でみた場合、JARファイルと大きな違いはないからです。Pax Examは、開発されたBundleを統合して、システムテストを行う環境として開発されたのでしょう。それでは手順をみていきましょう。

Pax Exam環境を構築する

まずPax Exam環境を構築しましょう。Pax Exam環境は、Bundleを統合するテストを行う環境なので、個々のBundleとは違うBundleを作成した方がわかりやすいです。またPax Examのテストクラスを開発するBundleは、Pax Constructを使用して、適当なPax Exam用のBundleを作成し、404 Not Foundに記述されているpax-exam、pax-exam-junit、pax-exam-container-defaultの3つをpom.xmlに追記しました。

テストを書いてみる

それではPax Examを使ったテストを書いてみます。Pax Examで作成するテストクラスは、実際にアプリケーションを構成するBundleとは別のプロジェクトにした方がいいです。通常のJUnit4Runnerではなく、PaxRunnerで用意されたJUnit4TestRunnerを@RunWithで指定します。見ていくと分かるんですが、起動するOSGiフレームワークの指定なんかも、このテストクラスの中で書きます。テストで必要なBundleも、テストクラスの中で指定します。

import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.junit.JUnit4TestRunner;

@RunWith( JUnit4TestRunner.class )
public class MyJUnitTest{
  @Test
  public void testMethod(){

  }
}

Bundle単体のテストは、OSGiコンテナ上に載せてから行うんじゃなく、通常のJUnitのテストで行うと割り切っているんでしょう。Bundle単体で考えた場合、クラスローダ環境は、そのBundle単体とOSGi環境と変わりない、として考えられているんじゃないっすかね。this.getClass().getResouce(String)で読む限り、リソースの読み方も違いないですから。OSGi環境に置ける大事な考え方なんですが、基本的に他のBundleの中身を読むことはできません。Bundleが変われば違う世界。なので、これまでのアプリケーションのように、利用しているライブラリの中身を読む、みたいな事はライブラリ役のBundleが許可していない限りできないので、これでテスト環境としては十分です。それではテストを実行してみてください。コンソール上にfelixが立ち上がり、何事もなく終わってくれたでしょうか?

起動したOSGiコンテナのBundleContextをテストクラスにInject

OSGiコンテナのBundleContextを使ったテストをやるにはこんな感じで@Injectを指定すればおkです。

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.osgi.framework.BundleContext;
import org.ops4j.pax.exam.Inject;
import org.ops4j.pax.exam.junit.JUnit4TestRunner;

@RunWith( JUnit4TestRunner.class )
public class MyJUnitTest{
  @Inject
  private BundleContext bundleContext;

  @Test
  public void testMethod(){
    assertThat( bundleContext, is( notNullValue() ) );
  }
}

BundleContextなんてテスト中に何をするんだろう、と思ったあなた。このテストケースはあくまでOSGiコンテナ上での統合テストです。いや、BundleContextなんていいから、直接BundleContextに登録されているサービスをインジェクトしろよ、と思ったあなた。この段階では、実際はなにもBundleが登録ていないので、なんもサービスはありません。実行してみてください。

指定したBundleをOSGiコンテナにインストールしてテストする

OSGiコンテナにBundleをインストールすることをPax Examではprovisionと呼んでいます。サンプルのテストコードをみると分かるんですが、Bundle化されたJARファイルをURLで指定してます。*2

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.ops4j.pax.exam.CoreOptions.*;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.Configuration;
import org.ops4j.pax.exam.junit.JUnit4TestRunner;

@RunWith( JUnit4TestRunner.class )
public class MyJUnitTest{

  @Configuration
  public static Option[] configuration(){
    return options(
      provision(
        bundle( "http://repository.ops4j.org/maven2/org/ops4j/pax/logging/pax-logging-api/1.3.0/pax-logging-api-1.3.0.jar" ),
        bundle( "http://repository.ops4j.org/maven2/org/ops4j/pax/logging/pax-logging-service/1.3.0/pax-logging-service-1.3.0.jar" ),
        mavenBundle().groupId( "org.ops4j.pax.url" ).artifactId( "pax-url-mvn" ).version( "0.3.2" )
      )
    );
  }

  @Test
  public void testMethod() throws Exception{
    assertThat( new URL( "mvn:org.ops4j.pax.web/pax-web-service" ).openStream(), is( notNullValue() ) );
  }
}

開発中のBundleもmavenBundle()で指定出来ます。Configurationで指定されているprovision()等のメソッドを提供しているのは「import static org.ops4j.pax.exam.CoreOptions.*;」なので、つけるのを忘れないでください。

じゃ、Felix以外のコンテナに載っけてみっか。

Felix以外のコンテナに載せるには下記のように指定します。

  @Configuration
  public static Option[] configuration()
  {
    return options(
      frameworks(
        felix(),
        equinox(),
        knopflerfish()
      )
    );
  }

この例ではFelixでテストを行った後、equinoxを起動し、さらにknopflerfishでもテストを行います。もちろん単体でも実行可能です。この@Configurationではシステムプロパティとか、ブート時のパッケージ等も指定できます。ブート時のパッケージ指定は、組み込みの用途でしょう。Webアプリケーションとか、PC用のアプリケーションでは使うことはないと思います。お伝えしたかったのは、@Configurationには大抵の環境のシミュレーションができるということ。詳しくは404 Not Foundをみてみませう。

Pax Constructの使い方

Pax ConstructはOSGi bundleの作成や、ビルド等々を助けてくれるスイスアーミーナイフと紹介されています。これからOSGi Bundleを作成するのに便利そうですね!ということで、試してみました。Pax系のツールはMaven2と組み合わせる事で有効にプロジェクトの補助をしてくれるそうなので、Maven2のインストールは忘れずに。MavenizeされたOSGiプロジェクトが作られていく感じなんでしょうね。

プロジェクトのページはこちら。404 Not Found最新は1.4です。

404 Not Foundをまずやってみます。

Pax Constructはスクリプトなので、Pax Constructをダウンロード後、忘れずにPATHを通しましょう。

まずプロジェクト作ってみよう。

それじゃプロジェクトを作ってみます。pax-create-projectを実行します。パラメータを指定すると初期値の指定になるようですが、そのまま実行してみたら、対話シェルになったよ。

$ pax-create-project 

pax-create-project -g groupId -a artifactId [-v version] [-o] [-- mvnOpts ...]

groupId (examples) ? kompiro
artifactId (myProject) ? hello-pax
version (1.0-SNAPSHOT) ? 

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [org.ops4j:maven-pax-plugin:1.4:create-project] (aggregator-style)
[INFO] ------------------------------------------------------------------------

...ライブラリのダウンロード

[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: packageName, Value: kompiro.hello-pax
[INFO] Parameter: archetypeVersion, Value: 1.0.3
[INFO] Parameter: groupId, Value: kompiro
[INFO] Parameter: archetypeArtifactId, Value: maven-archetype-osgi-project
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: archetypeGroupId, Value: org.ops4j.pax.construct
[INFO] Parameter: basedir, Value: /home/kompiro/codes/java/osgi-demo
[INFO] Parameter: package, Value: kompiro.hello-pax
[INFO] Parameter: artifactId, Value: hello-pax
[INFO] ********************* End of debug info from resources from generated POM ***********************
[INFO] Archetype created in dir: /home/kompiro/codes/java/osgi-demo/hello-pax
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13 seconds
[INFO] Finished at: Sat Jan 09 17:23:49 JST 2010
[INFO] Final Memory: 10M/18M
[INFO] ------------------------------------------------------------------------

どうなったのか、中を見てみる。

$ ls
pom.xml pomse provisione

すっきりしたもんですね。

Bundleを作ろう

続いてBundleを作ってみますか。

$ pax-create-bundle -p org.kompiro.osgi.hello -n hello
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building kompiro.hello-pax (OSGi project)
[INFO]    task-segment: [org.ops4j:maven-pax-plugin:1.4:create-bundle] (aggregator-style)
[INFO] ------------------------------------------------------------------------

...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11 seconds
[INFO] Finished at: Sat Jan 09 17:28:41 JST 2010
[INFO] Final Memory: 10M/18M
[INFO] ------------------------------------------------------------------------

OSGiコンテナへデプロイ

Quick Startよろしく、felixにデプロイしてみる。

$ mvn clean install pax:provision
...
[INFO] [pax:provision]
[INFO] Installing /home/kompiro/codes/java/osgi-demo/hello-pax/runner/deploy-pom.xml to /home/kompiro/.m2/repository/kompiro/hello-pax/build/deployment/1.0-SNAPSHOT/deployment-1.0-SNAPSHOT.pom
__________                 __________                                 
\______   \_____  ___  ___ \______   \__ __  ____   ____   ___________
|     ___/\__  \ \  \/  /  |       _/  |  \/    \ /    \_/ __ \_  __ \
|    |     / __ \_>    <   |    |   \  |  /   |  \   |  \  ___/|  | \/
|____|    (____  /__/\_ \  |____|_  /____/|___|  /___|  /\___  >__|   
               \/      \/         \/           \/     \/     \/       

Pax Runner (1.3.0) from OPS4J - http://www.ops4j.org
----------------------------------------------------

うぉ。Pax Runnerじゃないですか。

... ダウンロード等
Welcome to Felix
================

-> STARTING org.kompiro.osgi.hello
REGISTER org.kompiro.osgi.hello.ExampleService

お!felixさん、こんにちは。helpって打ち込めばコマンドわかるかな。

help
bundlelevel
cd
find
headers
help
inspect
install
log
ps
refresh
resolve
shutdown
start
startlevel
stop
sysprop
uninstall
update
version

じゃ、この中からBundleのリストを見るpsを実行してみる。

-> ps
START LEVEL 6
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (2.0.1)
[   1] [Active     ] [    5] kompiro.hello-pax.hello [org.kompiro.osgi.hello] (1.0.0.SNAPSHOT)
[   2] [Active     ] [    1] Apache Felix Shell Service (1.4.1)
[   3] [Active     ] [    1] Apache Felix Shell TUI (1.4.1)

よし、終了。

-> shutdown
-> STOPPING org.kompiro.osgi.hello

 -> Platform has been shutdown.
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 minutes 27 seconds
[INFO] Finished at: Sat Jan 09 17:34:49 JST 2010
[INFO] Final Memory: 20M/36M
[INFO] ------------------------------------------------------------------------

OSGiコンテナを切り替える

ん?よくよくみたら、pax-provisionなんてコマンドがある。こっちのヘルプを見てみると、こんな感じ。404 Not Foundデフォルトはfelixかな?起動してみる。

$ pax-provision
...中略
Welcome to Felix
================

-> STARTING org.kompiro.osgi.hello
REGISTER org.kompiro.osgi.hello.ExampleService

やっぱりfelixだった。じゃ、equinoxもいってみっか。

$ pax-provision -f equinox
...中略
osgi> STARTING org.kompiro.osgi.hello
REGISTER org.kompiro.osgi.hello.ExampleService
ss

Framework is launched.

id	State       Bundle
0	ACTIVE      org.eclipse.osgi_3.5.1.R35x_v20090827
1	ACTIVE      kompiro.hello-pax.hello_1.0.0.SNAPSHOT

osgi> exit
 -> Platform has been shutdown.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 28 seconds
[INFO] Finished at: Sat Jan 09 17:38:41 JST 2010
[INFO] Final Memory: 9M/18M
[INFO] ------------------------------------------------------------------------

おー。簡単にコンテナを切り替えられる。さすがPax Runner。ついでにKnopflerfish

$ pax-provision -f kf
...中略
Knopflerfish OSGi framework, version 4.1.10
Copyright 2003-2009 Knopflerfish. All Rights Reserved.

See http://www.knopflerfish.org for more information.
Loading xargs url file:knopflerfish/config.ini
Installed and started: file:bundles/org.knopflerfish.log-API_2.0.1.jar (id#1)
Installed and started: file:bundles/org.knopflerfish.bundle.cm-API_2.0.1.jar (id#2)
Installed and started: file:bundles/org.knopflerfish.bundle.console_2.0.1.jar (id#3)
Installed and started: file:bundles/org.knopflerfish.bundle.consoletty-IMPL_2.0.1.jar (id#4)
Installed and started: file:bundles/org.knopflerfish.bundle.frameworkcommands-IMPL_2.0.5.jar (id#5)
Installed and started: file:bundles/kompiro.hello-pax.hello_1.0.0.SNAPSHOT.jar (id#6)
> STARTING org.kompiro.osgi.hello
REGISTER org.kompiro.osgi.hello.ExampleService
Framework launched
help
Available command groups (type 'enter' to enter a group):
session - Session commands built into the console
framework - Framework commands
> 
> session
Available session commands:
  alias [<alias>] [<val>] ...  - Set or show aliases
  echo [-n] ...                - Echo command arguments
  enter <command group>        - Enter command group mode
  help [<command group> | all] - Help about specific command group or all command groups
  leave                        - Leave command group mode
  prompt <command prompt>      - Set command prompt
  quit                         - Exit this session
  save [<file>]                - Save current aliases as a property file
  restore [<file>]             - Restore aliases from a property file or from default aliases
  source <URL>                 - Source commands at URL
  unalias <alias name>         - Remove an alias

ヘルプの見方が・・・。つらい。

> help all
Available command groups (type 'enter' to enter a group):
session - Session commands built into the console
framework - Framework commands
> help session
Available session commands:
  alias [<alias>] [<val>] ...  - Set or show aliases
  echo [-n] ...                - Echo command arguments
  enter <command group>        - Enter command group mode
  help [<command group> | all] - Help about specific command group or all command groups
  leave                        - Leave command group mode
  prompt <command prompt>      - Set command prompt
  quit                         - Exit this session
  save [<file>]                - Save current aliases as a property file
  restore [<file>]             - Restore aliases from a property file or from default aliases
  source <URL>                 - Source commands at URL
  unalias <alias name>         - Remove an alias

なるほど。ヘルプがsessionとframeworkでグループ化されてるようなイメージかな。じゃ、frameworkのヘルプを見てみたらできるか?

> help framework
Available framework commands:
  addpermission [-help] -b #bundle# | -d | -l #location# <type> [<name> [<actions>]] - Add permissions to bundle
  bundles [-help] [-1] [-i] [-l] [-s] [-t] [<bundle>] ... - List bundles
  call [-help] [-f #filter#] <interface> <method> [<args>] ... - Call a method with zero or more java.lang.String
  closure [-help] <bundle> - Display the closure for a bundle
  deletepermission [-help] [-r] -b #bundle# | -d | -l #location# <type> <name> <actions> - Delete permissions from a bundle
  findbundles [-help] <symbolic name> - Find bundles with a given symbolic name
  headers [-help] [-i] [-l #locale#] <bundle> ... - Show bundle header values
  install [-help] [-s] <location> ... - Install one or more bundles
  package [-help] [-l] -b | -p [<selection>] ... - Show java package information
  permissions [-help] [-d] [<selection>] ... - Show permission information
  refresh [-help] [<bundle>] ... - Refresh all exported java packages belong to specified bundle
  resolve [-help] [<bundle>] ... - Resolve one or more bundles
  services [-help] [-i] [-l] [-f #filter#] [-r] [-u] [<bundle>] ... - List registered services
  start [-help] <bundle> ... - Start one or more bundles
  stop [-help] <bundle> ... - Stop one or more bundles
  showstate [-help] [<pid>] ... - Show the state of a service, if the service provides state information
  shutdown [-help] [<exit code>] - Shutdown framework
  uninstall [-help] <bundle> ... - Uninstall one or more bundles
  update [-help] <bundle> ... - Update one or more bundles
  fromupdate [-help] <bundle> <url> - Update a bundle from a specific URL
  frominstall [-help] <url> [<location>] - Install a bundle with a specific location from an URL
  startlevel [-help] [<level>] - Shows or sets the global startlevel
  cd [-help] [-reset] [<prefix>] ... - Shows or sets URL prefix
  bundlelevel [-help] <level> [<bundle>] ... - Set startlevel(s) for bundles

bundlesっぽい。

> bundles
   id  level/state name
   --------------------
    3  1/active    Console                  5  1/active    FW-Commands-IMPL
    1  1/active    LogService-API           0  0/active    System Bundle
    4  1/active    TTY-Console-IMPL         2  1/active    cm-API
    6  5/active    kompiro.hello-pax.hello [org.kompiro.osgi.hello]

でけた。なんか、くせある感じ。終了しよう。

> shutdown
> STOPPING org.kompiro.osgi.hello

 -> Platform has been shutdown.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 minutes 17 seconds
[INFO] Finished at: Sat Jan 09 17:44:14 JST 2010
[INFO] Final Memory: 9M/17M
[INFO] ------------------------------------------------------------------------

Bundleをいくつか作ってみよう。

よっしゃ、もしかしてBundleと言ってもEclipse Pluginと異なり、一つのプロジェクトで複数のBundleいけるのか?もやってみた。

$ pax-create-bundle -n test

ん?・・・よくよくみたら、hello-paxの下にプロジェクトができておる!どちらかというと、さっき作ったプロジェクトはワークスペースに近い性質っぽい。じゃ、testするにはどうしたらいいんだろう。とりあえず作成したtest bundleは削除しておこう。

$ pax-remove-bundle -n org.kompiro.hello-pax.test
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building kompiro.hello-pax (OSGi project)
[INFO]    task-segment: [org.ops4j:maven-pax-plugin:1.4:remove-bundle] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [pax:remove-bundle]
[INFO] Removing kompiro.hello-pax:test:bundle:1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10 seconds
[INFO] Finished at: Sat Jan 09 18:19:14 JST 2010
[INFO] Final Memory: 8M/17M
[INFO] ------------------------------------------------------------------------

testはPax Examでやるのね。ちょい小休止。

*1Eclipseプラグイン開発環境のJUnit Plug-in Testとは意味が異なります。JUnit Plug-in TestはあくまでEclipse環境上で動かすプラグインのテストを行うための環境が提供されます。なので、起動時にEclipseのproductかapplicationを指定する必要がありますが、Pax ExamはOSGiコンテナを切り替えたテストも行えます。開発しているBundleが他のOSGiコンテナで実行できるか、検証するための環境でした。

*2:なんも知らないとビビりますが、元々JARはそういうもんです。JARに署名をつけられるのは、署名をつけた人が作ったものである事を保証するためですよね。