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

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

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

便利ですね。

まずは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>

  <!--
   | imported (non-local) bundles are listed here as dependencies
   | and will be deployed by pax:provision unless they are marked
   | with <optional>true</optional>
  -->

</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>
... 中略 ...
  <!--
   | imported (non-local) bundles are listed here as dependencies
   | and will be deployed by pax:provision unless they are marked
   | with <optional>true</optional>
  -->

  <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ポートでサーバが立ち上がってるらしい。つないでみると・・・

動いてないじゃん。一回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シリーズにありますが、これは後日紹介します。