SlideShare a Scribd company logo
Having fun with Javassist
@antonarhipov
Me
Anton Arhipov
@antonarhipov
Me
Anton Arhipov
@antonarhipov
Javassist inside!
You?
You?
Are you interested in Javassist?
You?
Are you interested in Javassist?
Want to become a better programmer?
You?
Are you interested in Javassist?
Want to become a better programmer?
Bytecode instrumentation, anyone?
Riga Dev Day 2016 - Having fun with Javassist
@Entity

@Table(name  =  "owners")

public  class  Owner  extends  Person  {

        @Column(name  =  "address")

        @NotEmpty

        private  String  address;



        @Column(name  =  "city")

        @NotEmpty

        private  String  city;



        @Column(name  =  "telephone")

        @NotEmpty

        @Digits(fraction  =  0,  integer  =  10)

        private  String  telephone;



        @OneToMany(cascade  =  CascadeType.ALL,    
                              mappedBy  =  "owner")

        private  Set<Pet>  pets;  
public  class  JavassistLazyInitializer    
              extends  BasicLazyInitializer    
              implements  MethodHandler  {  
final  JavassistLazyInitializer  instance    
          =  new  JavassistLazyInitializer(…);  


ProxyFactory  factory  =  new  ProxyFactory();

factory.setSuperclass(interfaces.length  ==  1?persistentClass:null);

factory.setInterfaces(interfaces);

factory.setFilter(FINALIZE_FILTER);  


Class  cl  =  factory.createClass();

final  HibernateProxy  proxy  =  (HibernateProxy)  cl.newInstance();

((ProxyObject)proxy).setHandler(instance);

instance.constructed  =  true;

return  proxy;  
public  class  JavassistLazyInitializer    
              extends  BasicLazyInitializer    
              implements  MethodHandler  {  
final  JavassistLazyInitializer  instance    
          =  new  JavassistLazyInitializer(…);  


ProxyFactory  factory  =  new  ProxyFactory();

factory.setSuperclass(interfaces.length  ==  1?persistentClass:null);

factory.setInterfaces(interfaces);

factory.setFilter(FINALIZE_FILTER);  


Class  cl  =  factory.createClass();

final  HibernateProxy  proxy  =  (HibernateProxy)  cl.newInstance();

((ProxyObject)proxy).setHandler(instance);

instance.constructed  =  true;

return  proxy;  
Generates  proxy!
The main use case for
bytecode generation
in Java frameworks
is to generate proxies
The main use case for
bytecode generation
in Java frameworks
is to generate proxies
Riga Dev Day 2016 - Having fun with Javassist
Agenda
Javassist basics
-javaagent
HacksApplications
Agenda
Javassist basics
-javaagent
HacksApplications
… and a little bit on the use of Javassist in JRebel
Javassist 101
www.javassist.org
ClassPool
CtClass
CtClass
CtClass
CtClass
CtField
CtMethod
CtConst
CtMethod
insertBefore
insertAfter
instrument
It feels almost like Java Reflection API :)
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ct  =  cp.makeClass("com.zt.A",    
                cp.get("com.zt.Clazz"));  
        CtMethod[]  methods  =  ct.getMethods();

        for  (CtMethod  method  :  methods)  {

              //…  
        }  
        ct.writeFile("/output");  
  }
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ct  =  cp.makeClass("com.zt.A",    
                cp.get("com.zt.Clazz"));  
        CtMethod[]  methods  =  ct.getMethods();

        for  (CtMethod  method  :  methods)  {

              //…  
        }  
        ct.writeFile("/output");  
  }
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ct  =  cp.makeClass("com.zt.A",    
                cp.get("com.zt.Clazz"));  
        CtMethod[]  methods  =  ct.getMethods();

        for  (CtMethod  method  :  methods)  {

              //…  
        }  
        ct.writeFile("/output");  
  }
    ClassPool  cp  =  new  ClassPool(null);  
    cp.appendSystemPath();  
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ct  =  cp.makeClass("com.zt.A",    
                cp.get("com.zt.Clazz"));  
        CtMethod[]  methods  =  ct.getMethods();

        for  (CtMethod  method  :  methods)  {

              //…  
        }  
        ct.writeFile("/output");  
  }
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ct  =  cp.makeClass("com.zt.A",    
                cp.get("com.zt.Clazz"));  
        CtMethod[]  methods  =  ct.getMethods();

        for  (CtMethod  method  :  methods)  {

              //…  
        }  
        ct.writeFile("/output");  
  }
    public  class  A  extends  Clazz  {  

        public  A()  {

        }

    }  
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ct  =  cp.makeClass("com.zt.A",    
                cp.get("com.zt.Clazz"));  
        CtMethod[]  methods  =  ct.getMethods();

        for  (CtMethod  method  :  methods)  {

              //…  
        }  
        ct.writeFile("/output");  
  }
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ct  =  cp.makeClass("com.zt.A",    
                cp.get("com.zt.Clazz"));  
        CtMethod[]  methods  =  ct.getMethods();

        for  (CtMethod  method  :  methods)  {

              //…  
        }  
        ct.writeFile("/output");  
  }
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ct  =  cp.makeClass("com.zt.A",    
                cp.get("com.zt.Clazz"));  
        CtMethod[]  methods  =  ct.getMethods();

        for  (CtMethod  method  :  methods)  {

              //…  
        }  
        ct.writeFile("/output");  
  }
  mars:output  anton$  javap  -­‐c  com/zt/A.class    
  public  class  com.zt.A  extends  com.zt.Clazz  {  
      public  com.zt.A();  
          Code:  
              0:  aload_0  
              1:  invokespecial  #10    
              4:  return  
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ct  =  cp.makeClass("com.zt.A",    
                cp.get("com.zt.Clazz"));  
        CtMethod[]  methods  =  ct.getMethods();

        for  (CtMethod  method  :  methods)  {

              //…  
        }  
        ct.writeFile("/output");  
  }
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ct  =  cp.makeClass("com.zt.A",    
                cp.get("com.zt.Clazz"));  
        CtMethod[]  methods  =  ct.getMethods();

        for  (CtMethod  method  :  methods)  {

              //…  
        }  
        ct.writeFile("/output");  
  }
