NetBeans IDEでのCDIを使用したOSGiバンドルのサービスとしての注入

This tutorial needs a review. You can open a JIRA issue, or edit it in GitHub following these contribution guidelines.

このドキュメントでは、NetBeans IDEでのOpen Services Gateway Initiative (OSGi)フレームワークの統合サポートによって、OSGiバンドルを作成するプロセスおよびプロジェクトでそのバンドルを使用するプロセスがどのように簡素化されているかについて説明します。このチュートリアルでは、Maven OSGiバンドル原型から2つの単純なOSGiバンドルを作成し、次にそれらのバンドルをGlassFish Server Open Source Edition 3.1にデプロイします。

基本的なOSGiバンドルの作成後、Webクライアント・アプリケーションを作成し、CDIを使用してそれらのバンドルをサービスとして注入します。次に、Webアプリケーションをバンドルとしてサーバーにデプロイします。このチュートリアルでは、次にOSGi管理コンソールを使用してOSGiバンドルを操作する方法について説明します。

エンタープライズ・アプリケーションでOSGiバンドルを使用すると、個別のバンドルを更新する際のモジュール性および柔軟性を高めることができます。GlassFishサーバーがデフォルトでOSGiをサポートすることによって、アプリケーションにバンドルを組み込む作業は非常に簡単になります。

このチュートリアルは、Arun Gupta氏のブログで見ることができるブログ投稿TOTD#154: Dynamic OSGi services in GlassFish 3.1 - Using CDI and@OSGiServiceおよびその他のブログ・エントリに基づいています。OSGiの操作に関するその他の役立つ情報については、このブログを参照してください。

また、次のリソースには、ハイブリッド・アプリケーションでのOSGiとCDIの使用に関する情報が豊富に含まれています。

チュートリアルの課題

このチュートリアルに従うには、次のソフトウェアとリソースが必要です。

ソフトウェアまたはリソース 必須バージョン

NetBeans IDE

7.2、7.3、7.4、8.0、Java EEバージョン

Java Development Kit (JDK)

バージョン7または8

GlassFish Server Open Source Edition

3.1.xまたは4.x

前提条件

このドキュメントは、次のテクノロジについて基本的な知識またはプログラミング経験を持つ読者を想定して書かれています。

  • Javaプログラミング

  • NetBeans IDE

  • Mavenフレームワーク

このチュートリアルを開始する前に、必要に応じて次のドキュメントをお読みください。

親POMプロジェクトの作成

この項では、このチュートリアルで作成するOSGiバンドル用の親POMプロジェクトを作成します。プロジェクトのPOM ( pom.xml )を編集して、子プロジェクトによって依存性として継承される依存性管理要素を追加します。

  1. メイン・メニューから「新規プロジェクト」([Ctrl]-[Shift]-[N]、Macの場合は[⌘]-[Shift]-[N])を選択します。

  2. 「Maven」カテゴリから「POMプロジェクト」を選択します。

cdi newpomproject
Figure 1. 新規プロジェクト・ウィザードのMaven POMプロジェクト原型
  1. 「プロジェクト名」に「MavenOSGiCDIProject」と入力します。「終了」をクリックします。

「終了」をクリックすると、IDEがPOMプロジェクトを作成し、そのプロジェクトが「プロジェクト」ウィンドウで開きます。

  1. 「プロジェクト」ウィンドウで「プロジェクト・ファイル」ノードを展開して「 pom.xml 」をダブルクリックし、エディタでそのファイルを開きます。

プロジェクトの基本的なPOMは、次のようになっているはずです。

<?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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany</groupId>
    <artifactId>MavenOSGiCDIProject</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>
  1. 親の 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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany</groupId>
    <artifactId>MavenOSGiCDIProject</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    *<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.osgi</groupId>
                <artifactId>org.osgi.core</artifactId>
                <version>4.2.0</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>*
</project>

この課題では、プロジェクトで使用するアーティファクトとアーティファクト・バージョンを明示的に指定しました。依存性管理を使用し、親POMにアーティファクトを指定することで、子プロジェクト内のPOMがより単純化され、プロジェクト内で依存性のバージョンの一貫性を確保できます。

依存性管理の使用の詳細は、依存性メカニズム入門を参照してください。

OSGiバンドル・プロジェクトの作成

新規プロジェクト・ウィザードの「Maven」カテゴリには、OSGiバンドル・プロジェクトを作成するためのOSGiバンドルの原型が用意されています。OSGiバンドル・プロジェクトを作成すると、生成されたPOMは、 org.osgi.core JARを依存性として宣言し、プロジェクト・ビルド用に maven-bundle-plugin を指定します。

