javassist Getting Started
Published: 2019-04-09

javassist Basic Functions

Javassist is a dynamic class library that can be used to check, "dynamic" modifications and create Java classes.Its function is similar to jdk's own reflection function, but it is more powerful than reflection function.

Important Classes

ClassPool:javassist's class pool. using the ClassPool class, you can track and control the classes you operate. its working method is very similar to JVM class loader.
CtClass: CtClass provides methods for checking class data (such as fields and methods) and adding new fields, methods and constructors to classes, as well as changing classes, parent classes and interfaces.However, Javassist does not provide any way to delete fields, methods, or constructors in a class.
CtField: used to access domains
CtMethod: used to access methods
CtConstructor: used to access constructors

syntax

The code written with javassist is not completely consistent with java code. The main difference is that javassist provides some special markers (beginning with) to represent methods, constructor parameters, method return values, etc.Example: system.out.println ("argument1:"+beginning), used to represent methods, constructor parameters, method return values, etc.
Example: system.out.println ("argument1:"+1);Where $1 represents the first parameter.

example

java class methods can be modified through javassist to modify their implementation.As follows:

      ClassPool classPool = ClassPool.getDefault();
      CtClass ctClass = classPool.get("org.light.lab.JavassistTest");
      CtMethod ctMethod = ctClass.getDeclaredMethod("test");
      ctMethod.setBody("System.out.println(\"this method is changed dynamically!\");");
      ctClass.toClass();

The above method is to modify the implementation of a method. When ctClass.toClass () is called, the modified class will be loaded and instantiated by the current ClassLoader.

complete code:

public class ChangeDemo {

  public static void main(String[] args) throws NotFoundException, CannotCompileException {
       replaceMethodBody("foo.Student", "execute", "System.out.println(\"this method is changed dynamically!\");");
       Student student = new Student();
       student.execute();
   }

public static void replaceMethodBody(String clazzName, String methodName, String newMethodBody) {
    try {
        CtClass clazz = ClassPool.getDefault().get(clazzName);
        CtMethod method = clazz.getDeclaredMethod(methodName);
        method.setBody(newMethodBody);
        clazz.toClass();
    } catch (NotFoundException | CannotCompileException e) {
       throw new RuntimeException(e);
    }
}

}

Limitations and Limitations

  • It should be noted that this class will be loaded when calling ctClass.toClass (). If this class has been loaded before, a duplicate load error will be reported, indicating that a class cannot be loaded repeatedly.Therefore, the implementation of the modified method must be carried out before the modified class is loaded.
  • Cannot access local variables outside the block.If a code segment is added at the beginning and end of a method, the variable in the code segment at the beginning of the method cannot be accessed in the end block of the method (the less perfect solution is to rename the original method and then add a method with the same name as the original method).

and aspectj

Using aspectj can also achieve the effect of modification, but modifying the specified class requires adding an aspect to modify the class, and then adding the aspect to the configuration file to make it effective. Compared with javassist, modifying a class or using javassist is relatively simple.

Classpath in container

In containers such as tomcat, user-defined classes cannot be obtained through ClassPool.getDefault (), which can be obtained through the following methods:
pool.insertClassPath(new ClassClassPath(this.getClass()));
Or:
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(“/usr/local/javalib”);

References:

http://www.ibm.com/developerworks/cn/java/j-dyn0916/
http://jboss-javassist.github.io/javassist/tutorial/tutorial.html