OSGi サービスをテストする – Bundleの初歩的な実装法を感覚的に理解するために(2/3)


この記事は、「OSGi サービスを利用する Karaf コマンドを実装する – Bundleの初歩的な実装法を感覚的に理解するために(1/3)」の続編です。

この記事では、「OSGi サービスを利用する Karaf コマンドを実装する – Bundle の初歩的な実装法を感覚的に理解するために(1/3)」で作成した、ソースプログラムを元に、Pax Exam を使って OSGi のサービスをテストする方法を紹介します。

インターフェースだけを入れた Bundle プロジェクトを作成する

親プロジェクトの下に、インターフェースだけを入れた Bundle プロジェクトを作成しましょう。
ArtifactId は、”com.wingnest.bundles.sample.hello.service_spec”とします。

以下に示す mvn コマンドを端末から実行して作成します。

$ pwd
/home/gougi/デスクトップ/Karaf/com.wingnest.bundles.sample.hello
$ mvn archetype:generate \
    -DarchetypeGroupId=org.apache.karaf.archetypes \
    -DarchetypeArtifactId=karaf-bundle-archetype \
    -DarchetypeVersion=3.0.3 \
    -DgroupId=com.wingnest.bundles.sample.hello \
    -DartifactId=com.wingnest.bundles.sample.hello.service_spec \
    -Dversion=1.0-SNAPSHOT \
    -Dpackage=com.wingnest.bundles.sample.hello.service_spec
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] com.wingnest.bundles.sample.hello
[INFO] com.wingnest.bundles.sample.hello.service Bundle
[INFO] Apache Karaf :: Shell mycommand/hello Commands
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building com.wingnest.bundles.sample.hello 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ com.wingnest.bundles.sample.hello >>>
[INFO] 
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ com.wingnest.bundles.sample.hello <<<
[INFO] 
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ com.wingnest.bundles.sample.hello ---
[INFO] Generating project in Interactive mode
[INFO] Archetype repository missing. Using the one from [org.apache.karaf.archetypes:karaf-bundle-archetype:3.0.3] found in catalog remote
[INFO] Using property: groupId = com.wingnest.bundles.sample.hello
[INFO] Using property: artifactId = com.wingnest.bundles.sample.hello.service_spec
[INFO] Using property: version = 1.0-SNAPSHOT
[INFO] Using property: package = com.wingnest.bundles.sample.hello.service_spec
Confirm properties configuration:
groupId: com.wingnest.bundles.sample.hello
artifactId: com.wingnest.bundles.sample.hello.service_spec
version: 1.0-SNAPSHOT
package: com.wingnest.bundles.sample.hello.service_spec
 Y: : 
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: karaf-bundle-archetype:3.0.3
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.wingnest.bundles.sample.hello
[INFO] Parameter: artifactId, Value: com.wingnest.bundles.sample.hello.service_spec
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.wingnest.bundles.sample.hello.service_spaec
[INFO] Parameter: packageInPathFormat, Value: com/wingnest/bundles/sample/hello/service_spec
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.wingnest.bundles.sample.hello.service_spec
[INFO] Parameter: groupId, Value: com.wingnest.bundles.sample.hello
[INFO] Parameter: artifactId, Value: com.wingnest.bundles.sample.hello.service_spec
[INFO] project created from Archetype in dir: /home/gougi/デスクトップ/Karaf/com.wingnest.bundles.sample.hello/com.wingnest.bundles.sample.hello.service_spec
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] com.wingnest.bundles.sample.hello ................. SUCCESS [5.884s]
[INFO] com.wingnest.bundles.sample.hello.service Bundle .. SKIPPED
[INFO] Apache Karaf :: Shell mycommand/hello Commands .... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.376s
[INFO] Finished at: Mon Feb 09 14:41:30 JST 2015
[INFO] Final Memory: 15M/245M
[INFO] ------------------------------------------------------------------------
$ ls
com.wingnest.bundles.sample.hello.command
com.wingnest.bundles.sample.hello.service
com.wingnest.bundles.sample.hello.service_spec
pom.xml
$ 

既存のサービス用 Bundle プロジェクトの中にある src/main/java/com/wingnest/bundles/sample/hello/service/Hello.java を 今作成したインターフェース用の Bundle プロジェクトの src/main/java/com/wingnest/bundles/sample/hello/service_spec に移動します。

$ cd com.wingnest.bundles.sample.hello.service_spec
$ mv ../com.wingnest.bundles.sample.hello.service/src/main/java/com/wingnest/bundles/sample/hello/service/Hello.java \
     src/main/java/com/wingnest/bundles/sample/hello/service_spec/Hello.java
$

異なるパッケージに移動したので、package 宣言の値をエディタで修正しておきます。