MavenHelloServiceApiインタフェース・バンドルの作成

この課題では、新規プロジェクト・ウィザードを使用して、他のバンドルによって実装される単純なインタフェースを提供するOSGiバンドル・プロジェクトを作成します。バンドルとインタフェースを作成したら、POMを変更して、親POMプロジェクトで指定した org.osgi.core アーティファクトに対する依存性を更新します。

  1. 「ファイル」>「新規プロジェクト」を選択し、新規プロジェクト・ウィザードを開きます。

  2. 「Maven」カテゴリから「OSGiバンドル」を選択します。「次」をクリックします。

cdi new osgiproject
Figure 2. 新規プロジェクト・ウィザードのMaven OSGiバンドル原型
  1. 「プロジェクト名」に「MavenHelloServiceApi」と入力します。

  2. 「参照」をクリックし、「場所」として「MavenOSGiCDIProject」POMプロジェクトを選択します。「終了」をクリックします。

「終了」をクリックすると、IDEがバンドル・プロジェクトを作成し、そのプロジェクトが「プロジェクト」ウィンドウで開きます。エディタでMavenHelloServiceApiプロジェクトの pom.xml を開くと、 packaging 要素に bundle が指定されていること、およびバンドルのビルド時に maven-bundle-plugin が使用されることがわかります。

<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <artifactId>MavenOSGiCDIProject</artifactId>
    <groupId>com.mycompany</groupId>
    <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.mycompany</groupId>
    <artifactId>MavenHelloServiceApi</artifactId>
    <version>1.0-SNAPSHOT</version>
    *<packaging>bundle</packaging>*
    <name>MavenHelloServiceApi OSGi Bundle</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>4.3.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                *<artifactId>maven-bundle-plugin</artifactId>*
                <version>2.3.7</version>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-Activator>com.mycompany.mavenhelloserviceimpl.Activator</Bundle-Activator>
                        <Export-Package />
                    </instructions>
                </configuration>
            </plugin>

            ...
        </plugins>
    </build>

    ...
<project>

また、Maven OSGiバンドル原型を使用してOSGiバンドル・プロジェクトを作成したときに、IDEによって org.osgi.core アーティファクトがデフォルトで依存性として追加されたこともわかります。

  1. 「プロジェクト」ウィンドウでMavenHelloServiceApiプロジェクト・ノードを右クリックし、「プロパティ」を選択します。

  2. 「プロジェクト・プロパティ」ダイアログ・ボックスで「ソース」カテゴリを選択します。

  3. ソース/バイナリ形式」を1.6に設定し、「エンコーディング」がUTF-8であることを確認します。「OK」をクリックします。

  4. 「プロジェクト」ウィンドウで「ソース・パッケージ」ノードを右クリックし、「新規」>「Javaインタフェース」を選択します。

  5. 「クラス名」に「Hello」と入力します。

  6. 「パッケージ」として「com.mycompany.mavenhelloserviceapi」を選択します。「終了」をクリックします。

  7. インタフェースに次の sayHello メソッド(太字部分)を追加し、変更内容を保存します。

public interface Hello {
    *String sayHello(String name);*
}
  1. 「プロジェクト」ウィンドウでプロジェクトのノードを右クリックし、「ビルド」を選択します。

プロジェクトをビルドした後、「ファイル」ウィンドウを開いてプロジェクト・ノードを展開すると、 target フォルダに MavenHelloServiceApi-1.0-SNAPSHOT.jar が作成されていることがわかります。

cdi manifest
Figure 3. 「ファイル」ウィンドウにコンパイルされたJARの内容が表示される

プロジェクトをビルドすると、 maven-bundle-pluginMANIFEST.MF ファイルの生成を処理します。コンパイルされたJARの MANIFEST.MF ファイルを開くと、プラグインによって、エクスポート・パッケージを宣言するマニフェスト・ヘッダーが生成されたことがわかります。OSGiでは、公開して他のバンドルで使用できるようにするすべてのバンドルを MANIFEST.MFExport-Package 要素内に列挙する必要があります。

  1. MANIFEST.MFExport-Package 要素(次の例で*太字*で示された要素)が含まれていることを確認します。

