On-the-fly class reloading in java

Problem of redeploying during development

During development time of any web based java project the biggest headache for the developers is redeploying the code base to the server every time they make any change.
When a developer frequently makes small changes to an application with a long start up time that slows down the development process and especially if the project is using remote machine to de development, it takes considerable time to do redeployment.
It has been found in several statistical studies that in average 15 mints time get wasted by the developers in every 1hr to redeploy/publish their change. Which is ¼ th of the development effort. Thus minimizing this wastage of time development productivity can be enhanced significantly.
In this blog some of the techniques/tools have been discussed to show how this problem can be resolved or minimized to increase the productivity of the development team.
In this article I will discuss such technologies that enable the developers to, resume it directly from where it was suspended instead of stopping and restarting the server, after modifying and compiling the program.

Normal process in development environment

The normal process a developer follows after making any change in the java files of the workspace to make it available to the server, build the project and then publish the project.

Build

Build command is responsible for compiling the java source code and generating classes. The java builder is notified of changes to the resources in a workspace and can automatically compile java code.

Publish

Publishing involves copying files (projects, resource files, and server configurations) to the correct location for the server to find and use those.
Hence every time developer changes the code in workspace , these two above steps need to be performed,though the build process does not take much time but the publish process may be time consuming.

Understanding certain key concept:

Before going to explore different way to solve the problem lets discuss some key concept that will make it easier to understand that how the problem is handled by different tool/technique.

Java class loader

Class loaders are a fundamental module of the Java language. A class loader is a part of the Java virtual machine (JVM) that loads classes into memory; a class loader is responsible for finding and loading class files at run time.
Java class loaders do not have any standard mechanism to undeploy or unload a set of classes, nor can they load new versions of classes. In order to make updates to classes in a running virtual machine, the class loader that loaded the changed classes must be replaced with a new class loader.

Web Module Class loader

Web module class loaders load the contents of the WEB-INF/classes and WEB-INF/lib directories. Web module class loaders are children of application class loaders. Each class loader is a child of the previous class loader. That is, the application module class loaders are children of the WebSphere extensions class loader, which is a child of the CLASSPATH Java class loader. Whenever a class needs to be loaded, the class
loader usually delegates the request to its parent class loader. If none of the parent class loaders can find the class, the original class loader attempts to load the class. Requests can only go to a parent class loader; they cannot go to a child class loaderclass loader

JVM

A JVM provides a run-time environment in which Java bytecode can be executed. The JVM loads classes and other resources into the classpath exactly once (unless running in debug mode) from the directories or Jars specified in the CLASSPATH environment variable using classLoader. Once a resource has been loaded by a ClassLoader instance, it remains in memory until the ClassLoader is garbage collected.Class loader1

Different approaches/technique/tools as solution

In this section I will discuss on certain technique and tools that can be used to minimize the redeployment during development time.

Jrebel

JRebel is the most popular tool in this area, that lets Java developers instantly update code (i.e. add a new feature, fix a bug, etc) and see those changes reflected in their application under development without restarting the application server.

How Jrebel works:

JRebel uses “Rebellion Technology” to instantly reload changes made to a class structure, making a full application redeploy unnecessary. JRebel uses class rewriting and JVM integration to version individual classes. Plus it integrates with application servers to redirect class/resource and web server lookups back to the workspace

Jerebel Plug-in support for IDE: Jrebel provides plug-in for the following IDE

Eclipse
MyEclipse
IntelliJ IDEA
NetBeans
RAD and RSA
JDeveloper
JRebel supports various app servers/containers
Oracle WebLogic
WebSphere
Tomcat
JBoss
GlassFish
Jetty
Resin
Google AppEngine
SAP NetWeaver
SpringSourceDM Server (Eclipse Virgo)
Oracle OC4J
Mulesoft tcat server

Installation of plug-in and use:
Showing step by step installation process is out of the scope of this document but below is the url that provides information regarding installation process.

Jrebel for Eclipse

Jrebel for NetBeans