Can generate classes from
metadata at build time
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        cp.appendClassPath(new  ClassPath(){  …  });  
        CtClass  ct  =  cp.get("com.zt.A");  
        CtMethod[]  methods  =  ct.getMethods();

        for  (CtMethod  method  :  methods)  {

              //…  
        }  
        ct.writeFile("/output");  
  }
… or you can post process the
compiled classes
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        cp.appendClassPath(new  ClassPath(){  …  });  
        CtClass  ct  =  cp.get("com.zt.A");  
        CtMethod[]  methods  =  ct.getMethods();

        for  (CtMethod  method  :  methods)  {

              //…  
        }  
        ct.writeFile("/output");  
  }
… or you can post process the
compiled classes
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ctClass  =  cp.get("com.zt.A");  
        CtMethod  foo  =  ctClass.getMethod("foo",    
            "()V");  
        foo.insertBefore("System.out.println();");  
        Class  c  =  ctClass.toClass();

        A  a  =  (A)  c.newInstance();

        a.foo("Hello");

  }
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ctClass  =  cp.get("com.zt.A");  
        CtMethod  foo  =  ctClass.getMethod("foo",    
            "()V");  
        foo.insertBefore("System.out.println();");  
        Class  c  =  ctClass.toClass();

        A  a  =  (A)  c.newInstance();

        a.foo("Hello");

  }
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ctClass  =  cp.get("com.zt.A");  
        CtMethod  foo  =  ctClass.getMethod("foo",    
            "()V");  
        foo.insertBefore("System.out.println();");  
        Class  c  =  ctClass.toClass();

        A  a  =  (A)  c.newInstance();

        a.foo("Hello");

  }
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ctClass  =  cp.get("com.zt.A");  
        CtMethod  foo  =  ctClass.getMethod("foo",    
            "()V");  
        foo.insertBefore("System.out.println();");  
        Class  c  =  ctClass.toClass();

        A  a  =  (A)  c.newInstance();

        a.foo("Hello");

  }
    public  void  foo()  {  

    }  
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ctClass  =  cp.get("com.zt.A");  
        CtMethod  foo  =  ctClass.getMethod("foo",    
            "(Ljava/lang/String;)V");  
        foo.insertBefore("System.out.println();");  
        Class  c  =  ctClass.toClass();

        A  a  =  (A)  c.newInstance();

        a.foo("Hello");

  }
    public  void  foo(String  s)  {  

    }  
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ctClass  =  cp.get("com.zt.A");  
        CtMethod  foo  =  ctClass.getMethod("foo",    
            "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lja
        foo.insertBefore("System.out.println();");  
        Class  c  =  ctClass.toClass();

        A  a  =  (A)  c.newInstance();

        a.foo("Hello");

  }
  Descriptors  might  get  quite  long  ;)  
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ctClass  =  cp.get("com.zt.A");  
        CtMethod  foo  =  ctClass.getMethod("foo",    
            "(Ljava/lang/String;)V");  
        foo.insertBefore("System.out.println($1)");  
        Class  c  =  ctClass.toClass();

        A  a  =  (A)  c.newInstance();

        a.foo("Hello");

  }
  $1,  $2,  $3  —  local  variables  
  $0  —  this  for  non-­‐static  methods  
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ctClass  =  cp.get("com.zt.A");  
        CtMethod  foo  =  ctClass.getMethod("foo",    
            "(Ljava/lang/String;)V");  
        foo.insertBefore("System.out.println($1)");  
        Class  c  =  ctClass.toClass();

        A  a  =  (A)  c.newInstance();

        a.foo("Hello");

  }
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ctClass  =  cp.get("com.zt.A");  
        CtMethod  foo  =  ctClass.getMethod("foo",    
            "(Ljava/lang/String;)V");  
        foo.insertBefore("System.out.println($1)");  
        Class  c  =  ctClass.toClass();

        A  a  =  (A)  c.newInstance();

        a.foo("Hello");

  }
    
    Exception  in  thread  "main"  javassist.CannotCompileException:  [source  error]  ;  is  missing  
           at  javassist.CtBehavior.insertBefore(CtBehavior.java:774)  
           at  javassist.CtBehavior.insertBefore(CtBehavior.java:734)  
           at  com.zt.basics.Ex.main(Ex.java:35)  
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ctClass  =  cp.get("com.zt.A");  
        CtMethod  foo  =  ctClass.getMethod("foo",    
            "(Ljava/lang/String;)V");  
        foo.insertBefore("System.out.println($1);");  
        Class  c  =  ctClass.toClass();

        A  a  =  (A)  c.newInstance();

        a.foo("Hello");

  }
   public  static  void  main(String[]  args)  throws  Exception  {  
        ClassPool  cp  =  ClassPool.getDefault();  
        CtClass  ctClass  =  cp.get("com.zt.A");  
        CtMethod  foo  =  ctClass.getMethod("foo",    
            "(Ljava/lang/String;)V");  
        foo.insertBefore("System.out.println($1);");  
        Class  c  =  ctClass.toClass();

        A  a  =  (A)  c.newInstance();

        a.foo("Hello");

  }
       CtMethod  foo  =  …  
        foo.insertBefore(…);  
        foo.insertAfter(…);  
       CtMethod  foo  =  …  
        foo.insertBefore(…);  
        foo.insertAfter(…);  
Can implement tracing
… or add logging
        CtMethod  foo  =  …  
        foo.insertBefore(…);  
        foo.insertAfter(…);  
