Dynamic Code Evolution for Java
Architect at hama GmbH & Co, Marc Teufel, explains how Dynamic Code Evolution can increase developer productivity.
Dynamic Code Evolution (DCE) increases developer productivity by allowing developers to make changes to an application during runtime. If you compare DCE with JavaRebel, you may be wrong. We will show you why.
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 capbility because modifications can be tested immediately without restarting the whole application. This increases productivity, especially in large projects where start and initialization of an application takes time.
DCE versus JavaRebel?
If you know the commercial tool JavaRebel from Zero Turnaround,
you may think that DCE sounds the same – but it isn’t. Both
products differ in a technical matter, as well as in daily usage.
While JavaRebel integrates into a running Java virtual machine with
a parameter named
-javaagent, DCE itself is a modified virtual machine. DCE, in fact, is based on the Java HotSpot VM, which already gives you a chance to swap methods on classes during runtime. DCE is extending this basic functionality and pushing it to the max by making it possible to add and remove methods and fields to classes. You can modify supertypes , you can add, remove and use completely new classes and so forth.
There are also plans to bring DCE into production environments on servers. This would give you the chance to replace a complete application or only small parts of it – during runtime! You could also use DCE in an aspect-oriented kind of way, for example adding further logging methods before, and after, specific methods in your application classes would be no problem. But for the moment, these are just possibilities for the future.
The DCE maintainers recommend to install the software on developer machines only. It is stable enough for developing and debugging applications, but currently it’s too early to use on production servers. DCE is available as a 32- and 64bit Windows version, but for Mac OS X and Linux you can only get 32bit versions . To install DCE you can use a simple installer, which is included in the downloaded file. Requirements for installing DCE are less, you only need to have a JRE or JDK installed on your machine; that’s all! Starting the installer is quite simple:
sudo java -jar dcevm-020.jar
Make sure to start the installer with root permissions. In the first step, the installer (Figure 1) will list all the Java-Installations on your system, alternatively you can manually add Java-Installations by pressing the “Add installation directory…” button. On the list (Column DCE) you can see if DCE has been already installed into a specific Java installation. During installation, the file jvm.dll will be replaced with the DCE-version in the sub directories bin/client and bin/server. From the original file, a backup will be made. Finally, the file dcevm.jar will be copied into the directory lib/ext of your Java installation (important for Mixins). To check if the installation was successful, you can press the button “Test installation” in the installer or you can do a java –version on the command line, this will show you the version of Java itself and DCE (Figure 2).
Try it out
Now you can swap or modify classes during runtime, it’s important at this point that you start your application in Debug Mode. Next, we will show how to use DCE with the Eclipse RCP Mail-Template. After creating the RCP Mail-Project from within the IDE, the first thing you have to do is to start it in the Debugger. If you click the Plus-Symbol in the toolbar of the application, a new instance of the View-class will be generated and displayed. If you change this view now, for example, changing the line of code where the subject of the shown mail is handled, this change will be active as soon as you save the modified source code file. Check it by repressing the Plus-Symbol, and you will see the changed subject. But remember, this will only work if your application remains running in debug mode. The next question is, will this also work if we add a completely new class to the project? Let’s try it by adding a new class called TestDialog, which is extending from TitleAreaDialog (see sample in Listing 1).
In order to activate this new dialog, we use the second Button in the Toolbar. If you press this button, the MessagePopupAction class will be executed, so we must do a small modification here (Listing 2) to bring our new dialog into action. If you do all this while the RCP Mail Template remains in the debugger, the new dialog class will be available immediately.
As you can see, programming this way in combination with DCE can speed up your development and save you time, as you no longer have to keep restarting your app.
Another interesting feature, besides modifying parts of the application during debugging, is the option to use an API provided by DCE to modify classes dynamically during runtime. This means an application is able to modify itself! In DCE this is called Mixins, on the website you’ll find an example, including some documentation to get you started. The basic idea with Mixins is that DCE provides an addMixin-Method in order to add functionality to an existing class. It’s possible to call this method as often as needed. In order to get Mixins working, you must activate DCE with the –javaagent switch like this:
In the end you can compare DCE with JavaRebel but if you look deeper, there are differences. 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. This increases developer productivity, by saving you a lot of time. In the future, it is planned to also use DCE on servers, so that it’s possible to do modifications or replacements on production systems without stopping or restarting the whole system. Last but not least, DCE provides the Mixins-API, another interesting approach to modifying an application during runtime.