web-dev-qa-db-ja.com

OSGIバンドルのBundle-Classpathの使用目的は何ですか

OSGIバンドルのBundle-Classpathの使用目的を理解しようとしています。

これが私の理解です。これが正しいかどうかを理解するのを手伝ってください。

他のバンドルのエコシステムにデプロイされるOSGIバンドルの作成に取り組んでいるとしましょう。私が取り組んでいるバンドルには他のバンドルが必要ですが、これらはこのエコシステムにロード/エクスポートされておらず、エコシステムが何をエクスポートするかを制御できません。このようなシナリオでは、これらのバンドルを、バンドルの一部となるディレクトリ(たとえば、「lib」)内に配置できます。これらのバンドルは、ロードできるように、Bundle-Classpathからも参照する必要があります。

  • これはBundle-Classpathの正しいユースケースですか?
  • これらの追加のバンドルもOSGIコンテナーにロードされ、それらによってエクスポートされたパッケージは他のバンドルで使用できますか?
17
Parag

Bundle-ClassPathは、バンドルに依存関係を含めることを目的としているため、バンドルをスタンドアロンでデプロイできます。

例を見てみましょう。バンドル内のコードがライブラリを使用しているとします。グーグルグアバ。バンドルをパッケージ化するには、次の2つの選択肢があります。

  1. 自分のコードだけを含むバンドルを作成するだけです。バンドルには、Guavaへの依存を宣言するImport-Packageステートメントが含まれるようになり、私のバンドルをアプリケーションにデプロイしたい人は、Guavaもデプロイする必要があります。

  2. または、バンドル内にGuavaのコピーを含めて、Bundle-ClassPathから参照することもできます。私のバンドルをデプロイする人は誰でも私のバンドルをデプロイできjust、Guavaの入手先について心配する必要はありません。実際、バンドル内のGuavaの存在は実装の詳細であり、デプロイヤーは私がそれを使用していることを知る必要さえありません。

これら2つのオプションのどちらを選択するかは、トレードオフです。オプション2には、スタンドアロンであるため、バンドルの展開が簡単であるという利点があります。必要なものはすべて、バンドル内にあります。一方、私のバンドルは必要以上に大きいので、他の多くのバンドルにも独自のGuavaのコピーが埋め込まれていると問題になる可能性があります。

オプション2のより深刻な問題は、ライブラリのすべての依存関係がmy依存関係になることです。実際、GuavaはJavaライブラリのまれな例であり、独自の依存関係はありません...しかし、他の多くのJavaライブラリは、一時的な依存関係の巨大なツリーにドラッグします。たとえば、Hibernateでこのアプローチを使用すると、独自のバンドルにもその大きな依存関係が設定されます。これは非常に醜く、非常に迅速になります。

したがって、Bundle-ClassPath/Embed-Dependencyを使いすぎないように注意する必要があります。依存関係が(a)小さく、推移的な依存関係がなく、(b)バンドルがライブラリを内部実装の詳細として使用している場合、つまりパブリックAPIの一部ではない場合にのみ、使用を検討する必要があります。

[〜#〜] update [〜#〜]

輸出についての2番目の質問に答えるのを忘れました。答えは「いいえ」です。Bundle-ClassPathに配置した「バンドル」のエクスポートは、独自のバンドルのエクスポートにはなりません。実際、Bundle-ClassPathに配置したJARはバンドルとしてはまったく扱われず、単なるJARです。

Bundle-ClassPathのJAR内からのパッケージをエクスポートすることを選択できますが、これは独自のバンドルのMANIFEST.MFで行う必要があります。

35
Neil Bartlett

このヘッダーの最も一般的な使用例は、外部ライブラリのパッケージ化です。ライブラリfoo.jarがあり、そのクラスをバンドルで使用したいとします。

あなたはそのように瓶をあなたのバンドルに入れます、

/
  com/company/Activator.class
  foo.jar
  META-INF/MANIFEST.MF

マニフェストで、使用できるようになりました

Bundle-ClassPath: foo.jar,.

クラスパスに.を含めることを忘れないでください。そうしないと、バンドル内のクラスを見つけることができなくなります。

クラスがBundle-ClassPathにある場合、他のクラスと同じように使用できます。コードで使用するか、エクスポートします。

ここから少し離れているかもしれません。

Bundle-Classpathは、クラスおよびリソース要求を検索するための相対バンドルJARファイルの場所の順序付きのコンマ区切りリストです。

これが意味するのは、あるバンドルクラスが同じバンドル内の別のクラスを必要とする場合、それを含むバンドルのバンドルクラスパス全体が検索されてクラスが見つかるということです。

From OSGI in Action

具体的なケースを考えてみましょう。次の構造のバンドル(JARファイル)を想像してみてください。

src/a/A.class
src2/b/B.class
src3/c/C.class

a.Ab.B、およびc.Cを相互に使用できるようにする場合は、バンドルクラスパスに関連するものとしてsrcsrc2、およびsrc3を定義する必要があります。つまり、マニフェストファイルに次の行を追加する必要があります。

Bundle-ClassPath: src,src2,src3
2