Manifest-Version: 1.0
Bnd-LastModified: 1395049732676
Build-Jdk: 1.7.0_45
Built-By: nb
Bundle-Activator: com.mycompany.mavenhelloserviceapi.Activator
Bundle-ManifestVersion: 2
Bundle-Name: MavenHelloServiceApi OSGi Bundle
Bundle-SymbolicName: com.mycompany.MavenHelloServiceApi
Bundle-Version: 1.0.0.SNAPSHOT
Created-By: Apache Maven Bundle Plugin
*Export-Package: com.mycompany.mavenhelloserviceapi;uses:="org.osgi.frame
 work";version="1.0.0.SNAPSHOT"*
Import-Package: org.osgi.framework;version="[1.6,2)"
Tool: Bnd-1.50.0

OSGiコンテナは Export-Package マニフェスト・ヘッダーを読み取り、バンドル外からアクセスできる、バンドル内のクラスを判断します。この例では、 com.mycompany.mavenhelloserviceapi パッケージ内のクラスが公開されています。

MANIFEST.MFExport-Package 要素が含まれていない場合、「プロジェクト・プロパティ」ウィンドウでプラグインのデフォルト・プラグイン動作を有効にし、プロジェクトを再ビルドする必要があります。「プロジェクト・プロパティ」ウィンドウで「パッケージをエクスポート」カテゴリを選択し、*デフォルトmaven-bundle-plugin動作*オプションを選択します。「プロジェクト・プロパティ」ウィンドウの「パッケージをエクスポート」パネルを使用して、公開するパッケージを明示的に指定するか、 pom.xml に直接パッケージを指定します。

MavenHelloServiceImpl実装バンドルの作成

この課題では、POMプロジェクト内にMavenHelloServiceImplを作成します。

  1. 「ファイル」>「新規プロジェクト」を選択し、新規プロジェクト・ウィザードを開きます。

  2. 「Maven」カテゴリから「OSGiバンドル」を選択します。「次」をクリックします。

  3. 「プロジェクト名」に「MavenHelloServiceImpl」と入力します。

  4. 「参照」をクリックし、「場所」として「MavenOSGiCDIProject」POMプロジェクトを選択します(選択されていない場合)。「終了」をクリックします。

  5. 「プロジェクト」ウィンドウでプロジェクトのノードを右クリックし、「プロパティ」を選択します。

  6. 「プロジェクト・プロパティ」ダイアログ・ボックスで「ソース」カテゴリを選択します。

  7. ソース/バイナリ形式」を1.6に設定し、「エンコーディング」がUTF-8であることを確認します。「OK」をクリックします。

  8. 「プロジェクト」ウィンドウで「ソース・パッケージ」ノードを右クリックし、「新規」>「Javaクラス」を選択します。

  9. 「クラス名」に「HelloImpl」と入力します。

  10. 「パッケージ」として「com.mycompany.mavenhelloserviceimpl」を選択します。「終了」をクリックします。

  11. 次(太字部分)を入力し、変更内容を保存します。

public class HelloImpl *implements Hello {

    public String sayHello(String name) {
        return "Hello " + name;*
    }
}
``Hello`` を実装すると、MavenHelloServiceApiプロジェクトを依存性として追加することによって解決する必要があるエラーがIDEに表示されます。
  1. 「プロジェクト」ウィンドウの*MavenHelloServiceImpl*の「依存性」ノードを右クリックし、「依存性の追加」を選択します。

  2. 「ライブラリの追加」ダイアログで、「開いているプロジェクト」タブをクリックします。

  3. 「MavenHelloServiceApi OSGiバンドル」を選択します。「追加」をクリックします。

cdi add dependency
Figure 4. 「ライブラリの追加」ダイアログの「開いているプロジェクト」タブ
  1. エディタで開いている HelloImpl.java クラス内を右クリックして「インポートを修正」([Alt]-[Shift]-[I]、Macの場合は[⌘]-[Shift]-[I])を選択し、 com.mycompany.mavenhelloserviceapi.Hello のインポート文を追加します。変更を保存します。

  2. com.mycompany.mavenhelloserviceimpl 」パッケージを展開し、「 Activator.java 」をダブルクリックしてこのファイルをエディタで開きます。

cdi activator
Figure 5. 「プロジェクト」ウィンドウのActivatorクラス

IDEによってプロジェクト内に Activator.java バンドル・アクティベータ・クラスが自動的に作成されます。バンドル・アクティベータは、バンドルのライフサイクルを管理するために使用されます。バンドル・アクティベータ・クラスは、バンドルの MANIFEST.MF で宣言され、バンドルがコンテナによって開始されるときにインスタンス化されます。

