2

私は、クライアントがテキスト ファイルのリストを提供できるようにするライブラリを持っています。各ファイルには、Java クラス Z を拡張するクラスの groovy コードが含まれています。たとえば、ファイル 'A.groovy' には

package com.mypkg;

public class A extends Z {

    @Override
    public void someMethod() {

        // do something A-ish

    }
}

ライブラリはこれらのそれぞれをコンパイルし、(この場合) Z 型のインスタンスをクライアントに返します。

私の問題は、クライアントが次のようなものを必要とするときに発生します。

package com.mypkg;

public class B extends A {        // extends A!

    @Override
    public void someMethod() {

        // do something B-ish instead of A-ish

    }
}

ここで、B は A を拡張し、クラス A はクラス B の前に解析されました。

問題は、GroovyClassLoader がクラス A を解析しただけなのに、クラス A を見つけられないように見えることです。スクリプトをコンパイルしてインスタンスを作成するコードを次に示します。

    for (String fileName : listOfScriptFiles) {

        InputStream in = getInputStreamFromFile(fileName);

        CompilerConfiguration compConfig = new CompilerConfiguration();
        GroovyClassLoader classLoader = new GroovyClassLoader(Thread.currentThread()
            .getContextClassLoader(), compConfig);

        Z service = null;

        Class clazz = classLoader.parseClass(in);
        service = (Z) clazz.newInstance();

        return service;
    }

クラスAをランタイムに「登録」して、GroovyがクラスBをコンパイルしようとしたときに、クラスAが存在しないと文句を言わないようにする方法はありますか?

アップデート

クライアントのコード リストを反復処理するループの外で GroovyClassLoader をインスタンス化することで、実際にこれを解決できたので、A を解析するクラスローダーは B を解析するクラスローダーと同じです。

ただし、誰かのコードの一部で A を解析し、次に同じクラスローダーが利用できないまったく別の部分で B を解析するケースを想像できるため、疑問は依然として残ります。

4

1 に答える 1

0

Groovy クラスローダ (この点で Ant および beanshell のクラスローダと動作が似ています) に関する私の経験では、デフォルトのシステム クラスローダを使用するかどうかを前もって決定する必要があります。 Groovy スクリプトを起動するコマンド、または一方、コマンド ライン クラスパスで groovy jar のみを指定してから、カスタム クラスローダーの Groovy スクリプトの先頭にクラスを動的に追加します。

あなたの質問では多くの情報を提供していませんが、スクリプトを起動する前にクラス「A」をクラスパスに配置し、クラス「B」を動的にロードしようとしていると思います。私の知る限り、それはうまくいきません。

注:私自身、この種のことを行う方法を理解しようとしています。できそうですが、まだわかりません。

于 2012-04-30T18:01:21.087 に答える