6

ユーザーに機能を提供するためにOSGiをプラグインするバンドルを作成しています。

Usercase: User input the classname string and click "list" button, the corresponding class will be decompiled and show the text on GUI for user.

だからここに私の問題があります:私は私のバンドルのクラスローダーしか持っていません、どうすればOSGiコンテナ全体から名前でクラスをロードできるOSGiコンテナクラスローダーを取得できますか?(OSGiが起動すると、すべてのバンドルとすべてのクラスがメモリーにロードされると思います。OSGiコンテナー・クラスローダーが実際に存在し、可能であれば、どのクラスもロードできます)

誰もがこの仕事をする方法を知っていますか?サンプルコードは高く評価されています。

4

4 に答える 4

13

私はあなたを助けることができる2つの可能な状況を見ることができます。

目に見えるクラス

次のようなステートメントを追加できます

DynamicImport-Package: *

マニフェストに追加し、を使用してクラスをロードしてみてください

Class.forName("com.company.class");

エクスポートされているかどうかに関係なく、すべてのクラス

利用可能なすべてのクラスを本当に見つける必要がある場合、なぜこれが必要なのかわかりませんが、各バンドルに特定のクラスを「知っている」かどうかを尋ねることができます。この状況では、同じ名前の複数のクラスが作成される可能性があるため、適切なクラスを選択するのはあなた次第です。

あなたは次のようなことをすることができます

private List<Class<?>> findClass(BundleContext context, String name) {
    List<Class<?>> result = new ArrayList<Class<?>>();
    for (Bundle b : context.getBundles()) {
        try {
            Class<?> c = b.loadClass(name);
            result.add(c);
        } catch (ClassNotFoundException e) {
            // No problem, this bundle doesn't have the class
        }
    }
    return result;
}
于 2012-06-13T11:55:14.990 に答える
9

OSGiには、完全修飾クラス名だけでクラスに名前を付ける確実な方法はありません。その理由は、2つのバンドルが同じクラス名を異なる方法で定義できるためです。これは、たとえば、バンドルAがlib v1.0を必要とし、バンドルBがバージョン2.0で同じlibを必要とする場合に重要です。

バンドルも知っていれば、クラスに名前を付けることは可能です。したがって、(バンドルバンドル、文字列fqClassname)からクラスを解決できます。

これは、BundleContextを使用して実装できます。バンドルコンテキストからバンドルを一覧表示し、バンドルごとにクラスをロードできます。

もちろん、これらすべてのクラスローダーを単純に繰り返し処理して、名前でクラスを検索することもできます。問題は、それが一意である必要はないということです。あなたがあなたの場合に警告を印刷することができるので、それは大丈夫かもしれません。

したがって、必要な主要なAPIメソッドは次のとおりです。Bundle[] BundleContext.getBundles()クラスBundle.loadClass()

于 2012-06-13T14:27:23.983 に答える
4

私はあなたが何をしようとしているのか完全にはわかりませんが、OSGiフレームワークにインストールされている間にすべてのアプリケーションバンドルで何らかの形の処理を行う必要があるツールを構築していると仮定すると、OSGiエクステンダーパターンを検討することをお勧めします

于 2012-06-13T10:29:07.573 に答える
0

バンドルのマニフェストにインポートディレクティブがあり、必要なパッケージを取得していると思います。これが完了すると、探しているすべてのクラスがクラスローダーの一部になり、名前でクラスをロードできるようになります。

したがって、バンドル内のMETA-INF/MANIFEST.MFに次のようなものがあることを確認してください。

Import-Package: foo.bar.com;
于 2012-06-13T08:19:53.843 に答える