… or implement AOP
        CtMethod  foo  =  …  
        foo.insertBefore(…);  
        foo.insertAfter(…);  
       CtMethod  foo  =  …  
        foo.instrument(new  ExprEditor()  {  
            @Override

            public  void  edit(NewExpr  e)    
                    throws  CannotCompileException  {

                e.replace("{"  +

                        "$_  =  $proceed($$);"  +

                        "System.out.println($_);"  +

                        "}");

            }  
        });
       CtMethod  foo  =  …  
        foo.instrument(new  ExprEditor()  {  
            @Override

            public  void  edit(NewExpr  e)    
                    throws  CannotCompileException  {

                e.replace("{"  +

                        "$_  =  $proceed($$);"  +

                        "System.out.println($_);"  +

                        "}");

            }  
        });
       CtMethod  foo  =  …  
        foo.instrument(new  ExprEditor()  {  
            @Override

            public  void  edit(NewExpr  e)    
                    throws  CannotCompileException  {

                e.replace("{"  +

                        "$_  =  $proceed($$);"  +

                        "System.out.println($_);"  +

                        "}");

            }  
        });
       CtMethod  foo  =  …  
        foo.instrument(new  ExprEditor()  {  
            @Override

            public  void  edit(NewExpr  e)    
                    throws  CannotCompileException  {

                e.replace("{"  +

                        "$_  =  $proceed($$);"  +

                        "System.out.println($_);"  +

                        "}");

            }  
        });
       CtMethod  foo  =  …  
        foo.instrument(new  ExprEditor()  {  
            @Override

            public  void  edit(NewExpr  e)    
                    throws  CannotCompileException  {

                e.replace("{"  +

                        "$_  =  $proceed($$);"  +

                        "System.out.println($_);"  +

                        "}");

            }  
        }); Intercept new instances
       CtMethod  foo  =  …  
        foo.instrument(new  ExprEditor()  {  
            @Override

            public  void  edit(NewExpr  e)    
                    throws  CannotCompileException  {

                e.replace("{"  +

                        "$_  =  $proceed($$);"  +

                        "System.out.println($_);"  +

                        "}");

            }  
        }); Intercept new instances
       CtMethod  foo  =  …  
        foo.instrument(new  ExprEditor()  {  
            @Override

            public  void  edit(MethodCall  m)    
                    throws  CannotCompileException  {

                if(m.getMethodName().contains("println"))  {

                    m.replace("{}");

                }                
            }  
        });
       CtMethod  foo  =  …  
        foo.instrument(new  ExprEditor()  {  
            @Override

            public  void  edit(MethodCall  m)    
                    throws  CannotCompileException  {

                if(m.getMethodName().contains("println"))  {

                    m.replace("{}");

                }                
            }  
        }); Remove unwanted
invocations
       CtMethod  foo  =  …  
        foo.instrument(new  ExprEditor()  {  
            @Override

            public  void  edit(FieldAccess  m)    
                    throws  CannotCompileException  {

                if  (f.isWriter())  {

                    CtField  field  =  f.getField();

                    String  setterName  =  findSetter(field);

                    f.replace("{"  +  "$0."  +  setterName  +  "($$);"  +  "}");

                }                
            }  
        });
       CtMethod  foo  =  …  
        foo.instrument(new  ExprEditor()  {  
            @Override

            public  void  edit(FieldAccess  m)    
                    throws  CannotCompileException  {

                if  (f.isWriter())  {

                    CtField  field  =  f.getField();

                    String  setterName  =  findSetter(field);

                    f.replace("{"  +  "$0."  +  setterName  +  "($$);"  +  "}");

                }                
            }  
        });
Replace direct field access
with setter calls
java.lang.ClassFormatError:  LVTT  entry  
for  'callbackTypes'  in  class  file    
com/google/inject/internal/ProxyFactory  
does  not  match  any  LVT  entry
This slide is intentionally left blank
Java Agent
Java Agent
import java.lang.instrument.ClassFileTransformer;  
import java.lang.instrument.Instrumentation;  
public class Agent {  
public static void premain(String args, Instrumentation inst)   
throws Exception {  
inst.addTransformer(new ClassFileTransformer {   
// here be code
});  
}  
}
Java Agent
import java.lang.instrument.ClassFileTransformer;  
import java.lang.instrument.Instrumentation;  
public class Agent {  
public static void premain(String args, Instrumentation inst)   
throws Exception {  
inst.addTransformer(new ClassFileTransformer {   
// here be code
});  
}  
}
META-­‐INF/MANIFEST.MF  
Premain-­‐Class:  Agent
Java Agent
import java.lang.instrument.ClassFileTransformer;  
import java.lang.instrument.Instrumentation;  
public class Agent {  
public static void premain(String args, Instrumentation inst)   
throws Exception {  
inst.addTransformer(new ClassFileTransformer {   
// here be code
});  
}  
}
META-­‐INF/MANIFEST.MF  
Premain-­‐Class:  Agent
$>  java  –javaagent:agent.jar  application.Main
ClassFileTransformer
new ClassFileTransformer() {
public byte[] transform(ClassLoader loader,   
String className,  
Class<?> classBeingRedefined,  
ProtectionDomain protectionDomain,   
byte[] classfileBuffer){
ClassPool cp = ClassPool.getDefault();  
CtClass ct = cp.makeClass(new   
ByteArrayInputStream(classfileBuffer));
// here we can do all the things to ‘ct’
return ct.toBytecode();
}  
}
new ClassFileTransformer() {
public byte[] transform(ClassLoader loader,   
String className,  
Class<?> classBeingRedefined,  
ProtectionDomain protectionDomain,   
byte[] classfileBuffer){
ClassPool cp = ClassPool.getDefault();  
CtClass ct = cp.makeClass(new   
ByteArrayInputStream(classfileBuffer));
// here we can do all the things to ‘ct’
return ct.toBytecode();
}  
}
ClassFileTransformer
new ClassFileTransformer() {
public byte[] transform(ClassLoader loader,   
String className,  
Class<?> classBeingRedefined,  
ProtectionDomain protectionDomain,   
byte[] classfileBuffer){
ClassPool cp = ClassPool.getDefault();  
CtClass ct = cp.makeClass(new   
ByteArrayInputStream(classfileBuffer));
// here we can do all the things to ‘ct’
return ct.toBytecode();
}  
}
ClassFileTransformer
new ClassFileTransformer() {
public byte[] transform(ClassLoader loader,   
String className,  
Class<?> classBeingRedefined,  
ProtectionDomain protectionDomain,   
byte[] classfileBuffer){
ClassPool cp = ClassPool.getDefault();  
CtClass ct = cp.makeClass(new   
ByteArrayInputStream(classfileBuffer));
// here we can do all the things to ‘ct’
return ct.toBytecode();
}  
}
ClassFileTransformer
Riga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with Javassist
https://github.com/zeroturnaround/callspy
Javassist in
http://0t.ee/rigadevday2016
JRebel
core
Spring
plugin
Hibernate
plugin
EJB
plugin
JRebel
core
Spring
plugin
Hibernate
plugin
EJB
pluginjrebel.jar
Spring
plugin
Hibernate
plugin
EJB
plugin
JRebel
core
Spring
plugin
Hibernate
plugin
EJB
pluginReloads
classes
JRebel
core
JRebel
core
Spring
plugin
Hibernate
plugin
EJB
pluginNotifies
plugins
JRebel
core
Spring
plugin
Hibernate
plugin
EJB
plugin
Refresh
configurations
JRebel
core
Javassist lives here
Spring
plugin
Hibernate
plugin
EJB
plugin
Spring
Hibernate
OpenEJB
JRebel
core
Spring
plugin
Hibernate
plugin
EJB
plugin
Riga Dev Day 2016 - Having fun with Javassist
class  Framework  {  
    public  void  configure(){  
          //…

    }    
}
class  Framework  {  
    public  void  configure(){  
          //…

    }    
}
CtClass  framework    
    =  cp.get("com.zt.Framework");
