Explore Java hot deployment in depth

Source: Internet
Author: User
Tags modify

Brief introduction

In the Java development field, hot deployment has always been a difficult problem, the current Java virtual machine can only implement the modification of the method body hot deployment, for the entire class structure modification, still need to restart the virtual machine, the class reload to complete the update operation. For some large applications, each reboot will cost a lot of time. Although the presence of OSGi architectures makes it possible for modules to be restarted, such operations can still cause transient functional shock in applications if there is a call between the modules. This article explores how to implement a one-class hot deployment without disrupting the existing behavior of the Java virtual machine so that the system completes a class update without restarting.

The exploration of class loading

First, let's talk about hot deployment (HOTSWAP), which is the ability to automatically detect changes in class files and update run-time class behavior without restarting the Java virtual machine. Java classes are loaded through a Java virtual machine, and a class file that is loaded by ClassLoader generates a corresponding class object, and then an instance of the class can be created. The default virtual machine behavior only loads the class at startup, and if a later class needs to be updated, simply replace the compiled class file, and the Java virtual machine will not update the running class. If you want to achieve hot deployment, the most fundamental way is to modify the source code of the virtual machine, change the loading behavior of the ClassLoader, so that the virtual function listening to the class file update, reload class file, such behavior is very destructive, for subsequent JVM upgrades buried a big pit.

Another friendly approach is to create your own classloader to load the class that needs to be monitored, so that you can control the timing of classes loading to achieve hot deployment. This article will specifically explore how to implement this scheme. First you need to understand the existing loading mechanism of the Java virtual machine. The current loading mechanism, called parental delegation, when the system uses a classloader to load a class, asks the current ClassLoader whether the parent class is capable of loading, and if the parent cannot implement the load operation, the task is delegated to the ClassLoader to load. The advantage of this top-down loading approach is that each classloader performs its own load task and does not repeat the load class. However, this approach makes the loading sequence very difficult to change, allowing custom ClassLoader to preempt classes that require monitoring changes becomes a challenge.

But we can change the idea that although we can't load the class first, we can still use custom ClassLoader to create a class with the same functionality, so that each instantiated object points to the new class. When this class file changes, create an updated class again, and then if the system sends out an instantiated request again, the object that is created speaks to the new class.

Here's a quick list of the things you need to do.

Create a custom ClassLoader, load the class that needs to listen for changes, and reload the class file when it changes.

Change the behavior of creating objects so that they are created with a custom ClassLoader loaded class.

Implementation of custom Loader

The custom loader still needs to perform the function of class loading. There is a problem here, the same class loader cannot load two classes with the same name at the same time, because regardless of how the class structure changes, the generated class name does not change, and ClassLoader can only destroy the loaded class before the virtual machine stops, so ClassLoader cannot load the updated class. Here's a trick to keep each loaded class as a class with version information, such as when loading Test.class, the class stored in memory is Test_v1.class, and when the class changes, the reload class name is Test_v2.class. But the DefineClass method of actually performing loading class file creation class is a native method, and it becomes difficult to modify. So there is still a road left, that is, directly modify the build generated class file.

Modifying class files with ASM

There are a number of frames that can modify bytecode, such as Asm,cglib. The ASM is used in this article. First to introduce the class file structure, class file contains the following types of information, one is the basic information of the class, including access rights information, class name information, parent class information, interface information. The second is the variable information for the class. The third is the information of the method. ASM first loads a class file and then reads the class's information in strict order, and the user can define the enhanced component to modify the information as he wishes, and finally output it as a new class.

First look at how to use ASM to modify class information.

Listing 1. Using ASM to modify byte code

Classwriter cw = new Classwriter (CLASSWRITER.COMPUTE_MAXS); 
Classreader CR = null;     
String enhancedclassname = Classsource.getenhancedname (); 
try { 
    cr = new Classreader (new FileInputStream ( 
            classsource.getfile ()); 
} catch (IOException e) { 
    E.printstacktrace (); 
    return null; 
} 
Classvisitor CV = new Enhancedmodifier (CW, 
        classname.replace (".", "/"), 
        enhancedclassname.replace (".", "/" )); 
Cr.accept (CV, 0);

ASM modifies bytecode file's process is a responsibility chain pattern, first uses one classreader to read into the bytecode, then uses the classvisitor to make the personalization modification, finally utilizes the Classwriter output to revise the byte code.

As mentioned earlier, you need to make some modifications to the class name of the read class file, and load it into a new name derived class. This is divided into 2 steps.

The first step is to first turn the original class into an interface.

Listing 2. The original class that was redefined

   Public class<?> Redefineclass (String className) { 
       Classwriter cw = new Classwriter (CLASSWRITER.COMPUTE_MAXS) ; 
       Classreader CR = null; 
       Classsource cs = classfiles.get (className); 
       if (cs==null) {return 
           null; 
       } 
       try { 
           cr = new Classreader (New FileInputStream (Cs.getfile ()); 
       } catch (IOException e) { 
           e.printstacktrace (); 
           return null; 
       } 
       ClassModifier cm = new ClassModifier (CW); 
       Cr.accept (cm, 0); 
       byte[] Code = Cw.tobytearray (); 
       Return DefineClass (className, code, 0, code.length); 
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.