How to load a jar file at runtime

Amir Arad picture Amir Arad · Oct 11, 2008 · Viewed 154.6k times · Source

I was asked to build a java system that will have the ability to load new code (expansions) while running. How do I re-load a jar file while my code is running? or how do I load a new jar?

Obviously, since constant up-time is important, I'd like to add the ability to re-load existing classes while at it (if it does not complicate things too much).

What are the things I should look out for? (think of it as two different questions - one regarding reloading classes at runtime, the other regarding adding new classes).

Answer

Tom Hawtin - tackline picture Tom Hawtin - tackline · Oct 11, 2008

Reloading existing classes with existing data is likely to break things.

You can load new code into new class loaders relatively easily:

ClassLoader loader = URLClassLoader.newInstance(
    new URL[] { yourURL },
    getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
Class<? extends Runnable> runClass = clazz.asSubclass(Runnable.class);
// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();
doRun.run();

Class loaders no longer used can be garbage collected (unless there is a memory leak, as is often the case with using ThreadLocal, JDBC drivers, java.beans, etc).

If you want to keep the object data, then I suggest a persistence mechanism such as Serialisation, or whatever you are used to.

Of course debugging systems can do fancier things, but are more hacky and less reliable.

It is possible to add new classes into a class loader. For instance, using URLClassLoader.addURL. However, if a class fails to load (because, say, you haven't added it), then it will never load in that class loader instance.