Dynamic Code Evolution VM

DCE is a technique a programmer can use to modify his Java application without restarting directly during runtime. In Debugging Mode this is a very interesting capability because modifications can be tested immediately without restarting the whole application. This increases productivity, especially in large projects.
DCE, is based on the Java HotSpot VM, which already gives the flexibility to swap methods on classes during runtime. DCE is extending this basic functionality and pushing it further by making it possible to add and remove methods and fields to classes. It is also possible to modify supertypes , add/remove and use completely new classes and so forth.

Following section describes some changes that developers frequently make on existing classes and how JVM responds to those changes.

Swapping Method Bodies:
Replacing the bytecodes of a Java method is the simplest possible change. No other bytecodes or type information data depend on the actual implementation of a method. Therefore, this change can be done in isolation from the rest of the system.

Adding or Removing Methods:
When changing the set of methods of a class, the virtual method table that is used for dynamic dispatch needs to be modified. Additionally, a change in a class can have an impact on the virtual method table of a subclass .
The virtual method table indexes of methods may change and make machine invalid Machine code can also contain static linking to existing methods that must be invalidated or recalculated.

Adding or Removing Fields:
Previous two example changes only affected the metadata of the VM. Now the object instances need to be modified according to the changes in their class or superclasses. The VM needs to convert the old version of an object to a new version that can have different fields and a different size. Similarly to virtual method table
indexes, field offsets are used in various places in the interpreter and in the compiled machine code. They need to be correctly adjusted or invalidated.

How it works
The technique is implemented by modification to the Java HotSpot VM, with an interpreter and two just-in-time compilers( on client compiler and one server compiler). The implementation is based on the exist-ing mechanism for swapping method bodies and extends it to allow arbitrary changes to loaded types. The approach focuses on implementing code evolution in an existing VM while keeping the
necessary changes small.First, the algorithm finds all affected classes and sorts them based on their subtype relationships. Then, the new classes are loaded and added to the type universe of the VM forming a side universe. A modified full garbage collection performs the actual version change. After invalidating state that is no longer consistent with the new class versions, the VM continues executing the program.

Below figure gives an overview of the modifications to the VM that are described in the following subsections.DCE VM

Finding effected types
When applying more advanced changes than just swapping method bodies, classes can be indirectly affected by the redefinition step. A field added to a class is implicitly also
added to all its subclasses. Adding a method to a class can have effects on the virtual method tables of its subclasses.
Therefore, the algorithm needs to extend the set of redefined classes by all their subtypes.

􀀀 Build side universe
This technique keeps both the old and the new classes in the system. This is necessary to be able to keep executing old code that depends on properties of the old class. It would also open the possibility to keep old and new instances in parallel on the heap. Additionally, it is the only way to solve the problem of cyclic dependencies between code evolution changes.

􀀀 Swapping pointers
When updating a class C to C’ it must be ensured that all instances of class C are updated to be instances of class C’. The instance of an object on the heap contains a reference to its class. The Java HotSpotTM VMdoes not keep track of the instances of a given class, therefore a heap traversal is necessary to find all existing instances.
Additionally, other parts of the system (e.g., native code) can have references to the old class that need to be updated too.

􀀀Updating Instance
For updating instances, a strategy is required to initialize the fields of the new instance. This technique uses a simple algorithm that matches fields if their name and type are the same. For the matching fields, values from the old instance to the new instance are copied. All other fields are initialized with 0, null, or false.
The information is calculated once per class and temporarily attached to the class meta object. The modified garbage collector reads the information and performs the memory copy or clear operations for each instance.

Installation
Showing step by step installation process is out of the scope of this document but below is the url that provides information regarding installation process.

DCE VM installation

Conclusion

Though DCE and tools like JavaRebel provides the same functionality to developers. But there are differences of both provide their service. While JavaRebel hooks into an existing VM, DCE itself is a VM which makes it possible to do a lot of modification during runtime while debugging an application.
But at the end of the day both increases developer productivity, by saving a lot of time.

Leave a comment