Hot Class Reload of JAVA sources Example based on RelProxy!

As of Java 1.6 a Java compiler API is exposed to end developers and included in any JDK, in a standard Java EE web environment the compiler is accessible because the JDK is needed to recompile on the fly for instance JSPs

This opens the opportunity to make a hot class reload based on pure Java source code in a similar way to other dynamic languages... fast and avoiding the tedious context reload

So can I change Java source code and automatically reload it on the fly in runtime in production or development time?


RelProxy is a Java and Groovy hot class reloader library, in spite of it is a general purpose tool it was conceived to provide hot class reload to ItsNat.

This page is rendered by (compiled) Java source code included in the standard WAR file, of course into the WEB-INF folder if you need privacy of your code, this Java code can be modified and will be compiled and reloaded on the fly, reload the page and the new code will be executed.

A simple running example

Say something to hot reloaded Java classes:

You said:

Note: try changing the source code in runtime (template and Java code) to modify the behavior of this example and reload this page

The class JProxy is a Java class to provide a simple proxy for conventional Java objects, When JProxy is used, a java.lang.reflect.Proxy is passed instead of the original Java object, the original Java object is retained under the hood and method calls to the proxy are redirected to the real object calling the corresponding method using reflection, when the source code of the Java(s) class(es) changes.

JProxy automatically reloads the Java class and creates a new object to replace the old one, the fields of the original object are got and re-set to the new object to keep the state (number of fields and types must be the same otherwise reloading is not possible and a redeploy is required).

JProxy part of RelProxy is not so sophisticated like products like JRebel but it could dramatically reduce the number of redeploys in an ItsNat project.

With a simple boolean enabled param set to false in initialization time, JProxy does nothing and your original objects are returned instead of proxies with 0 performance penalty in production. If you still want to make hot changes in production, automatic detection of source code changes can be stopped to reduce footprint in production and started again in any time when we want make source code changes.

ItsNat, Java, JProxy and automatic reload

JProxy can easily be applied to an ItsNat project to provide a proxy instead of the original Java object when registering an ItsNatServletRequestListener associated to a page template. When a document (page) is loaded calling processRequest, JProxy re-creates this listener object if the source code of this object or any other dependent class has changed, and re-set all fields to restore the current state.

Field values injected to the class implementing ItsNatServletRequestListener are not (and must not be) reloaded to the new possible source, but cascade dependent classes usually creating new objects are automatically reloaded when executing processRequest, any new object created by processRequest is fresh with the last source and because registering in framework ItsNat classes happens after reloading no JProxy is needed.

This solution is not perfect because only affects to view-logic (not to classes of global objects provided to ItsNatServletRequestListener page loaders), that is, code for ItsNatDocument processing, anyway this is very much code.

This is an example of using a JProxy when registering a ItsNatServletRequestListener associated to a template for document loading:

ItsNatServletRequestListener listener = JProxy.create(new JProxyExampleLoadListener(db), ItsNatServletRequestListener.class);

How to test automatic reload in this example?

For instance change JProxyExampleDocument and jproxyex.html to change view logic, and reload this page, no redeploy is needed, no servlet context is reloaded, only Java classes are reloaded. The class JProxyExampleDocument contains an inner class, a member class (AuxMember) and using an external class JProxyExampleAux, change these classes with no problem. You can change also JProxyExampleLoadListener for instance to change the parameters provided to JProxyExampleDocument but do not add/remove/change its fields because this is the root class and instance managed by JProxy in this example and classes of the fields cannot be reloaded, for instance changes to FalseDB (a field of JProxyExampleDocument) are not automatically reloaded because FalseDB is not in the folder for class reload and trying to reload this class implies a field of JProxyExampleLoadListener has changed and reloading this class will fail.

In production time Java app servers usually extract deployed war files to internal folders, you can modify sources there.

UPDATE: As of ItsNat 1.4 RelProxy Java (JProxy) is built-in!

No more explicit JProxy.create() sentences, just configure RelProxy and your ItsNatServletRequestListener and EventListener listeners will be automatically reloadable if they are contained by reloadable classes! Read the ItsNat Manual for more info about RelProxy support.