OSGiバンドルにはバンドル・アクティベータ・クラスは必要ありませんが、アクティベータ・クラスで start() メソッドを使用して、たとえば、バンドルが必要とするサービスまたはその他のリソースを初期化できます。この課題では、「出力」ウィンドウにメッセージを出力するクラスに、少量のコード行を追加します。これにより、バンドルが開始および停止するタイミングを簡単に識別できます。

  1. バンドル・アクティベータ・クラスの start() および stop() メソッドを変更して、次の行(太字部分)を追加します。

public class Activator implements BundleActivator {

    public void start(BundleContext context) throws Exception {
        *System.out.println("HelloActivator::start");
        context.registerService(Hello.class.getName(), new HelloImpl(), null);
        System.out.println("HelloActivator::registration of Hello service successful");*
    }

    public void stop(BundleContext context) throws Exception {
        *context.ungetService(context.getServiceReference(Hello.class.getName()));
        System.out.println("HelloActivator stopped");*
    }
}

バンドル・アクティベータ・クラスが org.osgi.framework.BundleActivator および org.osgi.framework.BundleContext をインポートしていることが確認できます。デフォルトでは、生成されたクラスには start() および stop() の2つのメソッドが含まれています。OSGiフレームワークは、 start() メソッドおよび stop() メソッドを呼び出して、バンドルの提供する機能を開始および停止します。バンドルが開始されると、そのバンドルの提供するサービス・コンポーネントが、OSGiサービス・レジストリに登録されます。あるバンドルが登録されると、他のバンドルは、そのレジストリを使用してアクティブなサービスを検索し、バンドル・コンテキストを経由してそのサービスを使用できます。

プロジェクトのPOMを見ると、 maven-bundle-plugin のconfiguration要素の下にバンドル・アクティベータを指定する <Bundle-Activator> 要素を確認できます。

<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <version>2.3.7</version>
    <extensions>true</extensions>
      <configuration>
            <instructions>
                  *<Bundle-Activator>com.mycompany.mavenhelloserviceimpl.Activator</Bundle-Activator>*
            </instructions>
      </configuration>
</plugin>

バンドルをビルドすると、プラグインは、マニフェスト・ヘッダーをJAR内にあるバンドルのマニフェスト・ファイルに生成し、バンドル・アクティベータ・クラスを指定します。バンドルがデプロイされると、OSGiランタイムがマニフェスト・ファイル内の Bundle-Activator ヘッダーを検索します。

  1. Activator.java のインポート文を修正して、 com.mycompany.mavenhelloserviceapi.Hello をインポートします。変更を保存します。

  2. 「依存性」ノードを展開し、 org.osgi.core アーティファクトが依存性として表示されたことを確認します。

「依存性」ノードに古いバージョンのアーティファクトがリストされている場合、アーティファクトを右クリックして「依存性を削除」を選択し、削除します。依存性は、MavenHelloServiceApiプロジェクトおよび org.osgi.core アーティファクトのみである必要があります。
cdi implproject
Figure 6. 「プロジェクト」ウィンドウのActivatorクラス

OSGiバンドルのビルドとデプロイ

この課題では、OSGiバンドルをビルドし、バンドルをGlassFishにデプロイします。

  1. 「プロジェクト」ウィンドウでMavenOSGiCDIProjectノードを右クリックし、「消去してビルド」を選択します。

プロジェクトをビルドすると、IDEによって各プロジェクトの target フォルダ内にJARファイルが作成され、ローカル・リポジトリにもスナップショットJARがインストールされます。「ファイル」ウィンドウで、2つのバンドル・プロジェクトの target フォルダをそれぞれ展開すると、2つのJARアーカイブ( MavenHelloServiceApi-1.0-SNAPSHOT.jar および MavenHelloServiceImpl-1.0-SNAPSHOT.jar )が表示されます。

  1. GlassFishサーバーを起動します(まだ起動していない場合)。

  2. MavenHelloServiceApi-1.0-SNAPSHOT.jar をGlassFishインストールの glassfish/domains/domain1/autodeploy/bundles/ ディレクトリにコピーします。

「出力」ウィンドウ内のGlassFishのサーバー・ログに、次のような出力が表示されるはずです。

INFO: Started bundle: file:/glassfish-4.0/glassfish/domains/domain1/autodeploy/bundles/MavenHelloServiceApi-1.0-SNAPSHOT.jar

「出力」ウィンドウにサーバー・ログが表示されない場合は、「サービス」ウィンドウのGlassFishサーバー・ノードを右クリックして、「ドメイン・サーバー・ログを表示」を選択します。

  1. これらの手順を繰り返して、 MavenHelloServiceImpl-1.0-SNAPSHOT.jarautodeploy/bundles ディレクトリにコピーします。

