dynamic class reload
- Use different child classloader to reload the class and create new instance
- Apply proxy pattern to delegate the invocation to new instance, so that changes to the dynamic class become transparent to its caller.
// The dir contains the compiled classes.
File classesDir = new File("/temp/dynacode_classes/");
// The parent classloader
ClassLoader parentLoader = Postman.class.getClassLoader();
// Load class "sample.PostmanImpl" with our own classloader.
URLClassLoader loader1 = new URLClassLoader(
new URL[] { classesDir.toURL() }, parentLoader);
Class cls1 = loader1.loadClass("sample.PostmanImpl");
Postman postman1 = (Postman) cls1.newInstance();
/*
* Invoke on postman1 ...
* Then PostmanImpl.java is modified and recompiled.
*/
// Reload class "sample.PostmanImpl" with a new classloader.
URLClassLoader loader2 = new URLClassLoader(
new URL[] { classesDir.toURL() }, parentLoader);
Class cls2 = loader2.loadClass("sample.PostmanImpl");
Postman postman2 = (Postman) cls2.newInstance();
/*
* Work with postman2 from now on ...
* Don't worry about loader1, cls1, and postman1
* they will be garbage collected automatically.
*/
The Java reflection API includes a handy utility for creating proxies. The class java.lang.reflect.Proxy provides static methods that let you create proxy instances for any Java interface.
InvocationHandler handler = new DynaCodeInvocationHandler(...);
Postman proxy = (Postman) Proxy.newProxyInstance(
Postman.class.getClassLoader(),
new Class[] { Postman.class },
handler);
public class DynaCodeInvocationHandler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Get an instance of the up-to-date dynamic class
Object dynacode = getUpToDateInstance();
// Forward the invocation
return method.invoke(dynacode, args);
}
}
Reference link
No comments:
Post a Comment