私は、クライアントがテキスト ファイルのリストを提供できるようにするライブラリを持っています。各ファイルには、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 を解析するケースを想像できるため、疑問は依然として残ります。