6

EE アプリケーションを OSGi に移行したいと考えています。私のアプリケーションは、ビジネス ライブラリ、データベース JPA/エンティティ、および REST/WS インターフェイスで構成されています。また、Web クライアントも備えています。

まず、構造のプロトタイプを作成し、すべてのインターフェースとバンドルが OSGi のクリーンな方法で相互に通信できるようにします。特定のベンダーやフレームワークを使わずに、できるだけクリーンな仕様を使用したいと考えています。

マニフェストと宣言型サービスを生成するために bnd maven プラグインを使用しています。次のようなインジェクションを使用して、残りのリソースから OSGI サービス (別のバンドル) に呼び出しを行いたいと考えています。

@Path("some-resources")
@Component
public class SomeResources{

   private SomeService service = null;

   @Reference
   public void setController(SomeService service) {   // <- this is never called
    this.service = service;
   }

   @GET
   @Produces(javax.ws.rs.core.MediaType.APPLICATION_XML)
   public Object getSomeService() {                  // <- called 
    try {
        service.process("Hello World");              // <- Error null object
   }
    ...

}

リソースに bnd のアノテーションを付けたり、注入@Componentしたりできますか? @Resourceすべて正常に動作しますが、サービスは常に null です。

BND のバンドルを web/wab パッケージにするために宣言するにはどうすればよいですか?

私はmavenバンドルを使用しています:

<packaging>bundle</packaging>

...

        <plugin>                    
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>2.3.7</version>
                <extensions>true</extensions>
                <dependencies>
                    <dependency>
                        <groupId>biz.aQute</groupId>
                        <artifactId>bndlib</artifactId>
                        <version>1.50.0</version>
                    </dependency>
                </dependencies> 
                <configuration>
                    <supportedProjectTypes>
                        <supportedProjectType>ejb</supportedProjectType>
                        <supportedProjectType>war</supportedProjectType>
                        <supportedProjectType>wab</supportedProjectType>
                        <supportedProjectType>bundle</supportedProjectType>
                        <supportedProjectType>jar</supportedProjectType>
                    </supportedProjectTypes>
                    <instructions>
                        <_include>-osgi.bundle</_include>
                    </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>                    

 ...

bnd 命令で

Web-ContextPath: my-root-http/rest/
Service-Component: *
4

3 に答える 3

5

OSGi には、リモート サービスと呼ばれる仕様の一部があります。簡単に言えば、特別なサービス プロパティを使用してサービスを登録し、そのプロパティに基づいてテクノロジがサービスを取得し、そこからエンドポイントを作成するという方法で機能します。これは REST だけでなく、リモート呼び出しを処理するすべてのテクノロジーに関係しています。OSGi コア仕様の「リモート サービス」の章に情報が記載されている場合があります。

それは仕様ですが、誰がそれを実装しますか? 現在、私が試した 2 つの大きなプロジェクトがあります。CXF DOSGi および Eclipse ECF。これらは、リモート サービス仕様をサポートするいくつかのテクノロジを提供します。CXF は、サーバー側とクライアント側の両方での実装に基づいて、特に Jax-RS をサポートします。

OSGi 内で Spring 固有のソリューションを使用したくなかったので、最後に CXF を使用せず、独自のソリューションを作成しました。これは、Jersey およびリモート サービス仕様に基づいています。OSGi サービスが service.exported.interfaces=* および service.exported.configs=org.everit.osgi.remote.jersey で指定されている場合、HttpService を使用して /rest/ パスの下に REST エンドポイントが作成されます。バンドルは wab である必要はなく、単純なバンドルでもかまいません。

Remote Services 実装のいずれかを介してサービスを公開する場合は、Jax-RS アノテーションを元のクラスによって実装されたインターフェイスに取り込み、そのインターフェイスに基づいてサービスを公開する必要があることに注意してください。

OSGi 内の @Resource および @Component アノテーションの代わりに、Spring に驚くほど似ている Blueprint (OSGi 仕様の一部) を使用することをお勧めします。現在、Apache Aries と Gemini Blueprint が実装しています。ブループリントを使用すると、簡単に Bean を作成して相互に接続できます。この方法でリモート サービスを登録すると、ブループリントを使用して任意のプロパティを設定できます (Spring applicationcontext.xml の Bean のプロパティと同様)。

私が作成したサンプル アプリケーションはhttps://source.everit.biz/svn/everit-osgi/trunk/samples/jaxrs/ (user/passwd: guest/guest)にあります。このサンプルを開始および開発する方法を説明するガイドがhttp://cookbook.everit.orgにあります。

サンプル アプリケーションが、リモート サービス仕様の章を始めるのに役立つことを願っています。

JPA とインジェクション (ブループリント) の使用方法を確認するには、OSGi Compendium 仕様で可能性を確認し、好みの実装を見つけてください。また、既に提供したサンプル URL の兄弟として見つけることができる blueprint と hibernate-jpa に基づくサンプル プロジェクトも作成しました。

アップデート

https://github.com/everit-org/osgi-remote-jerseyで作成した JAXRS エクステンダーの実装もあります。ドキュメントについては、README を参照してください。これは、ホワイトボード サービスのプロパティに基づいて機能する方法が最初のものとは異なります。

于 2012-05-29T22:43:46.133 に答える
2

OSGi、Declarative Services、および Jersey で同様の問題が発生しました。

リソースには @Component および @Reference アノテーションを付けることができます。これにより、DS は SomeResource クラスのインスタンスを作成し、すべての依存関係 (参照) が満たされたときにこのインスタンスに有効な参照を挿入するように指示されます。

参照が null である理由は、JAX-RS 実装が Web 要求ごとに SomeResource クラスの新しいインスタンスを作成するためです。SomeResource クラスのこのインスタンスは、DS によって作成されたものと同じではありません。

Java static キーワードを使用して参照変数を static にすることで、この問題を解決しました。

private static SomeService service = null;

これにより、依存関係の参照がインスタンスではなくクラス オブジェクトに関連付けられ、すべてのインスタンスが注入された値を確認できるようになりました。

このソリューションにより、新しい問題が発生しました。この参照は、インスタンスが破棄されても破棄されないため、バインド解除イベント (サービスが利用できなくなったとき) でクリアする必要があります。

于 2012-06-26T10:58:04.953 に答える
0

この問題は、@Path アノテーション付きの型をサービス自体として登録すると解決します。DS を使用すると、他のサービスを注入するだけではありません。私はほぼ1年前にこの問題に直面しました。それが、私が説明したことを正確に提供する小さな OSGi JAX-RS コネクターを作成した理由です。よろしければお試しください: https://github.com/hstaudacher/osgi-jax-rs-connector

于 2012-08-28T08:34:02.683 に答える