2012-04-17 12 views
6

EEアプリケーションをOSGiに移行したい。私のアプリケーションは、ビジネスライブラリ、データベースJPA /エンティティ、REST/WSインタフェースで構成されています。それはまた、Webクライアントを持っています。OSGi JAX-RSとbnd宣言型サービス

まず構造体のプロトタイプを作成し、すべてのインタフェースとバンドルを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 
    } 
    ... 

} 

iはBND @Componentとのリソースに注釈を付けることができます@Resourceを注入することができますか? すべて正常に動作しますが、サービスは常にnullです。

私のバンドルをBNDに宣言してWeb/WABパッケージにする方法は?

私はMavenのバンドルを使用:BND命令で

<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>      

... 

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

私は最近、同様の問題(サービスが縛られていない)に遭遇し、[split package](http://wiki.osgi.org/wiki/)まで追跡しました。 Split_Packages)の問題です。サービスインタフェースを別のパッケージに入れてみましたか? –

+0

@BjörnPollexに感謝の意を表します。私は3つのバンドルを持っています.1つはインタフェースのみ、もう1つはサービス実装とRESTバンドルです。私はそれをRESTバンドルに戻して、それがうまくいくかどうかを確認しました。私がやっていることが、私のDS xmlを見つけられないSCRの問題かもしれないよりも正しいと思われる場合。 – Gadi

+0

@donalfellowsを編集してくれてありがとう – Gadi

答えて

5

のOSGiは、リモートサービスと呼ばれる仕様の一部を持っています。ごく短期間では、サービスを特別なサービスプロパティで登録し、プロパティテクノロジに基づいてテクノロジを登録し、そこからエンドポイントを作成する必要があります。 RESTだけでなく、リモートコールを処理する技術についても同様です。 OSGi Core仕様の「リモートサービス」の章に情報があります。

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

私はOSGiの中でスプリング固有のソリューションを使用したくないので、私は最後にCXFを使用せず、独自のソリューションを作成しました。 JerseyとRemote Servicesの仕様に基づいています。 OSGiサービスがservice.exported.interfaces = *で指定され、service.exported.configs = org.everit.osgi.remote.jerseyとすると、HttpServiceで/ rest/pathの下に休止エンドポイントが作成されます。あなたのバンドルは単純なバンドルにすることができますwabする必要はありません。

リモートサービスの実装を通じてサービスを公開する場合は、元のクラスで実装されているインターフェイスにJax-RS注釈を付け、そのインターフェイスに基づいてサービスを公開する必要があります。

OSGiの@Resourceと@Componentアノテーションの代わりに、驚くほどSpringに似ているBlueprint(OSGi仕様の一部)を使用することをお勧めします。現在、Apache AriesとGemini Blueprintが実装しています。青写真で簡単に豆を作り、お互いにつなげることができます。このようにしてリモートサービスを登録する場合は、青写真の助けを借りて任意のプロパティを設定できます(春のapplicationcontext.xmlにあるBeanのプロパティと同じように)。

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

このサンプルアプリケーションは、リモートサービス仕様の章を開始するのに役立ちます。

JPAとインジェクション(Blueprint)の使い方を見るには、OSGi概説の仕様をチェックして、好きな実装を見つけてください。私はすでに提供したサンプルURLの兄弟として見つけることができる青写真とhibernate-jpaに基づくサンプルプロジェクトを作成しました。

更新

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

2

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

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

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

私は、Javaの静的なキーワードで参照変数の静的を作ることによって、この問題を解決:

private static SomeService service = null; 

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

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

+0

静的参照をosgiコンポーネントに格納することはお勧めできません。 –

0

@Path注釈付きの型をサービス自体として登録すると、この問題は解決されます。 DSでは、他のサービスを注入するだけではありません。私はこの1年前にこの問題に直面しました。それで、私が記述したものを正確に提供する小さなOSGi JAX-RSコネクタを書いたのはなぜですか。あなたが好きなら試してみてください:https://github.com/hstaudacher/osgi-jax-rs-connector

関連する問題