4

現在、.Net 4 C# Web サイト内からGephi Toolkitを読み込んで使用しようとしています。

IKVM 仮想マシンに対してコンパイルされたバージョンのツールキット jar ファイルがあります。これは、次のコードを使用してコマンド ライン アプリケーションから期待どおりに動作します。

var controller = (ProjectController)Lookup.getDefault().lookup(typeof(ProjectController));
controller.closeCurrentProject();
controller.newProject();
var project = controller.getCurrentProject();
var workspace = controller.getCurrentWorkspace();

3 つのインスタンスは、 のような形式で正しくインスタンス化されますorg.gephi.project.impl.ProjectControllerImpl@8ddb93

ただし、まったく同じ using ステートメントと参照を使用してまったく同じコードを実行すると、ProjectControllerインスタンスをロードする最初の行で null が返されます。

私はいくつかの解決策を試しました

まず、Lookup.getDefault().lookup(type) 呼び出しを無視して、代わりに独自のインスタンスを作成しようとしました。

var controller = new ProjectControllerImpl();
controller.closeCurrentProject();
controller.newProject();
var project = controller.getCurrentProject();
var workspace = controller.getCurrentWorkspace();

これは controller.newProject(); の行で失敗します。内部的に (リフレクターを使用して) 同じ Lookup.getDefault().lookup(type) がコンストラクターで使用され、null を返し、例外をスローするためだと思います。

次に、ここから: Jython (および Gephi) でのルックアップ%CLASSPATH% をツールキットの JAR ファイルと DLL ファイルの両方の場所に設定しようとしました。

Lookup.getDefault().lookup(type) が Web 環境で機能しない理由はありますか? 私は Java 開発者ではないので、Java 側については少し詳しくありません。

すべてのインスタンスを自分で作成することは可能だと思っていましたが、その方法を見つけることができませんでした。

また、ProjectController の読み込みが null を返した理由を確認する方法も見つかりません。例外はスローされません。私が非常にばかでない限り、試行されたロードの結果を確認する方法はないようです。

更新 - 回答

Jeroen Frijters からの回答に基づいて、次のように問題を解決しました。

public class Global : System.Web.HttpApplication
{
    public Global()
    {
        var assembly = Assembly.LoadFrom(Path.Combine(root, "gephi-toolkit.dll"));
        var acl = new AssemblyClassLoader(assembly);
        java.lang.Thread.currentThread().setContextClassLoader(new MySystemClassLoader(acl));
    }
}

internal class MySystemClassLoader : ClassLoader
{
    public MySystemClassLoader(ClassLoader parent)
        : base(new AppDomainAssemblyClassLoader(typeof(MySystemClassLoader).Assembly))
    { }
}

コードikvm.runtime.Startup.addBootClassPathAssemby()はうまくいかないようでしたが、提供されたリンクから、すべてのインスタンスでうまくいくと思われる解決策を見つけることができました。

4

1 に答える 1

0

これは Java クラス ローダーの問題です。コマンド ライン アプリでは、メインの実行可能ファイルはシステム クラス ローダーとして機能し、アセンブリの依存関係を読み込む方法を知っていますが、Web プロセスではメインの実行可能ファイルがないため、システム クラス ローダーは有用なものを読み込む方法を知りません。

解決策の 1 つは、ikvm.runtime.Startup.addBootClassPathAssemby() を呼び出して、関連するアセンブリをブート クラス ローダーに追加することです。

IKVM クラスのロードに関する問題の詳細については、http: //sourceforge.net/apps/mediawiki/ikvm/index.php?title=ClassLoader を参照してください。

于 2012-11-22T07:44:14.617 に答える