Closing a URLClassLoader

Guest Author
By Michael McMahon

Complex Java programs, such as application servers, sometimes create their own class loaders using the URLClassLoader type. With URLClassLoader, applications can load classes and resources from a search path of URLs. The following URL types are supported:

  • file: (loads from file-system directories)
  • jar: (loads from JAR files)
  • http: (loads from http servers)

A frequent problem has been how to support updated implementations of the classes and resources loaded from a particular codebase, and in particular from JAR files. In principle, once the application clears all references to a loader object, the garbage collector and finalization mechanisms will eventually ensure that all resources (such as the JarFile objects) are released and closed.

The application can then replace the JAR file, and create a new URLClassLoader instance to load from the same location, but this time using the new implementation of the classes/resources.

However, since it can't be predicted exactly when finalization and garbage collection will occur, this causes problems for applications which need to be able to do this in a predictable and timely fashion. It is a particular problem on Windows, because open files cannot be deleted or replaced.

To alleviate this problem, URLClassLoader has acquired a new method called close(). It has been implemented since Build 48 of JDK7.

The close() method effectively invalidates the loader, so that no new classes can be loaded from it. It also closes any JAR files that were opened by the loader. This allows the application to delete or replace these files and, if necessary, create new loaders using new implementations.

The new method follows the familiar "Closeable" pattern, and URLClassLoader now implements the Closeable interface, which defines URLClassLoader.close(). The following sample code shows how one might use the method.

// 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();
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

Michael McMahon is an engineer at Sun Microsystems. He works in the Java Security, Networking, and Libraries group.

Join the discussion

Comments ( 5 )
  • binvij Tuesday, March 17, 2009

    This is a much wanted feature. Thanks !

    I was wondering if this feature can be used for unloading JNI dll inside a jar file which I am calling from a custom URLClassLoader ? Since as of now the ClassLoader does not have a direct method to unload a native dll, i was hoping this can make it easier !

  • Ashish Laddha Thursday, March 19, 2009

    We have a typical problem. Let's say I am working on development of some java files as a part of development of an application. Let's say the application runs on a J2EE webserver. I start the server and change a java file. In order for the server to pick up the updated file, I need to restart the server. Can jvm be told to reload the class file or unload a particular class file so that it picks up the newly updated class file when required?

  • Alexander Masyura Thursday, March 19, 2009

    This new functionality is very useful. Thanks.

  • Michael McMahon Friday, March 20, 2009

    In reply to binvij. Without knowing the details of your extension to URLClassLoader, I would say it should be possible in principle. If you override the close() method, and do whatever specialised clean up is needed there, and then call super.close(), that will close the jar file.

    In reply to Ashish, you would need to address that question to the application server, but this functionality may help them to provide what you are looking for.

  • Fotobuch Friday, May 1, 2009

    Perhaps close functions needs an isClosed() function?

Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.