Groovyで動的にクラスをロード、再読み込み
基本な仕組みはJavaのクラスローダの場合と同じ(はず)。
基本クラスローダ(ブートストラップ、エクステンション、システム)
システムクラスローダは、クラスパス上のクラスを読むローダ。
クラスパス上に存在するクラスはシステムクラスローダで読まれてしまうので、動的にロード、リロードする場合は、該当クラスをクラスパスに含めないようにし、自前のクラスローダでロードするようにする。
Groovyで用意されているクラスローダは、java.net.URLClassLoaderを継承したGroovyClassLoaderというクラス。
def loader = new GroovyClassLoader()
動的にロードしたいクラスは後からロードするが、そのクラスが参照するクラスがCLASSPATHに含まれていない場合、Loaderにクラスパスを追加する。
loader.addClasspath(xxxx)
クラスの読み込んでインスタンスの取得。
def obj = loader.parseClass(new File("/path/to/Foo.groovy")).newInstance()
parseClassで読まれたクラスはキャッシュされる。
groovyスクリプトを書き換えを行い、GroovyのVMを再起動なしで変更を反映したい場合に再度parseClassを呼んでも、このキャッシュのため、変更が反映されない。
loader.clearCache()
を呼ぶとキャッシュがクリアされ、その後のparseClass呼び出しで実際に読まれるようになった。
#parseClassの第二パラメータのbool値でキャッシュするかの指定をできるはずだが、手元ではうまく反映されなかたので、clearCache()を使った。
上記は同一のローダで再読み込みする方法で、Javaのようにローダのインスタンスごと使い捨てて新しいローダのインスタンスで読みむ方法でも実現は可能。