2

OSGi フラグメントとClass.forName(). 以下の例は、私の問題を示しています。

サードパーティのバンドルがありFooます。どうにも改造できませんFoo。バンドルには次のクラスが含まれています。

public class Serializer {
    public String summarizeClass(String className) {
        Class<?> myClass = Class.forName(className);
        ...
    }
}

Barbundle forからこのメソッドを呼び出すと、 bundle のクラスパスにないためorg.myPackage.MyClass、失敗します。MyClassFoo

bundle のクラスパスを変更するためにFoo.fragment、依存関係を持つフラグメントを単純に追加できますか? それとも、この依存関係はフラグメント内のクラスにのみ適用されますか?BarFoo

簡単Class.forName()に言うと、Host バンドルのクラスで実行された場合の OSGi のセマンティクスは何ですか? それには以下が含まれますか?

  • Q: バンドル クラスは? A: はい。
  • Q: フラグメントに含まれるクラスは? A: はい。ソース
  • Q: インポートされたパッケージと、必要なバンドルからエクスポートされたパッケージは? A: はい。
  • Q: インポートされたパッケージと、すべてのフラグメントの必要なバンドルからエクスポートされたパッケージは? A: わかりません。
4

1 に答える 1

5

OSGi コア仕様、リリース 5.0.0 のセクション 3.14 を参照してください。

概要: Import-Package ヘッダーまたは Require-Bundle ヘッダーだけでフラグメントを追加できます。これらのヘッダーの句は、ホスト バンドル内の対応するヘッダーに追加されます。したがって、次を追加すると:

 Fragment-Host:  Foo;version="[1,2)"
 Import-Package: org.myPackage;version="[1,2)"

その後、Foo バンドルは MyClass を認識できるようになります。

summarizeClassのコードは、単一のクラス空間が存在し、クラスが特定のクラスを一意に識別することを前提としていることに注意してください。ただし、大規模なアプリケーションには、同じ依存関係の競合するバージョンを頻繁に使用する依存関係ツリーがあります。これらの場合、この仮定は非常に間違っています。OSGi は、解決時にすべてのクラスが一貫したクラス空間を参照することを保証しますが、異なるバンドルは異なるクラス空間を参照できます。この機能では、バンドルに必要なパッケージを OSGi が認識している必要があります。悲しいことに、Class.forName には他にも悪い性質があり (クラスをメモリに固定します)、ほとんどの場合、まったく不要です。

于 2013-09-09T09:25:07.733 に答える