src/main/java/com/wingnest/bundles/sample/hello/service_spec/Hello.java:
---
package com.wingnest.bundles.sample.hello.service_spec;

public interface Hello {

    String hello();

}

では、サービスのインターフェースだけを入れた Bundle を Maven のローカルリポジトリにインストールし、さらに Karaf にインストールしてみましょう。

まずは、mvn install を実行して、Maven のローカルリポジトリにサービスのインターフェースだけを入れた Bundle をインストールします。

$ pwd
/home/gougi/デスクトップ/Karaf/com.wingnest.bundles.sample.hello/com.wingnest.bundles.sample.hello.service_spec
$ mvn install
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building com.wingnest.bundles.sample.hello.service_spec Bundle 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
(省略)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.194s
[INFO] Finished at: Mon Feb 09 15:09:55 JST 2015
[INFO] Final Memory: 15M/355M
[INFO] ------------------------------------------------------------------------
$

無事、インストールできました。

では、次に、Karaf コンソールから Karaf にインストールしてみましょう。

karaf@root()> install -s mvn:com.wingnest.bundles.sample.hello/com.wingnest.bundles.sample.hello.service_spec/1.0-SNAPSHOT
Bundle ID: 66
karaf@root()> list
START LEVEL 100 , List Threshold: 50
ID | State  | Lvl | Version        | Name                                                 
------------------------------------------------------------------------------------------
64 | Active |  80 | 1.0.0.SNAPSHOT | com.wingnest.bundles.sample.hello.service Bundle     
65 | Active |  80 | 1.0.0.SNAPSHOT | Apache Karaf :: Shell mycommand/hello Commands       
66 | Active |  80 | 1.0.0.SNAPSHOT | com.wingnest.bundles.sample.hello.service_spec Bundle
karaf@root()> 

うまくインストールできました。

では、コマンドとサービスの両方をこのインターフェースだけを入れた Bundle を利用するように修正し、いつもの手順で更新しましょう。

まず、サービスの pom.xml の dependencies 要素の下に、サービスのインターフェースだけを入れた Bundle を利用するために、その dependency 要素を追記します。

(省略)
    <dependencies>    
        <dependency>
            <groupId>com.wingnest.bundles.sample.hello</groupId>
            <artifactId>com.wingnest.bundles.sample.hello.service_spec</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
(省略)

次に、コマンド用 Bundle の pom.xml の dependencies 要素の下にある、次の記述を書き換えます。

次のようになっている記述を:

(省略)
    <dependencies>
        <dependency>
            <groupId>com.wingnest.bundles.sample.hello</groupId>
            <artifactId>com.wingnest.bundles.sample.hello.service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
(省略)

(サービスの pom.xml と同様に)次のように書き換えます:

(省略)
    <dependencies>    
        <dependency>
            <groupId>com.wingnest.bundles.sample.hello</groupId>
            <artifactId>com.wingnest.bundles.sample.hello.service_spec</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
(省略)

では、親プロジェクトの中で、 mvn install を実行し、子プロジェクトが生成するすべての Bundle を Mavenのローカルリポジトリに一度にインストールしてしまいましょう。