これで、GlassFishのサーバー・ログに次のような出力が表示されるはずです。

INFO: HelloActivator::start
INFO: HelloActivator::registration of Hello service successful
INFO: Started bundle: file:/glassfish-4.0/glassfish/domains/domain1/autodeploy/bundles/MavenHelloServiceImpl-1.0-SNAPSHOT.jar
INFO: Started bundle: file:/glassfish-4.0/glassfish/domains/domain1/autodeploy/bundles/MavenHelloServiceImpl-1.0-SNAPSHOT.jar

または、GlassFish OSGi管理コンソールからバンドルをインストールすることもできます。詳細は、OSGi管理コンソールのインストールと使用の項を参照してください。

Webクライアント・アプリケーションの作成

この項では、OSGiバンドルの提供するサービスにアクセスするJava EE Webクライアントの作成方法について説明します。単純なサーブレットをWebアプリケーションで作成し、宣言されたサービスを注入します。プロジェクトを作成する前に、親POMプロジェクトに依存性管理要素をいくつか追加します。

親POMプロジェクトでの依存性の構成

この課題では、親POMプロジェクトに依存性要素を指定します。また、プロジェクトによって使用されるアーティファクトのリポジトリも追加します。

  1. 「プロジェクト」ウィンドウで*MavenOSGiCDIProject*プロジェクトの「プロジェクト・ファイル」ノードを展開し、 pom.xml をダブルクリックしてエディタでこのファイルを開きます。

  2. 親の 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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany</groupId>
    <artifactId>MavenOSGiCDIProject</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    ...

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.osgi</groupId>
                <artifactId>org.osgi.core</artifactId>
                <version>4.3.0</version>
                <scope>provided</scope>
            </dependency>
            *<dependency>
                <groupId>org.osgi</groupId>
                <artifactId>org.osgi.compendium</artifactId>
                <version>4.2.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.glassfish</groupId>
                <artifactId>osgi-cdi-api</artifactId>
                <version>3.1-b41</version>
                <type>jar</type>
                <scope>provided</scope>
            </dependency>*

        </dependencies>
    </dependencyManagement>

    ...
</project>
  1. 次の要素を追加して、POMにGlassFishリポジトリを追加します。変更を保存します。

<project>

    ...

    </dependencyManagement>

    *<repositories>
        <!-- glassfish nexus repo for glassfish dependencies -->
        <repository>
            <id>glassfish-repo-archive</id>
            <name>Nexus repository collection for Glassfish</name>
            <url>http://maven.glassfish.org/content/groups/glassfish</url>
            <snapshots>
                <updatePolicy>never</updatePolicy>
            </snapshots>
        </repository>
    </repositories>*
    <modules>
        <module>MavenHelloServiceApi</module>
        <module>MavenHelloServiceImpl</module>
    </modules>
</project>

POMにGlassFishリポジトリを追加した後、「サービス」ウィンドウで「Mavenリポジトリ」ノードの下のリポジトリのリストを表示すると、IDEによってGlassFishリポジトリのノードが自動的に追加されたことがわかります。デフォルトでは、ローカルMavenリポジトリのノードがIDEに表示されます。開いているプロジェクトにリポジトリを指定すると、IDEによって「Mavenリポジトリ」ノードの下にリポジトリのノードが自動的に追加されます。

cdi maven repositories
Figure 7. 「Mavenリポジトリ」ウィンドウのGlassFishリポジトリ

この課題では、プロジェクトで使用される追加のアーティファクトとアーティファクト・バージョンを追加しました。また、 osgi-cdi-api アーティファクトを含むGlassFishリポジトリも追加しました。

MavenHelloWebClient Webアプリケーションの作成

最初に通常のWebアプリケーションを作成し、次にプロジェクトを変更してOSGiバンドル(Webアプリケーション・バンドル(WAB))にします。

  1. メイン・メニューから「ファイル」>「新規プロジェクト」を選択します。

  2. 「Maven」カテゴリから「Webアプリケーション」を選択します。「次」をクリックします。

  3. 「プロジェクト名」に「MavenHelloWebClient」と入力します。

  4. 「参照」をクリックし、「場所」として「MavenOSGiCDIProject」POMプロジェクトを指定します(まだ選択されていない場合)。「次」をクリックします。

  5. サーバーとして「GlassFish Server」を選択し、Java EEバージョンとして「Java EE 6 Web」または「Java EE 7 Web」を選択します。「終了」をクリックします。

  6. プロジェクト・ノードを右クリックし、「新規」>「サーブレット」を選択します。

  7. 「クラス名」に「HelloServlet」と入力します。

  8. パッケージとして com.mycompany.mavenhellowebclient を選択します。「終了」をクリックします。

  9. IDEによって生成されたサーブレット内のデフォルトのメソッド( processRequestdoGetdoPostgetServletInfo )を削除します。

