2

私は現在、OSGiに非常に不利なサードパーティのライブラリをOSGiバンドルで利用できるようにすることに取り組んでいます。これらのライブラリーの1つ(私はすでにbndを使用してバンドルに変換しました)は、(少なくともOSGiルールによって)ロードできないはずのクラスをロードすることができます。バンドルがと呼ばれFoo、それがクラスをロードするパッケージがと呼ばれると仮定しましょうbar

Foobarオプションのインポートとしてあります。ただし、をエクスポートするバンドルがないため、これは問題ではありませんbar。ブート委任を使用していません。ただし、jarを含む-filebarはapplication-classpath上にあります(OSGiフレームワークは私のアプリケーションに埋め込まれて実行されます)。

どうやらFooどういうわけかOSGiクラスローディングインフラストラクチャをバイパスしています。これはどのように行うことができますか?カスタムクラスローダーを使用する理由がないため、カスタムクラスローダーを使用していないことは間違いありません(機能のFoo提供にそのようなものが必要になることはありません)。では、OSGiクラスローディングをバイパスするためにバンドルで使用できる標準のすぐに使えるメソッドは何でしょうか?

4

4 に答える 4

1

どの OSGi フレームワークを使用していますか? パッケージに関する詳細情報を要求するコマンド プロンプト コマンドまたはその他の手段はありますか? OSGi 仕様により、詳細な調査が可能になり、ほとんどのフレームワークは、OSGi PackageAdmin およびその他の API に対応するコマンド/インターフェースを提供します。

他の OSGi フレームワークでも発生しますか?

ProSyst の mBedded Serverを OSGi フレームワークとして使用すると、コマンドを使用して、誰がどこから何をロードしているかを検出できます。

pkginfo [<package>[ <package>]]- 指定したパッケージの依存関係を表示します。パラメーターがない場合は、フレームワークで使用可能なすべてのパッケージに関する情報を受け取ります。

于 2012-08-02T07:54:23.480 に答える
1

クラスがアプリケーションクラスローダーで利用可能な場合、これはトリックを行います:

BundleContext.class.getClassLoader().loadClass("bar.X")

ローダーによってロードされたクラスを取得できる場合は、他のすべてのクラスを取得できます。もちろん、セキュリティを実行している場合は、クラス ローダーへのアクセスを禁止できます。

于 2013-08-02T09:20:38.120 に答える
0

さて、以下は証明のない私の仮定です。

非OSGiオプションのインポートを実装する最も簡単な方法は、の使用法ですClass.forName(name)-classLoaderなしの署名に注意してください。このためのソースコードを見てみましょう:

return forName0(className, true, ClassLoader.getCallerClassLoader());

他の順番で見てみましょうClassLoader.getCallerClassLoader()

...
Class caller = Reflection.getCallerClass(3);
...

3-呼び出すフレームの数です(たとえば、getCallerClass(0)-Reflectionクラスを返します)。スタック内の#3のコードを簡単に数えることができ、OSGiによってロードされていない場合は、デフォルトのclassLoaderが使用されます。

于 2012-08-02T07:40:48.167 に答える
0

決定的な答えを与えるのに十分な情報がないため、以下は推測です。ライブラリが Thread Context ClassLoader (TCCL) を使用している可能性があります。パッケージが独自のバンドルに表示されている場合bar(つまり、バンドル内のプライベート パッケージである場合)、バンドルを呼び出すと、バンドルからパッケージをロードFooできるように TCCL が設定されている可能性があります。bar

この理論をテストするには、バンドルnullを呼び出す前にTCCL を明示的に設定するようにコードを変更してみてください。FooClassNotFoundException

于 2012-08-02T09:38:55.597 に答える