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
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.
Note: try changing the source code in runtime (template and Java code) to modify the behavior of this example and reload this page
JProxy is a Java class to provide a simple proxy for conventional Java objects,
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.
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
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,
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); docTemplate.addItsNatServletRequestListener(listener);
For instance change
jproxyex.html to change view logic, and reload this page, no redeploy is needed, no servlet context is reloaded, only Java classes are reloaded.
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
JProxy in this example and classes of the fields cannot be reloaded, for instance changes to
FalseDB (a field of
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.
No more explicit JProxy.create() sentences, just configure RelProxy and your
EventListener listeners will be
automatically reloadable if they are contained by reloadable classes! Read the ItsNat Manual for more info about RelProxy support.