URLClassLoaderのclose()メソッドを使用すると、特定のコードベース(特にJARファイル)からロードされた更新済みのリソースやクラスの実装をサポートする方法における問題を効果的に解決できます。 原則として、ローダー・オブジェクトに対するすべての参照がアプリケーションでいったん消去されると、ガベージ・コレクタとファイナライゼーション・メカニズムによって、最終的にすべてのリソース(JarFileオブジェクトなど)が解放され、終了されるようになっています。
次に、アプリケーションはJARファイルを置換して新しいURLClassLoaderインスタンスを作成します。しかし今回は、新しいクラスまたはリソースの実装を使用して、同じロケーションからロードを実行します。 しかし、ファイナライゼーションとガベージ・コレクションがいつ実行されるのかを明確に予測することはできないため、予測可能かつ適切なタイミングでこれを実行する必要のあるアプリケーションにとってはこれが問題になります。 Windowsでは開かれているファイルを削除したり置換したりすることはできないため、この問題はWindows上で発生します。
Java SE 7では、URLClassLoaderのclose()メソッドによってローダーが実質的に無効化されるため、ローダーから新たにクラスをロードすることはできません。 また、ローダーによって開かれたJARファイルも終了されます。 これによって、アプリケーションは必要に応じてこれらのファイルを削除または置換し、新しい実装を使用して新規ローダーを作成できるようになります。
close()メソッドは馴染みある"Closeable"パターンに従っており、URLClassLoaderでは、URLClassLoader.close()を定義するCloseableインタフェースが実装されています。 次のサンプル・コードは、このメソッドの使用方法を示したものです。
//
// create a class loader loading from "foo.jar"
//
URL url = new URL("file:foo.jar");
URLClassLoader loader = new URLClassLoader (new URL[] {url});
Class cl = Class.forName ("Foo", true, loader);
Runnable foo = (Runnable) cl.newInstance();
foo.run();
loader.close ();
// foo.jar gets updated somehow
loader = new URLClassLoader (new URL[] {url});
cl = Class.forName ("Foo", true, loader);
foo = (Runnable) cl.newInstance();
// run the new implementation of Foo
foo.run();