class  Framework  {  
    public  void  configure(){  
          //…

    }    
}
CtClass  framework    
    =  cp.get("com.zt.Framework");
class  Framework    
  implements  Listener  {  
    public  void  configure(){

    }    
}
class  Framework  {  
    public  void  configure(){  
          //…

    }    
}
CtClass  framework    
    =  cp.get("com.zt.Framework");
framework.addInterface(  
  cp.get("com.zt.jrebel.Listener"));
class  Framework    
  implements  Listener  {  
    public  void  configure(){

    }    
}
class  Framework  {  
    public  void  configure(){  
          //…

    }    
}
CtClass  framework    
    =  cp.get("com.zt.Framework");
framework.addInterface(  
  cp.get("com.zt.jrebel.Listener"));
class  Framework    
  implements  Listener  {  
    public  void  configure(){

    }    
}
framework.addMethod(  
    CtNewMethod.make(  
        "public  void  onEvent(){"  +  
        "    configure();"  +  
        "}",  
        framework  
));
https://github.com/antonarhipov/jpoint
HowItWorks
Riga Dev Day 2016 - Having fun with Javassist
Riga Dev Day 2016 - Having fun with Javassist
Why would you use Javassist?
> Implement you own custom
framework (like if there’s not enough)
> Tools
> Profilers
> Post-processing of Java classes
> Integrate with 3rd party solution that doesn’t provide an API
> JRebel plug-ins :)
Your task
Javassist
https://speakerdeck.com/antonarhipov
http://www.slideshare.net/arhan
@antonarhipov
anton@zeroturnaround.com
http://0t.ee/rigadevday2016

More Related Content

PDF
JavaOne 2015 - Having fun with Javassist
PDF
Voxxed Days Vilnius 2015 - Having fun with Javassist
PDF
Oredev 2015 - Taming Java Agents
PDF
JEEConf 2017 - Having fun with Javassist
PDF
Con-FESS 2015 - Having Fun With Javassist
PDF
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
PPTX
Use of Apache Commons and Utilities
PDF
Антон Нонко, Классические строки в C++
JavaOne 2015 - Having fun with Javassist
Voxxed Days Vilnius 2015 - Having fun with Javassist
Oredev 2015 - Taming Java Agents
JEEConf 2017 - Having fun with Javassist
Con-FESS 2015 - Having Fun With Javassist
Riga DevDays 2017 - The hitchhiker’s guide to Java class reloading
Use of Apache Commons and Utilities
Антон Нонко, Классические строки в C++

What's hot (20)

PDF
GeeCON 2017 - TestContainers. Integration testing without the hassle
PDF
Metaprogramming and Reflection in Common Lisp
PDF
devday2012
PDF
Server1
PPTX
Jdk 7 4-forkjoin
PDF
4. Обработка ошибок, исключения, отладка
PDF
Something about Golang
KEY
Gevent what's the point
PDF
A deep dive into PEP-3156 and the new asyncio module
PDF
TensorFlow XLA RPC
PDF
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
PDF
asyncio internals
PDF
Java 7 LavaJUG
PDF
Jakarta Commons - Don't re-invent the wheel
PDF
Jenkins 2を使った究極のpipeline ~ 明日もう一度来てください、本物のpipelineをお見せしますよ ~
PPTX
모던자바의 역습
PDF
No dark magic - Byte code engineering in the real world
KEY
DjangoCon US 2011 - Monkeying around at New Relic
PPT
Ggug spock
PDF
Software Testing - Invited Lecture at UNSW Sydney
GeeCON 2017 - TestContainers. Integration testing without the hassle
Metaprogramming and Reflection in Common Lisp
devday2012
Server1
Jdk 7 4-forkjoin
4. Обработка ошибок, исключения, отладка
Something about Golang
Gevent what's the point
A deep dive into PEP-3156 and the new asyncio module
TensorFlow XLA RPC
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
asyncio internals
Java 7 LavaJUG
Jakarta Commons - Don't re-invent the wheel
Jenkins 2を使った究極のpipeline ~ 明日もう一度来てください、本物のpipelineをお見せしますよ ~
모던자바의 역습
No dark magic - Byte code engineering in the real world
DjangoCon US 2011 - Monkeying around at New Relic
Ggug spock
Software Testing - Invited Lecture at UNSW Sydney
Ad

Viewers also liked (20)