$ pwd
/home/gougi/デスクトップ/Karaf/com.wingnest.bundles.sample.hello
$ mvn install
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] com.wingnest.bundles.sample.hello
[INFO] com.wingnest.bundles.sample.hello.service_spec Bundle
[INFO] com.wingnest.bundles.sample.hello.service Bundle
[INFO] Apache Karaf :: Shell mycommand/hello Commands
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building com.wingnest.bundles.sample.hello 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-install-plugin:2.3:install (default-install) @ com.wingnest.bundles.sample.hello ---
[INFO] Installing /home/gougi/デスクトップ/Karaf/com.wingnest.bundles.sample.hello/pom.xml to /home/gougi/.m2/repository/com/wingnest/bundles/com.wingnest.bundles.sample.hello/1.0-SNAPSHOT/com.wingnest.bundles.sample.hello-1.0-SNAPSHOT.pom
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building com.wingnest.bundles.sample.hello.service_spec Bundle 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
(省略)
[INFO] ------------------------------------------------------------------------
[INFO] Building com.wingnest.bundles.sample.hello.service Bundle 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
(省略) 
[INFO] ------------------------------------------------------------------------
[INFO] Building Apache Karaf :: Shell mycommand/hello Commands 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
(省略) 
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] com.wingnest.bundles.sample.hello ................. SUCCESS [0.079s]
[INFO] com.wingnest.bundles.sample.hello.service_spec Bundle  SUCCESS [0.801s]
[INFO] com.wingnest.bundles.sample.hello.service Bundle .. SUCCESS [0.508s]
[INFO] Apache Karaf :: Shell mycommand/hello Commands .... SUCCESS [0.290s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.048s
[INFO] Finished at: Mon Feb 09 16:41:33 JST 2015
[INFO] Final Memory: 23M/324M
[INFO] ------------------------------------------------------------------------
$ 

無事に、すべての Bundle を Maven のローカルリポジトリにインストールできました。

では、サービスとコマンド用の Bundle を Karaf にインストールしましょう。実際は、すでにインストールされているので、install コマンドではなく、update コマンドで行います。

karaf@root()> list
START LEVEL 100 , List Threshold: 50
ID | State  | Lvl | Version        | Name                                                 
------------------------------------------------------------------------------------------
64 | Active |  80 | 1.0.0.SNAPSHOT | com.wingnest.bundles.sample.hello.service Bundle     
65 | Active |  80 | 1.0.0.SNAPSHOT | Apache Karaf :: Shell mycommand/hello Commands       
66 | Active |  80 | 1.0.0.SNAPSHOT | com.wingnest.bundles.sample.hello.service_spec Bundle
karaf@root()> update 64
Stopping the bundle!!!
Starting the bundle!!!
karaf@root()> update 65
karaf@root()> 
</code></pre>

mycommand:hello コマンドを実行してみます。

<pre><code>karaf@root()> mycommand:hello 
hello
karaf@root()> 

ちゃんと、”hello” と出力されたでしょうか。

PAX Exam4 を使ってサービスのテストを書く

Pax Exam は、任意の Bundle に対するテストケースを記述可能にするテストフレームワークです。
このフレームワークを使うことで、Bundle のテストケースを Apache FelixEclipse Equinoxなどの OSGi フレームワークを使う OSGi テストコンテナ、または、 Karaf を使うKaraf テストコンテナの上など1)https://ops4j1.jira.com/wiki/display/PAXEXAM4/Test+Containersで実行できます。

今回作成したサービスのテストは、OSGi テストコンテナと Karaf テストコンテナのどちらでも記述できますが、この記事では、OSGi テストコンテナの上にテストケースを記述します。OSGi フレームワークとしては、Apache Felix を利用します。

Pax Exam4 を利用するために必要な Maven Dependency