HttpServletメソッドを削除するには、エディタの折りたたみを展開する必要があります。
  1. 次のコード(太字部分)を入力してサービスを注入します。

@WebServlet(name = "HelloServlet", urlPatterns = {"/HelloServlet"})
public class HelloServlet extends HttpServlet {

    *@Inject
    @OSGiService(dynamic=true)
    Hello hello;*
}
  1. 次の doGet メソッドを追加します。

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        out.println(hello.sayHello("Duke"));
    }
  1. プロジェクト・ノードを右クリックし、「新規」>「その他」を選択します。

  2. 「コンテキストと依存性の注入」カテゴリで*beans.xml*を選択します。「次」をクリックします。

  3. デフォルトのファイル名( beans )を使用します。「終了」をクリックします。

「終了」をクリックすると、ウィザードによってWebアプリケーション内に beans.xml ファイルが作成されます。 beans.xml がアプリケーションの一部である場合は、CDIが自動的に有効になります。

  1. beans.xml ファイルを変更して、 bean-discovery-mode のデフォルト値を all に変更します。

bean-discovery-mode="*all*"

変更内容を保存し、ファイルを閉じます。

``bean-discovery-mode`` 値の間の違いについては、次のページを参照してください。
  • Java EE 7チュートリアルの25.1 CDIアプリケーションのパッケージ

  • http://stackoverflow.com/questions/18107858/cdi-inject-fails-on-maven-embedded-glassfish-plugin-org-jboss-weld-exceptions

    1. 「プロジェクト」ウィンドウのMavenHelloWebClientの「依存性」ノードを右クリックし、「依存性の追加」を選択します。

    2. 「スコープ」として「Provided」を選択します。

    3. 「ライブラリの追加」ダイアログで、「開いているプロジェクト」タブをクリックし、「MavenHelloServiceApi OSGiバンドル」を選択します。「追加」をクリックします。

    4. もう一度「依存性」ノードを右クリックし、「依存性の追加」を選択します。

    5. 「ライブラリの追加」ダイアログで「依存性管理」タブをクリックし、親POMプロジェクトで指定した osgi-cdi-api アーティファクトを選択します。「追加」をクリックします。

cdi add dependency3
Figure 8. 「ライブラリの追加」ダイアログの「依存性管理」タブ
  1. エディタで HelloServlet.java 内を右クリックし、「インポートを修正」([Alt]-[Shift]-[I]、Macの場合は[⌘]-[Shift]-[I])を選択して com.mycompany.mavenhelloserviceapi.Hellojavax.inject.Inject および org.glassfish.osgicdi.OSGiService を追加します。変更を保存します。

com.mycompany.mavenhelloserviceapi.Hello のインポート文がIDEによって自動的に追加されない場合は、手動で追加する必要があります。
  1. MavenOSGiCDIProjectを右クリックし、「消去してビルド」を選択します。

プロジェクトをビルドすると、「出力」ウィンドウに次のような出力が表示されるはずです。

Reactor Summary:

MavenOSGiCDIProject ............................... SUCCESS [0.798s]
MavenHelloServiceApi OSGi Bundle .................. SUCCESS [7.580s]
MavenHelloServiceImpl OSGi Bundle ................. SUCCESS [1.142s]
MavenHelloWebClient ............................... SUCCESS [8.072s]
------------------------------------------------------------------------
BUILD SUCCESS
MavenOSGiCDIProjectプロジェクトをビルドするときに、Webアプリケーションが自動的にビルドされない場合は、Webアプリケーションを手動でビルドする必要があります。

「ファイル」ウィンドウで、Webアプリケーションのプロジェクト・ノードを展開して、アーカイブ MavenHelloWebClient-1.0-SNAPSHOT.war がターゲット・ディレクトリに作成されたことを確認します。WebクライアントのWARアーカイブを展開して MANIFEST.MF を調べると、マニフェストに次のような行が含まれていることがわかります。

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: nb
Build-Jdk: 1.7.0_45

OSGiバンドルとしてのWebアプリケーションのビルド

