0

「プレーンな」Java、Equinox、および 2 つの間の通信の組み合わせである問題に直面しています。私は他の関連する質問 (ここここ、およびそこ、およびこのサイトやそのサイトなどの他の Web サイト)を読みましたが、満足のいく (または機能する) 解決策を見つけることができませんでした。

プラグインのセットがあります: P1、P2、および P3。P1 は、P2 で使用されるいくつかのクラスをエクスポートします。P2 はさらに、P3 で使用される他のクラスとインターフェイスをエクスポートします。特に、P2 はインターフェース MyInterfaceを定義してエクスポートし、その実装クラス MyInterfaceImpl は MyInterfaceを実装します。P3 はアプリケーションであるため、 IApplication を実装するクラス Launcherを含み、パブリック オブジェクトの start(IApplicationContext)メソッドを定義します。すべてが正常にコンパイルされます。Launcher を Eclipse から Eclipse アプリケーションとして実行すると、正常に動作します。ランチャーはMyInterfaceMyInterfaceImplをうまく使います。

さて、さまざまな投稿によると、次の (単純な) コードを使用してプログラムでアプリケーションを実行します。

void callApplication() {
    final String[] args =
        new String[] {
            "-application",
            "Launcher",
            ... };
    EclipseStarter.run(args, null);
}

繰り返しますが、このコードは問題なく動作し、アプリケーションの実行を「確認」して、期待どおりの結果を生成できます。

さて、ここで問題が発生します。Equinoxで実行されているアプリケーションによってビルドされた MyInterfaceImpl のインスタンスを、「外側の」Java コード内に戻して取得したいと考えています。私の素朴な解決策は、このオブジェクトをpublic Object start(IApplicationContext)メソッドで返し、呼び出しコードを次のように変更することでした。

MyInterface callApplication() {
    final String[] args =
        new String[] {
            "-application",
            "Launcher",
            ... };
    return (MyInterface) EclipseStarter.run(args, null);
}

しかし、この単純な解決策は機能しません。java.lang.ClassCastException: MyInterfaceImpl を MyInterface にキャストできません。考えてみると、 callApplication() の最後に { MyInterface , MyInterfaceImpl } のペアの 2 つの「バージョン」があるため、それは理かなっます。Equinox からの別のもので、Equinox クラスローダーによってロードされます。返されたオブジェクトとMyInterfaceのクラスローダーを出力するようにコードを変更しました。

final Object o = EclipseStarter.run(args, null);
System.out.println(o.getClass().getClassLoader());
System.out.println(MyInterface.class.getClassLoader());

そして、確かに、私は得ました:

org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@7e66458c[P2:1.5.0(id=413)]
sun.misc.Launcher$AppClassLoader@1efc3d2

P2 はMyInterfaceMyInterfaceImplを定義およびエクスポートするプラグインであるため、返されたオブジェクトのクラスローダーは、予想どおり P2 に由来すると言われていることに注意してください。

{ MyInterfaceMyInterfaceImpl }の「互換性のある」ペアを取得するさまざまな方法を試しましたが、これまでのところ運がありません (常に同じjava.lang.ClassCastException: MyInterfaceImpl を MyInterface にキャストできません)。

  • プロパティを設定してみました -Dorg.osgi.framework.bootdelegation=* -Dorg.osgi.framework.system.packages.extra=MyInterface,MyInterfaceImpl.

  • また、start()メソッドでDefaultClassLoaderを傍受しようとしました。

だから、私の質問は次のとおりです。プラグインでもあり、これらのクラスをエクスポートするプロジェクトで定義されたいくつかのクラスを使用するJavaプログラムが、これらのクラスのインスタンスをプログラムで開始されたEclipseのインスタンスと交換する方法はありますか? ありがとう!

4

1 に答える 1

1

ああ、これはトリッキーです。アプリケーションを再設計し、すべてにプラグインを使用することをお勧めしますが、それはあなたの質問には答えません.

さて、あなたがしたいことは、最初にインターフェース定義フォーム P2 を削除し、元の (OSGi 以外の) JAR に、できればそれ自体のパッケージに追加することcom.example.apiです。-Dorg.osgi.framework.system.packages.extra=com.example.api次に、 ;を追加します。また、そのパッケージの P2 と P3 にインポートを追加します。

お役に立てれば。

于 2013-08-06T18:14:47.827 に答える