I am creating a class file at runtime.
I want to replace an existing class file with an updated one in the class loader.
It looks like a hot swap (for example, JRebel), which avoids rebooting and reinstalling the server.
I found the context.xml approach for tomcat to overload the context. But this is not very useful in the case of a production environment.
Is it possible to register a class with ClassLoader at runtime? Please suggest if there is any alternative to reloading the class at runtime.
I am using the following code to retrieve the current classLoader.
ClassLoader classLoader = LoggingAspect.class.getClassLoader();
The following is the implementation of the load class method.
public class AspectClassLoader extends ClassLoader{ @Override public synchronized Class<?> loadClass(String name) throws ClassNotFoundException { String customLoadClass = "com.log.LoggingAspect"; try { if(!customLoadClass.equals(name)) { return super.loadClass(name); } else { URL classLoadUrl = new URL(this.reloadClassUrl); URLConnection connection = classLoadUrl.openConnection(); InputStream input = connection.getInputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int data = input.read(); while(data != -1){ buffer.write(data); data = input.read(); } input.close(); byte[] classData = buffer.toByteArray(); return defineClass(name, classData, 0, classData.length); } } catch(Exception e) { e.printStackTrace(); } return null; }
To reload the class, I use the following code.
AspectClassLoader urlClsLoader = new AspectClassLoader(classLoader); Class aspect = urlClsLoader.reloadClass("com.log.LoggingAspect", true, new String("file:"+className));
My method of reloading the class loader
public synchronized Class<?> reloadClass(String name, boolean resolve, String reloadClassUrl) throws ClassNotFoundException { this.reloadClassUrl = reloadClassUrl; return this.loadClass(name, resolve); }
After rebooting, if I create a new instance of LoggingAspect, it still gives me the old instance. Please suggest.
Class aspect = urlClsLoader.reloadClass("com.log.LoggingAspect", true, new String("file:"+className)); com.log.aspect.Aspect aspectObj = (com.log.aspect.Aspect)aspect.newInstance();
However, I get the old instance.
Indicate why the class loader does not load the modified class?