3

Declarative Services を使用して、別のバンドルに機能を提供するサービス バンドルを作成しようとしています。ただし、サービス プロバイダー バンドルが必要になるまで起動しないようにします。私の条件を説明しましょう。

2 つのバンドルがあります。

-com.example.serviceprovider

-com.example.serviceconsumer

Service Provider バンドルは、次のように Declarative Services を使用してサービスを提供します。

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" enabled="true"     immediate="true" name="samplerunnable1">
<implementation class="com.example.serviceprovider.SampleRunnable"/>
<service>
    <provide interface="java.lang.Runnable"/>
</service>

サービス コンシューマは、提供されたサービスを次のように参照します。

<reference name="SampleRunnable"
    interface="java.lang.Runnable"
    bind="setRunnable"
    unbind="unsetRunnable"
    cardinality="1..n"
    policy="dynamic"/>

これらのバンドルの両方が起動時に「アクティブ」である場合、サービス コンシューマは、サービス プロバイダによって宣言されたサービスとの通信に問題はありません。この問題は、サービス プロバイダーを怠惰な方法で起動しようとすると発生します。

Service Provider が遅延読み込みに設定されると、OSGi コンソールに次のように表示されます。

osgi> ss
  "Framework is launched."
  id      State       Bundle
  15      STARTING    com.example.serviceconsumer_1.0.0.X
  16      RESOLVED    com.example.serviceprovider_1.0.0.X

私が期待するのは、バンドル 16 が「解決済み」であるにもかかわらず、少なくとも登録されているのはサービスであるということです。しかし、「バンドル」コマンドを呼び出すと、「登録されたサービスはありません」と表示されます。

osgi> bundle 16
com.example.serviceprovider_1.0.0.X [17]
  Id=17, Status=RESOLVED    Data Root=C:\apache\apache-tomcat-.0.40\work\Catalina\localhost\examplesX\eclipse\configuration\org.eclipse.osgi\bundles\17\data
  "No registered services."
  No services in use.
  No exported packages
  Imported packages
     org.osgi.framework; version="1.7.0"<org.eclipse.osgi_3.8.0.v20120529-1548 [0]>
  No fragment bundles
  Named class space
    com.example.serivceprovider; bundle-version="1.0.0.X"[provided]
  No required bundles

たぶん、遅延ロードされたバンドルとサービス登録の基本的な概念を見逃していたのでしょう。バンドルが「解決済み」状態にある場合、すべての「ワイヤ」を接続する必要はありませんか? (つまり、クラスローダがあり、インポートとエクスポートの依存関係が解決され、サービスが登録されています。) サービス コンシューマがサービスにアクセスしようとすると、そのバンドルは "ACTIVE" 状態に移行するべきではありませんか? ここで欠けているのは何ですか?

4

2 に答える 2

5

RESOLVED 状態のバンドルはサービスを提供できず、Declarative Services によって無視されます。遅延読み込み動作が必要な場合でも、通常はすべてのバンドルを起動時に開始する必要があります。重要なのは、バンドルのアクティベーションを安価 (または無料!) にし、必要な場合にのみコンポーネントの初期化に対して料金を支払うことです。

DS は、デフォルトですでに遅延アクティベーションを処理しています。これを行うために有効にしたり変更したりする必要はありません。基本的に、DS はサービス エントリをレジストリに公開しますが、クライアントがサービスを使用しようとするまで、コンポーネントを実際にインスタンス化する (またはそのクラスをロードする) ことはありません。

さらに、DS は必要になるまでクラスをロードしないため、バンドルにBundleActivator がない限り、OSGi はバンドル用の ClassLoader を作成する必要さえありません。

繰り返しますが、バンドルを RESOLVED 状態のままにしようとするべきではありません。このようなバンドルは、静的コードとリソースのみをエクスポートできますが、何も「実行」することはできず、サービス レジストリに参加することもできません。

于 2013-06-07T16:58:27.807 に答える