2

私は 3 つの RCP プラグインのセットを持っています。1 つはメイン アプリケーション プラグイン、もう 1 つは計算のコレクション、3 つ目は GridGain のラッパーです。これは、特に計算プラグインからクラスのインスタンスを作成する必要があります。

メイン プラグインは、ExtensionPoint インスタンス化を使用して、計算プラグインと GridGain プラグインの両方からクラスをインスタンス化します。

    IExtensionRegistry registry = Platform.getExtensionRegistry();

    IExtensionPoint providerExtensionPoint = registry.getExtensionPoint(EXT_CORE_DATA_PROVIDERS);
    IConfigurationElement[] providers = providerExtensionPoint.getConfigurationElements();

    List<DataProviderFactory> dataProviders = new ArrayList<DataProviderFactory>();
    for (IConfigurationElement member : providers) {
        try {
            Object obj = member.createExecutableExtension(K_CLASS);
            if (obj instanceof DataProviderFactoryFactory) {
                DataProviderFactoryFactory factory = (DataProviderFactoryFactory) obj;
                for (Object o : factory.createProviderFactories(this, holdingProperties())) {
                    dataProviders.add((DataProviderFactory) o);
                }
            }
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    return dataProviders;

したがって、他のプラグインに直接依存することはありません。

私の問題は、GridGain が計算プラグインからクラスのインスタンスをインスタンス化する必要があるときに発生します。GridGain プラグインは計算プラグインに直接依存していないため、クラスをロードするプロセスではそこにクラスが表示されないため、ClassNotFoundException が発生します。

過去にRCP バディ ポリシーを使用して同様の問題を解決しましたが、これは ORM で直面する問題と同様の問題のようです。ただし、「登録済み」ポリシーは、クラスを定義するプラグイン (私の場合は計算プラグイン) がそれらをインスタンス化するプラグイン (GridGain プラグイン) に依存しているという事実に依存します。私のシナリオでは、そのような依存関係はありません。したがって、BuddyPolicy: registered を GridGain に追加し、RegisterBuddy: gridgain を計算プラグインに追加しても機能しません。

GridGain プラグインが計算プラグインからクラスを解決する唯一の方法は、GridGain を計算に依存するものとして明示的に定義することです。私の考えでは、それは必要ないはずです。計算プラグインが存在する場合、GridGain がそこからクラスをインスタンス化できるソフトな依存関係にする方法があるはずです。クラスローディングの問題が解決するように、この相互依存関係をモデル化する別の方法はありますか?

4

3 に答える 3

1

計算プラグインには、GridGain プラグインから何らかの依存関係があるはずです。依存関係を定義しない場合、GridGain は計算クラスにアクセスできません。これを考えて、共通のインターフェースを持つ別のプラグイン(ベースプラグイン)を作成し、GridGain と計算をベースプラグインに依存させることができます。ベース プラグインで定義するインターフェイスの計算プラグインで宣言型サービスを公開します。

GridGain プラグインでは、osgi を使用ServiceTrackerして、Calculations プラグインで公開されているサービスを待機します。

于 2012-10-18T22:26:48.183 に答える
1

パッケージをインポートせずに別のバンドルからクラスをインスタンス化する安全な方法が 2 つあります。

ほとんどの場合、既知のインターフェイスの実装が必要です。この場合の良いスタイルは、impl を認識し、OSGi サービスなどを使用して公開するバンドル内のクラスのファクトリを作成することです。ファクトリ内では、new を使用してクラスをインスタンス化できます。

もう 1 つの方法は、impl を認識しているバンドルのクラスローダーを使用することです。この場合、他のバンドルのクラスローダーを取得できるインターフェースを使用する必要があります。次に、クラスをその名前でロードするだけです。

于 2012-10-19T06:06:19.373 に答える
1

あなたはできる:

  1. 計算プラグインへの依存をオプションにします。

  2. パッケージ名が事前にわかっている場合は、Import-Package代わりに(これも省略可能です)を使用します。Require-Bundle

  3. を使用DynamicImport-Packageしますが、これはほとんどの場合避けるべきです。

于 2012-10-19T09:11:06.903 に答える