PDF
Joker 2016 - Bytecode 101
PDF
JPoint 2016 - Etudes of DIY Java profiler
PDF
Devclub 01/2017 - (Не)адекватное Java-интервью
PDF
JPoint 2016 - Bytecode
PDF
Introduction to Groovy
PDF
Something about Golang
PPTX
Jenkins Evolutions - JEEConf 2012
PDF
Taming Java Agents
PDF
import continuous.delivery.*
PDF
Con-FESS 2015 - Is your profiler speaking to you?
PDF
Improve your Developer Experiece using the WAS Liberty Profile with JRebel
PDF
JPoint 2015 - Javassist на службе Java-разработчика
PPTX
NetBeans Plugin Development: JRebel Experience Report
PDF
Загрузчики классов в Java - коллекция граблей
PDF
Under the hood of scala implicits (kl10tch 10.03.2015)
PDF
PDF
PDF
Joker 2016 - Bytecode 101
JPoint 2016 - Etudes of DIY Java profiler
Devclub 01/2017 - (Не)адекватное Java-интервью
JPoint 2016 - Bytecode
Introduction to Groovy
Something about Golang
Jenkins Evolutions - JEEConf 2012
Taming Java Agents
import continuous.delivery.*
Con-FESS 2015 - Is your profiler speaking to you?
Improve your Developer Experiece using the WAS Liberty Profile with JRebel
JPoint 2015 - Javassist на службе Java-разработчика
NetBeans Plugin Development: JRebel Experience Report
Загрузчики классов в Java - коллекция граблей
Under the hood of scala implicits (kl10tch 10.03.2015)
Ad

Similar to Riga Dev Day 2016 - Having fun with Javassist (20)

PPTX
Binary patching for fun and profit @ JUG.ru, 25.02.2012
PDF
Java agents are watching your ByteCode
PPT
2012 JDays Bad Tests Good Tests
PPT
Java Generics
PPT
Whats new in_csharp4
PDF
GeeCON 2012 Bad Tests, Good Tests
PDF
Confitura 2012 Bad Tests, Good Tests
DOCX
PPTX
Summary of C++17 features
PPTX
Anti patterns
PDF
Apache Commons - Don\'t re-invent the wheel
PDF
33rd Degree 2013, Bad Tests, Good Tests
DOCX
My java file
PPSX
What's new in C# 6 - NetPonto Porto 20160116
PDF
Sam wd programs
PPT
New features and enhancement
DOC
5 Rmi Print
PPTX
Chap2 class,objects contd
PPTX
Jvm a brief introduction
PDF
TypeScript Introduction
Binary patching for fun and profit @ JUG.ru, 25.02.2012
Java agents are watching your ByteCode
2012 JDays Bad Tests Good Tests
Java Generics
Whats new in_csharp4
GeeCON 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good Tests
Summary of C++17 features
Anti patterns
Apache Commons - Don\'t re-invent the wheel
33rd Degree 2013, Bad Tests, Good Tests
My java file
What's new in C# 6 - NetPonto Porto 20160116
Sam wd programs
New features and enhancement
5 Rmi Print
Chap2 class,objects contd
Jvm a brief introduction
TypeScript Introduction

More from Anton Arhipov (17)

PDF
JavaZone 2022 - Building Kotlin DSL.pdf
PDF
Idiomatic kotlin
PDF
TechTrain 2019 - (Не)адекватное техническое интервью
PDF
Build pipelines with TeamCity
PDF
Build pipelines with TeamCity
PDF
Devoxx Ukraine 2018 - Kotlin DSL in under an hour
PDF
GeeCON Prague 2018 - Kotlin DSL in under an hour
PDF
Build pipelines with TeamCity and Kotlin DSL
PDF
Build pipelines with TeamCity
PDF
JavaDay Kiev 2017 - Integration testing with TestContainers
PDF
GeeCON Prague 2017 - TestContainers
PDF
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
PDF
JavaOne 2017 - TestContainers: integration testing without the hassle
PDF
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
PDF
JavaZone 2017 - The Hitchhiker’s guide to Java class reloading
PDF
JUG.ua 20170225 - Java bytecode instrumentation
PDF
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JavaZone 2022 - Building Kotlin DSL.pdf
Idiomatic kotlin
TechTrain 2019 - (Не)адекватное техническое интервью
Build pipelines with TeamCity
Build pipelines with TeamCity
Devoxx Ukraine 2018 - Kotlin DSL in under an hour
GeeCON Prague 2018 - Kotlin DSL in under an hour
Build pipelines with TeamCity and Kotlin DSL
Build pipelines with TeamCity
JavaDay Kiev 2017 - Integration testing with TestContainers
GeeCON Prague 2017 - TestContainers
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - TestContainers: integration testing without the hassle
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaZone 2017 - The Hitchhiker’s guide to Java class reloading
JUG.ua 20170225 - Java bytecode instrumentation
JEEConf 2017 - The hitchhiker’s guide to Java class reloading

Recently uploaded (20)

PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
cuic standard and advanced reporting.pdf
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Electronic commerce courselecture one. Pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
A Presentation on Artificial Intelligence
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
Cloud computing and distributed systems.
Per capita expenditure prediction using model stacking based on satellite ima...
Digital-Transformation-Roadmap-for-Companies.pptx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
cuic standard and advanced reporting.pdf
Unlocking AI with Model Context Protocol (MCP)
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Electronic commerce courselecture one. Pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
A Presentation on Artificial Intelligence
Spectral efficient network and resource selection model in 5G networks
The Rise and Fall of 3GPP – Time for a Sabbatical?
Building Integrated photovoltaic BIPV_UPV.pdf
Encapsulation_ Review paper, used for researhc scholars
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
MYSQL Presentation for SQL database connectivity
Cloud computing and distributed systems.