Pax Exam を利用するのに必要な Maven Dependency は、OSGi Containersという記事に書かれています。…と言いたいところですが、そこに記述されている内容は、Pax Exam3 用のままになっているようです。
そのため、これを参考に、以下のようにサービスの 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/xsd/maven-4.0.0.xsd">

    <!-- Licensed to the Apache Software Foundation (ASF) under one or more 
        contributor license agreements. See the NOTICE file distributed with this 
        work for additional information regarding copyright ownership. The ASF licenses 
        this file to you under the Apache License, Version 2.0 (the "License"); you 
        may not use this file except in compliance with the License. You may obtain 
        a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless 
        required by applicable law or agreed to in writing, software distributed 
        under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
        OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
        the specific language governing permissions and limitations under the License. -->

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>com.wingnest.bundles.sample.hello</artifactId>
        <groupId>com.wingnest.bundles</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.wingnest.bundles.sample.hello</groupId>
    <artifactId>com.wingnest.bundles.sample.hello.service</artifactId>
    <packaging>bundle</packaging>

    <name>com.wingnest.bundles.sample.hello.service Bundle</name>
    <description>com.wingnest.bundles.sample.hello.service OSGi bundle project.</description>

    <properties>
        <maven-bundle-plugin.version>2.5.3</maven-bundle-plugin.version>
        <osgi.version>5.0.0</osgi.version>
        <!-- for testing -->
        <pax-exam.version>4.4.0</pax-exam.version>
        <pax-url.version>2.3.0</pax-url.version>
        <felix.version>4.6.0</felix.version>
        <junit.version>4.11</junit.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.10</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.0.9</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam</artifactId>
            <version>${pax-exam.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-spi</artifactId>
            <version>${pax-exam.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-container-native</artifactId>
            <version>${pax-exam.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-junit4</artifactId>
            <version>${pax-exam.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-link-mvn</artifactId>
            <version>${pax-exam.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.ops4j.pax.url</groupId>
            <artifactId>pax-url-aether</artifactId>
            <version>${pax-url.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.apache.felix.framework</artifactId>
            <version>${felix.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.wingnest.bundles.sample.hello</groupId>
            <artifactId>com.wingnest.bundles.sample.hello.service_spec</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>${osgi.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.compendium</artifactId>
            <version>${osgi.version}</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>${maven-bundle-plugin.version}</version>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-Version>${project.version}</Bundle-Version>
                        <Bundle-Activator>com.wingnest.bundles.sample.hello.service.Activator</Bundle-Activator>
                        <Export-Package>com.wingnest.bundles.sample.hello.service*;version=${project.version}</Export-Package>
                        <Import-Package>*</Import-Package>
                    </instructions>
                </configuration>
            </plugin>

            <!-- Needed if you use versionAsInProject() -->
            <plugin>
                <groupId>org.apache.servicemix.tooling</groupId>
                <artifactId>depends-maven-plugin</artifactId>
                <version>1.2</version>
                <executions>
                    <execution>
                        <id>generate-depends-file</id>
                        <goals>
                            <goal>generate-depends-file</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

</project>

次にテストケースを書きます。

テストケースは、以下の内容にします:

  • BundleContex と Hello サービス は、テスト実行前に、 @Inject により、インジェクトしてもらう
  • テストの中では、BundleContex と Hello サービスが、インジェクトされているか確認する
  • Hello サービスの #hello() メソッドを呼び出し文字列 “hello” が取得できるか確認する。

では、次のクラスを src/test/java の下に作成してください。

/src/test/java/com/wingnest/bundles/sample/hello/service/TestOsgiServices.java
---
package com.wingnest.bundles.sample.hello.service;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.ops4j.pax.exam.CoreOptions.junitBundles;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.streamBundle;
import static org.ops4j.pax.tinybundles.core.TinyBundles.bundle;

import javax.inject.Inject;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerClass;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;

import com.wingnest.bundles.sample.hello.service_spec.Hello;

@ExamReactorStrategy(PerClass.class)
@RunWith(PaxExam.class)
public class TestOsgiServices {

  @Inject
  protected BundleContext bundleContext;

  @Inject
  protected Hello hello;

  @Inject
  protected Hello hello;

    @Configuration
    public Option[] config() {
        return new Option[] {

                mavenBundle()
                        .groupId("com.wingnest.bundles.sample.hello")
                        .artifactId(
                                "com.wingnest.bundles.sample.hello.service_spec")
                        .versionAsInProject(),

                streamBundle(bundle()
                        .set(Constants.BUNDLE_SYMBOLICNAME, "com.wingnest.bundles.sample.hello.service")    // この設定は必須ではない
                        .add(com.wingnest.bundles.sample.hello.service.Activator.HelloImpl.class) // 2)私のWindows環境では、下のadd()と順番を入れ替えるとActivatorクラスが見つけられないという例外になった。摩訶不思議。
                        .add(com.wingnest.bundles.sample.hello.service.Activator.class)
                        .set(Constants.BUNDLE_ACTIVATOR, com.wingnest.bundles.sample.hello.service.Activator.class.getName())
                        .set(Constants.IMPORT_PACKAGE, "org.osgi.framework, com.wingnest.bundles.sample.hello.service_spec")
                        .build()),

                junitBundles()

        };
    }

  @Test
  public void test() throws InterruptedException {
    assertNotNull(bundleContext);
    assertNotNull(hello);
    assertEquals("hello", hello.hello());
  }

}

@Configurationでアノテーションした config()メソッドでは、Felix を起動するための構成情報を記述しています。
Hello インターフェースだけを持った Bundle をリポジトリから取得して利用すること、そして Helloサービスの実装を記述したサービス Bundle をテストのために動的に生成して利用することを記述しています。

後者の streamBundle() の中で行っている設定は、pom.xml での maven-bundle-plugin プラグインの設定方法とほぼ同じです。

テストを実行してみる

では、記述したテストを実行してみましょう。

$ mvn test
[INFO] Scanning for projects...
[INFO] 
[INFO] Using the builder org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder with a thread count of 1
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building com.wingnest.bundles.sample.hello.service Bundle 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
(省略)
10:45:27.966 [main] INFO  o.o.p.e.spi.reactors.ReactorManager - suite finished
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.542 sec - in com.wingnest.bundles.sample.hello.service.TestOsgiServices

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.201 s
[INFO] Finished at: 2015-02-15T10:45:27+09:00
[INFO] Final Memory: 18M/257M
[INFO] ------------------------------------------------------------------------

スルッと通ったでしょうか。

あとがき

Pax Exam を使っていて悩ましいく感じているのが、設定がうまくできていない時に出るエラーや例外では、それを受けてどのように対処すれば良いかが、まったく想像ができないケースが多いということです。簡単には埋めることが難しいギャップがあるでしょうね。

後、Karaf コマンドのテスト方法について書きたいと思っています。しかし、Pax Exam にそのテストに関わる不具合があることがわかっているので、それが解決されてからにしようかどうしようかと、迷っています。

では、この記事はこの辺で。

Footnotes   [ + ]

1. https://ops4j1.jira.com/wiki/display/PAXEXAM4/Test+Containers
2. 私のWindows環境では、下のadd()と順番を入れ替えるとActivatorクラスが見つけられないという例外になった。摩訶不思議。