``@OSGiService`` を使用して登録済のOSGiバンドルを取得するには、Webアプリケーションを ``BundleContext`` にアクセスできるバンドルにする必要があります。WARをOSGiバンドル(Webアプリケーション・バンドル)にするには、WAR内の ``MANIFEST.MF`` に ``Web-ContextPath`` メタデータを追加します。  これを行うには、 ``maven-bundle-plugin`` への指示の中に ``<Web-ContextPath>`` 要素を指定し、このプラグインによって生成されるマニフェストにこの要素を含めます。次に、 ``maven-war-plugin`` の構成を変更して、 ``maven-bundle-plugin`` によって生成されたマニフェストをWARアーカイブに追加するようにプラグインに指示します。
  1. 「プロジェクト」ウィンドウで、MavenHelloWebClientの下の「プロジェクト・ファイル」ノードを展開し、 pom.xml をダブルクリックしてエディタでこのファイルを開きます。

  2. 次のエントリを追加して、POMに maven-bundle-plugin を追加します。

<build>
    <plugins>
        *<plugin>
             <groupId>org.apache.felix</groupId>
             <artifactId>maven-bundle-plugin</artifactId>
             <version>2.2.0</version>
             <extensions>true</extensions>
             <configuration>
                 <supportedProjectTypes>
                     <supportedProjectType>ejb</supportedProjectType>
                     <supportedProjectType>war</supportedProjectType>
                     <supportedProjectType>bundle</supportedProjectType>
                     <supportedProjectType>jar</supportedProjectType>
                 </supportedProjectTypes>
                 <instructions>
                     <!-- Specify elements to add to MANIFEST.MF -->
                     <Web-ContextPath>/mavenhellowebclient</Web-ContextPath>
                     <!-- By default, nothing is exported -->
                     <Export-Package>!*.impl.*, *</Export-Package>
                 </instructions>
             </configuration>
             <executions>
                 <execution>
                     <id>bundle-manifest</id>
                     <phase>process-classes</phase>
                     <goals>
                         <goal>manifest</goal>
                     </goals>
                 </execution>
                 <execution>
                     <id>bundle-install</id>
                     <phase>install</phase>
                     <goals>
                         <goal>install</goal>
                     </goals>
                 </execution>
             </executions>
         </plugin>*
  1. maven-war-plugin の構成要素を変更して、 MANIFEST.MF にバンドル情報を追加します。変更を保存します。

 <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-war-plugin</artifactId>
     <version>2.3</version>
     <configuration>
         *<archive>
             <!-- add bundle plugin generated manifest to the war -->
             <manifestFile>
                 ${project.build.outputDirectory}/META-INF/MANIFEST.MF
             </manifestFile>
             <!-- For some reason, adding Bundle-ClassPath in maven-bundle-plugin
             confuses that plugin and it generates wrong Import-Package, etc.
             So, we generate it here.-->
             <manifestEntries>
                 <Bundle-ClassPath>WEB-INF/classes/</Bundle-ClassPath>
             </manifestEntries>
         </archive>*
         <failOnMissingWebXml>false</failOnMissingWebXml>
     </configuration>
 </plugin>
  1. 「プロジェクト」ウィンドウでMavenHelloWebClientプロジェクト・ノードを右クリックし、「消去してビルド」を選択します。

これで、WARアーカイブを展開して MANIFEST.MF をエディタで開くと、 maven-bundle-plugin の構成で指定した Web-ContextPath: /mavenhellowebclient エントリやバンドル名エントリを含む追加情報が MANIFEST.MF に含まれていることがわかります。

Manifest-Version: 1.0
Export-Package: com.mycompany.mavenhellowebclient;uses:="com.mycompany
 .mavenhelloserviceapi,javax.servlet,org.glassfish.osgicdi,javax.injec
 t,javax.servlet.annotation,javax.servlet.http";version="1.0.0.SNAPSHO
 T"
Bundle-ClassPath: WEB-INF/classes/
Built-By: nb
Tool: Bnd-1.50.0
Bundle-Name: MavenHelloWebClient
Created-By: Apache Maven Bundle Plugin
*Web-ContextPath: /mavenhellowebclient*
Build-Jdk: 1.7.0_45
Bundle-Version: 1.0.0.SNAPSHOT
Bnd-LastModified: 1395053424008
Bundle-ManifestVersion: 2
Import-Package: com.mycompany.mavenhelloserviceapi;version="[1.0,2)",j
 avax.inject,javax.servlet,javax.servlet.annotation,javax.servlet.http
 ,org.glassfish.osgicdi;version="[1.0,2)"