Riga Dev Day 2016 - Having fun with Javassist

  • 1. Having fun with Javassist @antonarhipov
  • 5. You? Are you interested in Javassist?
  • 6. You? Are you interested in Javassist? Want to become a better programmer?
  • 7. You? Are you interested in Javassist? Want to become a better programmer? Bytecode instrumentation, anyone?
  • 9. @Entity
 @Table(name  =  "owners")
 public  class  Owner  extends  Person  {
        @Column(name  =  "address")
        @NotEmpty
        private  String  address;
 
        @Column(name  =  "city")
        @NotEmpty
        private  String  city;
 
        @Column(name  =  "telephone")
        @NotEmpty
        @Digits(fraction  =  0,  integer  =  10)
        private  String  telephone;
 
        @OneToMany(cascade  =  CascadeType.ALL,                                  mappedBy  =  "owner")
        private  Set<Pet>  pets;  
  • 10. public  class  JavassistLazyInitializer                  extends  BasicLazyInitializer                  implements  MethodHandler  {   final  JavassistLazyInitializer  instance              =  new  JavassistLazyInitializer(…);   
 ProxyFactory  factory  =  new  ProxyFactory();
 factory.setSuperclass(interfaces.length  ==  1?persistentClass:null);
 factory.setInterfaces(interfaces);
 factory.setFilter(FINALIZE_FILTER);   
 Class  cl  =  factory.createClass();
 final  HibernateProxy  proxy  =  (HibernateProxy)  cl.newInstance();
 ((ProxyObject)proxy).setHandler(instance);
 instance.constructed  =  true;
 return  proxy;  
  • 11. public  class  JavassistLazyInitializer                  extends  BasicLazyInitializer                  implements  MethodHandler  {   final  JavassistLazyInitializer  instance              =  new  JavassistLazyInitializer(…);   
 ProxyFactory  factory  =  new  ProxyFactory();
 factory.setSuperclass(interfaces.length  ==  1?persistentClass:null);
 factory.setInterfaces(interfaces);
 factory.setFilter(FINALIZE_FILTER);   
 Class  cl  =  factory.createClass();
 final  HibernateProxy  proxy  =  (HibernateProxy)  cl.newInstance();
 ((ProxyObject)proxy).setHandler(instance);
 instance.constructed  =  true;
 return  proxy;   Generates  proxy!
  • 12. The main use case for bytecode generation in Java frameworks is to generate proxies
  • 13. The main use case for bytecode generation in Java frameworks is to generate proxies
  • 16. Agenda Javassist basics -javaagent HacksApplications … and a little bit on the use of Javassist in JRebel
  • 19.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ct  =  cp.makeClass("com.zt.A",                    cp.get("com.zt.Clazz"));          CtMethod[]  methods  =  ct.getMethods();
        for  (CtMethod  method  :  methods)  {
              //…          }          ct.writeFile("/output");    }
  • 20.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ct  =  cp.makeClass("com.zt.A",                    cp.get("com.zt.Clazz"));          CtMethod[]  methods  =  ct.getMethods();
        for  (CtMethod  method  :  methods)  {
              //…          }          ct.writeFile("/output");    }
  • 21.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ct  =  cp.makeClass("com.zt.A",                    cp.get("com.zt.Clazz"));          CtMethod[]  methods  =  ct.getMethods();
        for  (CtMethod  method  :  methods)  {
              //…          }          ct.writeFile("/output");    }    ClassPool  cp  =  new  ClassPool(null);      cp.appendSystemPath();  
  • 22.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ct  =  cp.makeClass("com.zt.A",                    cp.get("com.zt.Clazz"));          CtMethod[]  methods  =  ct.getMethods();
        for  (CtMethod  method  :  methods)  {
              //…          }          ct.writeFile("/output");    }
  • 23.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ct  =  cp.makeClass("com.zt.A",                    cp.get("com.zt.Clazz"));          CtMethod[]  methods  =  ct.getMethods();
        for  (CtMethod  method  :  methods)  {
              //…          }          ct.writeFile("/output");    }    public  class  A  extends  Clazz  {  
        public  A()  {
        }
    }  
  • 24.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ct  =  cp.makeClass("com.zt.A",                    cp.get("com.zt.Clazz"));          CtMethod[]  methods  =  ct.getMethods();
        for  (CtMethod  method  :  methods)  {
              //…          }          ct.writeFile("/output");    }
  • 25.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ct  =  cp.makeClass("com.zt.A",                    cp.get("com.zt.Clazz"));          CtMethod[]  methods  =  ct.getMethods();
        for  (CtMethod  method  :  methods)  {
              //…          }          ct.writeFile("/output");    }
  • 26.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ct  =  cp.makeClass("com.zt.A",                    cp.get("com.zt.Clazz"));          CtMethod[]  methods  =  ct.getMethods();
        for  (CtMethod  method  :  methods)  {
              //…          }          ct.writeFile("/output");    }  mars:output  anton$  javap  -­‐c  com/zt/A.class      public  class  com.zt.A  extends  com.zt.Clazz  {        public  com.zt.A();            Code:                0:  aload_0                1:  invokespecial  #10                  4:  return  
  • 27.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ct  =  cp.makeClass("com.zt.A",                    cp.get("com.zt.Clazz"));          CtMethod[]  methods  =  ct.getMethods();
        for  (CtMethod  method  :  methods)  {
              //…          }          ct.writeFile("/output");    }
  • 28.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ct  =  cp.makeClass("com.zt.A",                    cp.get("com.zt.Clazz"));          CtMethod[]  methods  =  ct.getMethods();
        for  (CtMethod  method  :  methods)  {
              //…          }          ct.writeFile("/output");    } Can generate classes from metadata at build time
  • 29.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          cp.appendClassPath(new  ClassPath(){  …  });          CtClass  ct  =  cp.get("com.zt.A");          CtMethod[]  methods  =  ct.getMethods();
        for  (CtMethod  method  :  methods)  {
              //…          }          ct.writeFile("/output");    } … or you can post process the compiled classes
  • 30.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          cp.appendClassPath(new  ClassPath(){  …  });          CtClass  ct  =  cp.get("com.zt.A");          CtMethod[]  methods  =  ct.getMethods();
        for  (CtMethod  method  :  methods)  {
              //…          }          ct.writeFile("/output");    } … or you can post process the compiled classes
  • 31.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ctClass  =  cp.get("com.zt.A");          CtMethod  foo  =  ctClass.getMethod("foo",                "()V");          foo.insertBefore("System.out.println();");          Class  c  =  ctClass.toClass();
        A  a  =  (A)  c.newInstance();
        a.foo("Hello");
  }
  • 32.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ctClass  =  cp.get("com.zt.A");          CtMethod  foo  =  ctClass.getMethod("foo",                "()V");          foo.insertBefore("System.out.println();");          Class  c  =  ctClass.toClass();
        A  a  =  (A)  c.newInstance();
        a.foo("Hello");
  }
  • 33.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ctClass  =  cp.get("com.zt.A");          CtMethod  foo  =  ctClass.getMethod("foo",                "()V");          foo.insertBefore("System.out.println();");          Class  c  =  ctClass.toClass();
        A  a  =  (A)  c.newInstance();
        a.foo("Hello");
  }
  • 34.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ctClass  =  cp.get("com.zt.A");          CtMethod  foo  =  ctClass.getMethod("foo",                "()V");          foo.insertBefore("System.out.println();");          Class  c  =  ctClass.toClass();
        A  a  =  (A)  c.newInstance();
        a.foo("Hello");
  }    public  void  foo()  {  
    }  
  • 35.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ctClass  =  cp.get("com.zt.A");          CtMethod  foo  =  ctClass.getMethod("foo",                "(Ljava/lang/String;)V");          foo.insertBefore("System.out.println();");          Class  c  =  ctClass.toClass();
        A  a  =  (A)  c.newInstance();
        a.foo("Hello");
  }    public  void  foo(String  s)  {  
    }  
  • 36.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ctClass  =  cp.get("com.zt.A");          CtMethod  foo  =  ctClass.getMethod("foo",                "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lja        foo.insertBefore("System.out.println();");          Class  c  =  ctClass.toClass();
        A  a  =  (A)  c.newInstance();
        a.foo("Hello");
  }  Descriptors  might  get  quite  long  ;)  
  • 37.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ctClass  =  cp.get("com.zt.A");          CtMethod  foo  =  ctClass.getMethod("foo",                "(Ljava/lang/String;)V");          foo.insertBefore("System.out.println($1)");          Class  c  =  ctClass.toClass();
        A  a  =  (A)  c.newInstance();
        a.foo("Hello");
  }  $1,  $2,  $3  —  local  variables    $0  —  this  for  non-­‐static  methods  
  • 38.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ctClass  =  cp.get("com.zt.A");          CtMethod  foo  =  ctClass.getMethod("foo",                "(Ljava/lang/String;)V");          foo.insertBefore("System.out.println($1)");          Class  c  =  ctClass.toClass();
        A  a  =  (A)  c.newInstance();
        a.foo("Hello");
  }
  • 39.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ctClass  =  cp.get("com.zt.A");          CtMethod  foo  =  ctClass.getMethod("foo",                "(Ljava/lang/String;)V");          foo.insertBefore("System.out.println($1)");          Class  c  =  ctClass.toClass();
        A  a  =  (A)  c.newInstance();
        a.foo("Hello");
  }        Exception  in  thread  "main"  javassist.CannotCompileException:  [source  error]  ;  is  missing            at  javassist.CtBehavior.insertBefore(CtBehavior.java:774)            at  javassist.CtBehavior.insertBefore(CtBehavior.java:734)            at  com.zt.basics.Ex.main(Ex.java:35)  
  • 40.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ctClass  =  cp.get("com.zt.A");          CtMethod  foo  =  ctClass.getMethod("foo",                "(Ljava/lang/String;)V");          foo.insertBefore("System.out.println($1);");          Class  c  =  ctClass.toClass();
        A  a  =  (A)  c.newInstance();
        a.foo("Hello");
  }
  • 41.    public  static  void  main(String[]  args)  throws  Exception  {          ClassPool  cp  =  ClassPool.getDefault();          CtClass  ctClass  =  cp.get("com.zt.A");          CtMethod  foo  =  ctClass.getMethod("foo",                "(Ljava/lang/String;)V");          foo.insertBefore("System.out.println($1);");          Class  c  =  ctClass.toClass();
        A  a  =  (A)  c.newInstance();
        a.foo("Hello");
  }
  • 42.        CtMethod  foo  =  …          foo.insertBefore(…);          foo.insertAfter(…);  
  • 43.        CtMethod  foo  =  …          foo.insertBefore(…);          foo.insertAfter(…);   Can implement tracing
  • 44. … or add logging        CtMethod  foo  =  …          foo.insertBefore(…);          foo.insertAfter(…);  
  • 45. … or implement AOP        CtMethod  foo  =  …          foo.insertBefore(…);          foo.insertAfter(…);  
  • 46.        CtMethod  foo  =  …          foo.instrument(new  ExprEditor()  {              @Override
            public  void  edit(NewExpr  e)                        throws  CannotCompileException  {
                e.replace("{"  +
                        "$_  =  $proceed($$);"  +
                        "System.out.println($_);"  +
                        "}");
            }          });
  • 47.        CtMethod  foo  =  …          foo.instrument(new  ExprEditor()  {              @Override
            public  void  edit(NewExpr  e)                        throws  CannotCompileException  {
                e.replace("{"  +
                        "$_  =  $proceed($$);"  +
                        "System.out.println($_);"  +
                        "}");
            }          });
  • 48.        CtMethod  foo  =  …          foo.instrument(new  ExprEditor()  {              @Override
            public  void  edit(NewExpr  e)                        throws  CannotCompileException  {
                e.replace("{"  +
                        "$_  =  $proceed($$);"  +
                        "System.out.println($_);"  +
                        "}");
            }          });
  • 49.        CtMethod  foo  =  …          foo.instrument(new  ExprEditor()  {              @Override
            public  void  edit(NewExpr  e)                        throws  CannotCompileException  {
                e.replace("{"  +
                        "$_  =  $proceed($$);"  +
                        "System.out.println($_);"  +
                        "}");
            }          });
  • 50.        CtMethod  foo  =  …          foo.instrument(new  ExprEditor()  {              @Override
            public  void  edit(NewExpr  e)                        throws  CannotCompileException  {
                e.replace("{"  +
                        "$_  =  $proceed($$);"  +
                        "System.out.println($_);"  +
                        "}");
            }          }); Intercept new instances
  • 51.        CtMethod  foo  =  …          foo.instrument(new  ExprEditor()  {              @Override
            public  void  edit(NewExpr  e)                        throws  CannotCompileException  {
                e.replace("{"  +
                        "$_  =  $proceed($$);"  +
                        "System.out.println($_);"  +
                        "}");
            }          }); Intercept new instances
  • 52.        CtMethod  foo  =  …          foo.instrument(new  ExprEditor()  {              @Override
            public  void  edit(MethodCall  m)                        throws  CannotCompileException  {
                if(m.getMethodName().contains("println"))  {
                    m.replace("{}");
                }                            }          });
  • 53.        CtMethod  foo  =  …          foo.instrument(new  ExprEditor()  {              @Override
            public  void  edit(MethodCall  m)                        throws  CannotCompileException  {
                if(m.getMethodName().contains("println"))  {
                    m.replace("{}");
                }                            }          }); Remove unwanted invocations
  • 54.        CtMethod  foo  =  …          foo.instrument(new  ExprEditor()  {              @Override
            public  void  edit(FieldAccess  m)                        throws  CannotCompileException  {
                if  (f.isWriter())  {
                    CtField  field  =  f.getField();
                    String  setterName  =  findSetter(field);
                    f.replace("{"  +  "$0."  +  setterName  +  "($$);"  +  "}");
                }                            }          });
  • 55.        CtMethod  foo  =  …          foo.instrument(new  ExprEditor()  {              @Override
            public  void  edit(FieldAccess  m)                        throws  CannotCompileException  {
                if  (f.isWriter())  {
                    CtField  field  =  f.getField();
                    String  setterName  =  findSetter(field);
                    f.replace("{"  +  "$0."  +  setterName  +  "($$);"  +  "}");
                }                            }          }); Replace direct field access with setter calls
  • 56. java.lang.ClassFormatError:  LVTT  entry   for  'callbackTypes'  in  class  file     com/google/inject/internal/ProxyFactory   does  not  match  any  LVT  entry
  • 57. This slide is intentionally left blank
  • 59. Java Agent import java.lang.instrument.ClassFileTransformer;   import java.lang.instrument.Instrumentation;   public class Agent {   public static void premain(String args, Instrumentation inst)   throws Exception {   inst.addTransformer(new ClassFileTransformer {   // here be code });   }   }
  • 60. Java Agent import java.lang.instrument.ClassFileTransformer;   import java.lang.instrument.Instrumentation;   public class Agent {   public static void premain(String args, Instrumentation inst)   throws Exception {   inst.addTransformer(new ClassFileTransformer {   // here be code });   }   } META-­‐INF/MANIFEST.MF   Premain-­‐Class:  Agent
  • 61. Java Agent import java.lang.instrument.ClassFileTransformer;   import java.lang.instrument.Instrumentation;   public class Agent {   public static void premain(String args, Instrumentation inst)   throws Exception {   inst.addTransformer(new ClassFileTransformer {   // here be code });   }   } META-­‐INF/MANIFEST.MF   Premain-­‐Class:  Agent $>  java  –javaagent:agent.jar  application.Main
  • 62. ClassFileTransformer new ClassFileTransformer() { public byte[] transform(ClassLoader loader,   String className,   Class<?> classBeingRedefined,   ProtectionDomain protectionDomain,   byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault();   CtClass ct = cp.makeClass(new   ByteArrayInputStream(classfileBuffer)); // here we can do all the things to ‘ct’ return ct.toBytecode(); }   }
  • 63. new ClassFileTransformer() { public byte[] transform(ClassLoader loader,   String className,   Class<?> classBeingRedefined,   ProtectionDomain protectionDomain,   byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault();   CtClass ct = cp.makeClass(new   ByteArrayInputStream(classfileBuffer)); // here we can do all the things to ‘ct’ return ct.toBytecode(); }   } ClassFileTransformer
  • 64. new ClassFileTransformer() { public byte[] transform(ClassLoader loader,   String className,   Class<?> classBeingRedefined,   ProtectionDomain protectionDomain,   byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault();   CtClass ct = cp.makeClass(new   ByteArrayInputStream(classfileBuffer)); // here we can do all the things to ‘ct’ return ct.toBytecode(); }   } ClassFileTransformer
  • 65. new ClassFileTransformer() { public byte[] transform(ClassLoader loader,   String className,   Class<?> classBeingRedefined,   ProtectionDomain protectionDomain,   byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault();   CtClass ct = cp.makeClass(new   ByteArrayInputStream(classfileBuffer)); // here we can do all the things to ‘ct’ return ct.toBytecode(); }   } ClassFileTransformer
  • 82. class  Framework  {      public  void  configure(){            //…
    }     }
  • 83. class  Framework  {      public  void  configure(){            //…
    }     } CtClass  framework        =  cp.get("com.zt.Framework");
  • 84. class  Framework  {      public  void  configure(){            //…
    }     } CtClass  framework        =  cp.get("com.zt.Framework"); class  Framework      implements  Listener  {      public  void  configure(){
    }     }
  • 85. class  Framework  {      public  void  configure(){            //…
    }     } CtClass  framework        =  cp.get("com.zt.Framework"); framework.addInterface(    cp.get("com.zt.jrebel.Listener")); class  Framework      implements  Listener  {      public  void  configure(){
    }     }
  • 86. class  Framework  {      public  void  configure(){            //…
    }     } CtClass  framework        =  cp.get("com.zt.Framework"); framework.addInterface(    cp.get("com.zt.jrebel.Listener")); class  Framework      implements  Listener  {      public  void  configure(){
    }     } framework.addMethod(      CtNewMethod.make(          "public  void  onEvent(){"  +          "    configure();"  +          "}",          framework   ));
  • 90. Why would you use Javassist? > Implement you own custom framework (like if there’s not enough) > Tools > Profilers > Post-processing of Java classes > Integrate with 3rd party solution that doesn’t provide an API > JRebel plug-ins :)