web-dev-qa-db-ja.com

Import-PackageとRequire-Bundleはいつ使用する必要がありますか?

OSGiは、(任意のバンドルからエクスポートされた)単一のパッケージをワイヤリングするImport-Packageと、特定の名前付きバンドルのエクスポートにワイヤリングするRequire-Bundleを介して依存関係を決定できるようにします。

グリーンフィールドOSGiアプリケーションを構築する場合、依存関係を表すためにどのアプローチを使用すればよいですか?ほとんどのバンドルは内部にありますが、外部(オープンソース)バンドルにはいくつかの依存関係があります。

50
AlBlue

私はRequire-BundleはEclipseのものだと信じています(これにより、OSGi仕様でEclipseに対応できるようになりました)。 「純粋な」OSGiの方法は、Import-Packageを使用することです。これは、パッケージを提供するバンドルからパッケージを明確に分離するためです。必要な機能への依存関係(Java特定のパッケージの特定のバージョンで提供されるAPI))を宣言する必要があります(その機能の提供元(重要ではないはず))ではありません。これにより、バンドルの構成がより柔軟になります。

JavaScriptの類推:これは、Webエージェントが特定のAPIをサポートしているかどうかを検出するのではなく、ユーザーエージェント文字列がブラウザの種類を示していることから推測するようなものです。

OSGiアライアンスのPeter Kriensは、これについて OSGiブログ でさらに詳しく述べています。

おそらく、Require-Bundleを使用する必要がある唯一のケースは、分割パッケージがある場合、つまり、複数のバンドルにまたがるパッケージである場合です。もちろん分割パッケージはお勧めしません。

50
Thilo

必須バンドルよりもインポートパッケージを優先します。

バンドルが必要:

  • 使用する明示的なバンドル(およびバージョン)を指定します。 requirdeバンドルをリファクタリングする必要があり、パッケージを別の場所に移動する場合、依存関係の人はMANIFEST.MFを変更する必要があります
  • バンドルのすべてのエクスポートへのアクセスを提供します。それらが何であるか、およびそれらが必要かどうかは関係ありません。必要のない部分に独自の依存関係がある場合は、次のことを行う必要があります。
  • バンドルは再エクスポートできます
  • 推奨されませんが、分割パッケージの使用を許可します。つまり、複数のバンドルにまたがるパッケージ
  • 非コードの依存関係、たとえば、リソース、ヘルプなどに使用できます。

インポートパッケージ:

  • 疎結合、パッケージ(およびバージョン)のみが指定され、ランタイムが必要なバンドルを見つける
  • 実際の実装は交換できます
  • 依存パッケージは、パッケージ所有者が別のバンドルに移動できます
  • ただし、より低い粒度でより多くのメタデータ(つまり、各パッケージ名)を維持する必要があります。
14
tekumara

Import-Packageを使用すると結合が緩くなるため、推奨されるはずです。私が所有していないパッケージ(slf4jなど)への依存関係を宣言するときに使用し、必要に応じて実装を入れ替えることができます。依存関係が自分のバンドルなど、自分で制御できるものである場合は、いずれにせよ重要な変更は自分自身で行われるため、Require-Bundleを使用します。

5
omerkudat

Import-Packageは避けてください。パッケージはバンドル間に多対多の関係を提供するため、検出および回避が困難な依存サイクルが発生しやすくなります。

一方、Require-Bundleは単一のバンドルを参照し、簡単なビルド時チェックによって依存関係グラフをサイクルから保護します。 Require-Bundleを使用すると、分離された下位レベルの抽象化を使用してレイヤードアーキテクチャを構築することがはるかに簡単になります。

0
Basilevs

以前に述べたように、既存のクライアントのMANIFEST.MFを変更せずに、あるバンドルから別のバンドルにパッケージを移動できるため、Import-Packageの方が良いはずです。

だが...

Eclipseを使用してバンドルを開発している場合は、Require-Bundleを使用する実用的な理由があります。

Eclipseは解決の単位としてパッケージを使用しません。バンドルを使用します。つまり、バンドルの1つのパッケージを使用する場合、Eclipseはバンドルをコンパイルしますが、そのバンドルからインポートされない残りのパッケージの使用に関する問題は報告されません。

あなたは(あなたは人間です)すべてが大丈夫だと考え、デプロイメントのためにバンドルをアップロードしますが...バンドルは実行時に壊れます。

この問題が今日(私にとって!)起こったので、私はそれについて確信しています。

良い解決策はEclipseクラスパスコンテナーを変更することですが、これを行わない場合は、パッケージの代わりにバンドルを必要とするこの種の問題を回避し、上記の価格を支払うこともできます(下位互換性なし)バンドル間のコード移動)。

0
Santiago Ruiz