Bundle-SymbolicName: com.mycompany.MavenHelloWebClient
Archiver-Version: Plexus Archiver

WebアプリケーションをOSGiバンドルとしてビルドする方法の詳細は、次のページを参照してください。

Webアプリケーション・バンドルのデプロイ

この課題では、Webアプリケーション・バンドルをGlassFishインストールの autodeploy/bundles フォルダにコピーします。

  1. MavenHelloWebClient-1.0-SNAPSHOT.war を含む target ディレクトリに移動します。

  2. MavenHelloWebClient-1.0-SNAPSHOT.war をGlassFishインストールの autodeploy/bundles フォルダにコピーします。

WARアーカイブをこのディレクトリにコピーすると、GlassFishのサーバー・ログに次のような出力が表示されます。

INFO: Started bundle: file:/glassfish-3.1.1/glassfish/domains/domain1/autodeploy/bundles/MavenHelloWebClient-1.0-SNAPSHOT.war
...
INFO: ---- Injection requested for framework service type interface com.mycompany.mavenhelloserviceapi.Hello and annotated with dynamic=true, serviceCriteria=
INFO: WEB0671: Loading application [com.mycompany.MavenHelloWebClient_1.0.0.SNAPSHOT] at [/mavenhellowebclient]
INFO: Registered ServletContext as a service with properties: {osgi.web.symbolicname=com.mycompany.MavenHelloWebClient, osgi.web.version=1.0.0.SNAPSHOT, osgi.web.contextpath=/mavenhellowebclient}

これで、次のリンクをクリックすることで、ブラウザにサーブレットを表示できます。http://localhost:8080/mavenhellowebclient/HelloServlet

OSGi管理コンソールのインストールと使用

GlassFish OSGi管理コンソールを使用して、サーバーにデプロイされているOSGiバンドルをインストール、起動および停止できます。この課題では、GlassFish OSGi管理コンソールを有効にしてから、登録済のOSGiバンドルのリストを表示します。

OSGiコンソールを有効にし、デプロイされたバンドルをGlassFishドメイン管理コンソールに表示するには、次の手順を実行して必要なGlassFishアドオンをインストールします。

  1. ブラウザでGlassFishドメイン管理コンソールを開きます。

「サービス」ウィンドウのGlassFishサーバー・ノードを右クリックし、「ドメイン管理コンソールを表示」を選択します。

  1. 左側のナビゲーション列で「更新ツール」をクリックします。

  2. 利用可能なアドオンの一覧から glassfish-osgi-gui を選択します。

「インストール」をクリックしてライセンスに同意します。

cdi glassfish addons
Figure 9. 更新ツールGlassFish管理コンソール
  1. GlassFishサーバーを再起動します。

*重要: *GlassFish Server 3.1.2.2を使用している場合、 GLASSFISH-INSTALL/glassfish/config/ ディレクトリにある osgi.properties ファイルを変更し、 org.osgi.framework.startlevel.beginning プロパティの値を"2"に設定する( org.osgi.framework.startlevel.beginning=2 )必要があります。 詳細は、次のフォーラムの投稿を参照してください。 + Cannot start web console in Glassfish version 3.1.2.2+.

  1. 管理コンソールを再度開き、左側のナビゲーション列で「サーバー(管理サーバー)」をクリックします。

  2. 「OSGiコンソール」タブをクリックして、デプロイされているOSGiバンドルの一覧を表示します。

cdi glassfish console
Figure 10. 「ライブラリの追加」ダイアログの「依存性管理」タブ
OSGiバンドルのリストを表示する際に、ユーザー名とパスワードの入力を求められることがあります。OSGiコンソール・タブにバンドルのリストが表示されない場合は、承認ダイアログが非表示になっていないことを確認します。IDEのインストール時にGlassFish 4サーバーをインストールした場合、サーバーのデフォルトのユーザー名は admin です。デフォルトでは、パスワードは空白です。

一覧を下にスクロールして登録済のOSGiバンドルのステータスを表示したり、個々のバンドルを起動および停止したりできます。一覧をIDで(最大から最小へ)ソートすると、デプロイした3つのバンドルが一覧の最上位付近に表示されることがわかります。

関連項目

NetBeans IDEおよびMavenを使用してOSGiバンドルを開発する方法の詳細は、次のリソースを参照してください。

nbj2eeメーリング・リストに登録することによって、NetBeans IDE Java EE開発機能に関するご意見やご提案を送信したり、サポートを受けたり、最新の開発情報を入手したりできます。