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のようにローダのインスタンスごと使い捨てて新しいローダのインスタンスで読みむ方法でも実現は可能。