Top Banner
Having fun with Javassist @antonarhipov
92

Riga Dev Day 2016 - Having fun with Javassist

Jan 16, 2017

Download

Technology

Anton Arhipov
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Riga Dev Day 2016 - Having fun with Javassist

Having fun with Javassist@antonarhipov

Page 2: Riga Dev Day 2016 - Having fun with Javassist

Me

Anton Arhipov @antonarhipov

Page 3: Riga Dev Day 2016 - Having fun with Javassist

Me

Anton Arhipov @antonarhipov

Javassist inside!

Page 4: Riga Dev Day 2016 - Having fun with Javassist

You?

Page 5: Riga Dev Day 2016 - Having fun with Javassist

You?

Are you interested in Javassist?

Page 6: Riga Dev Day 2016 - Having fun with Javassist

You?

Are you interested in Javassist?

Want to become a better programmer?

Page 7: Riga Dev Day 2016 - Having fun with Javassist

You?

Are you interested in Javassist?

Want to become a better programmer?

Bytecode instrumentation, anyone?

Page 8: Riga Dev Day 2016 - Having fun with Javassist
Page 9: 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;  

Page 10: Riga Dev Day 2016 - Having fun with Javassist

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;  

Page 11: Riga Dev Day 2016 - Having fun with Javassist

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!

Page 12: Riga Dev Day 2016 - Having fun with Javassist

The main use case for bytecode generation in Java frameworks

is to generate proxies

Page 13: Riga Dev Day 2016 - Having fun with Javassist

The main use case for bytecode generation in Java frameworks

is to generate proxies

Page 14: Riga Dev Day 2016 - Having fun with Javassist
Page 15: Riga Dev Day 2016 - Having fun with Javassist

Agenda

Javassist basics -javaagent

HacksApplications

Page 16: Riga Dev Day 2016 - Having fun with Javassist

Agenda

Javassist basics -javaagent

HacksApplications

… and a little bit on the use of Javassist in JRebel

Page 17: Riga Dev Day 2016 - Having fun with Javassist

Javassist 101www.javassist.org

Page 18: Riga Dev Day 2016 - Having fun with Javassist

ClassPool

CtClassCtClassCtClass

CtClass

CtFieldCtMethodCtConst

CtMethod

insertBeforeinsertAfterinstrument

It feels almost like Java Reflection API :)

Page 19: Riga Dev Day 2016 - Having fun with Javassist

   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");  

 }

Page 20: Riga Dev Day 2016 - Having fun with Javassist

   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");  

 }

Page 21: Riga Dev Day 2016 - Having fun with Javassist

   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();  

Page 22: Riga Dev Day 2016 - Having fun with Javassist

   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");  

 }

Page 23: Riga Dev Day 2016 - Having fun with Javassist

   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()  {        }    }  

Page 24: Riga Dev Day 2016 - Having fun with Javassist

   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");  

 }

Page 25: Riga Dev Day 2016 - Having fun with Javassist

   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");  

 }

Page 26: Riga Dev Day 2016 - Having fun with Javassist

   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  

Page 27: Riga Dev Day 2016 - Having fun with Javassist

   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");  

 }

Page 28: Riga Dev Day 2016 - Having fun with Javassist

   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

Page 29: Riga Dev Day 2016 - Having fun with Javassist

   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

Page 30: Riga Dev Day 2016 - Having fun with Javassist

   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

Page 31: Riga Dev Day 2016 - Having fun with Javassist

   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");

 }

Page 32: Riga Dev Day 2016 - Having fun with Javassist

   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");

 }

Page 33: Riga Dev Day 2016 - Having fun with Javassist

   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");

 }

Page 34: Riga Dev Day 2016 - Having fun with Javassist

   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()  {      }  

Page 35: Riga Dev Day 2016 - Having fun with Javassist

   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)  {      }  

Page 36: Riga Dev Day 2016 - Having fun with Javassist

   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;Ljava/lang/String;)V");  

       foo.insertBefore("System.out.println();");  

       Class  c  =  ctClass.toClass();        A  a  =  (A)  c.newInstance();        a.foo("Hello");

 }

 Descriptors  might  get  quite  long  ;)  

Page 37: Riga Dev Day 2016 - Having fun with Javassist

   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  

Page 38: Riga Dev Day 2016 - Having fun with Javassist

   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");

 }

Page 39: Riga Dev Day 2016 - Having fun with Javassist

   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)  

Page 40: Riga Dev Day 2016 - Having fun with Javassist

   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");

 }

Page 41: Riga Dev Day 2016 - Having fun with Javassist

   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");

 }

Page 42: Riga Dev Day 2016 - Having fun with Javassist

       CtMethod  foo  =  …  

       foo.insertBefore(…);  

       foo.insertAfter(…);  

Page 43: Riga Dev Day 2016 - Having fun with Javassist

       CtMethod  foo  =  …  

       foo.insertBefore(…);  

       foo.insertAfter(…);  

Can implement tracing

Page 44: Riga Dev Day 2016 - Having fun with Javassist

… or add logging

       CtMethod  foo  =  …  

       foo.insertBefore(…);  

       foo.insertAfter(…);  

Page 45: Riga Dev Day 2016 - Having fun with Javassist

… or implement AOP

       CtMethod  foo  =  …  

       foo.insertBefore(…);  

       foo.insertAfter(…);  

Page 46: Riga Dev Day 2016 - Having fun with Javassist

       CtMethod  foo  =  …  

       foo.instrument(new  ExprEditor()  {              @Override            public  void  edit(NewExpr  e)                        throws  CannotCompileException  {                e.replace("{"  +                        "$_  =  $proceed($$);"  +                        "System.out.println($_);"  +                        "}");            }  

       });

Page 47: Riga Dev Day 2016 - Having fun with Javassist

       CtMethod  foo  =  …  

       foo.instrument(new  ExprEditor()  {              @Override            public  void  edit(NewExpr  e)                        throws  CannotCompileException  {                e.replace("{"  +                        "$_  =  $proceed($$);"  +                        "System.out.println($_);"  +                        "}");            }  

       });

Page 48: Riga Dev Day 2016 - Having fun with Javassist

       CtMethod  foo  =  …  

       foo.instrument(new  ExprEditor()  {              @Override            public  void  edit(NewExpr  e)                        throws  CannotCompileException  {                e.replace("{"  +                        "$_  =  $proceed($$);"  +                        "System.out.println($_);"  +                        "}");            }  

       });

Page 49: Riga Dev Day 2016 - Having fun with Javassist

       CtMethod  foo  =  …  

       foo.instrument(new  ExprEditor()  {              @Override            public  void  edit(NewExpr  e)                        throws  CannotCompileException  {                e.replace("{"  +                        "$_  =  $proceed($$);"  +                        "System.out.println($_);"  +                        "}");            }  

       });

Page 50: Riga Dev Day 2016 - Having fun with Javassist

       CtMethod  foo  =  …  

       foo.instrument(new  ExprEditor()  {              @Override            public  void  edit(NewExpr  e)                        throws  CannotCompileException  {                e.replace("{"  +                        "$_  =  $proceed($$);"  +                        "System.out.println($_);"  +                        "}");            }  

       }); Intercept new instances

Page 51: Riga Dev Day 2016 - Having fun with Javassist

       CtMethod  foo  =  …  

       foo.instrument(new  ExprEditor()  {              @Override            public  void  edit(NewExpr  e)                        throws  CannotCompileException  {                e.replace("{"  +                        "$_  =  $proceed($$);"  +                        "System.out.println($_);"  +                        "}");            }  

       }); Intercept new instances

Page 52: Riga Dev Day 2016 - Having fun with Javassist

       CtMethod  foo  =  …  

       foo.instrument(new  ExprEditor()  {              @Override            public  void  edit(MethodCall  m)                        throws  CannotCompileException  {                if(m.getMethodName().contains("println"))  {                    m.replace("{}");                }                            }  

       });

Page 53: Riga Dev Day 2016 - Having fun with Javassist

       CtMethod  foo  =  …  

       foo.instrument(new  ExprEditor()  {              @Override            public  void  edit(MethodCall  m)                        throws  CannotCompileException  {                if(m.getMethodName().contains("println"))  {                    m.replace("{}");                }                            }  

       }); Remove unwanted invocations

Page 54: Riga Dev Day 2016 - Having fun with Javassist

       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  +  "($$);"  +  "}");                }                            }  

       });

Page 55: Riga Dev Day 2016 - Having fun with Javassist

       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

Page 56: Riga Dev Day 2016 - Having fun with Javassist

java.lang.ClassFormatError:  LVTT  entry  for  'callbackTypes'  in  class  file    com/google/inject/internal/ProxyFactory  does  not  match  any  LVT  entry

Page 57: Riga Dev Day 2016 - Having fun with Javassist

This slide is intentionally left blank

Page 58: Riga Dev Day 2016 - Having fun with Javassist

Java Agent

Page 59: Riga Dev Day 2016 - Having fun with Javassist

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 });   }  }

Page 60: Riga Dev Day 2016 - Having fun with Javassist

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

Page 61: Riga Dev Day 2016 - Having fun with Javassist

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

Page 62: Riga Dev Day 2016 - Having fun with Javassist

ClassFileTransformernew 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(); }  }

Page 63: Riga Dev Day 2016 - Having fun with Javassist

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

Page 64: Riga Dev Day 2016 - Having fun with Javassist

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

Page 65: Riga Dev Day 2016 - Having fun with Javassist

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

Page 66: Riga Dev Day 2016 - Having fun with Javassist
Page 67: Riga Dev Day 2016 - Having fun with Javassist
Page 68: Riga Dev Day 2016 - Having fun with Javassist
Page 69: Riga Dev Day 2016 - Having fun with Javassist
Page 70: Riga Dev Day 2016 - Having fun with Javassist
Page 71: Riga Dev Day 2016 - Having fun with Javassist

https://github.com/zeroturnaround/callspy

Page 72: Riga Dev Day 2016 - Having fun with Javassist

Javassist inhttp://0t.ee/rigadevday2016

Page 73: Riga Dev Day 2016 - Having fun with Javassist

JRebel core

Spring plugin

Hibernate plugin

EJB plugin

Page 74: Riga Dev Day 2016 - Having fun with Javassist

JRebel core

Spring plugin

Hibernate plugin

EJB pluginjrebel.jar

Page 75: Riga Dev Day 2016 - Having fun with Javassist

Spring plugin

Hibernate plugin

EJB plugin

JRebel core

Page 76: Riga Dev Day 2016 - Having fun with Javassist

Spring plugin

Hibernate plugin

EJB pluginReloads

classes

JRebel core

Page 77: Riga Dev Day 2016 - Having fun with Javassist

JRebel core

Spring plugin

Hibernate plugin

EJB pluginNotifies

plugins

Page 78: Riga Dev Day 2016 - Having fun with Javassist

JRebel core

Spring plugin

Hibernate plugin

EJB plugin

Refresh configurations

Page 79: Riga Dev Day 2016 - Having fun with Javassist

JRebel core

Javassist lives here

Spring plugin

Hibernate plugin

EJB plugin

Page 80: Riga Dev Day 2016 - Having fun with Javassist

Spring

Hibernate

OpenEJB

JRebel core

Spring plugin

Hibernate plugin

EJB plugin

Page 81: Riga Dev Day 2016 - Having fun with Javassist
Page 82: Riga Dev Day 2016 - Having fun with Javassist

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

Page 83: Riga Dev Day 2016 - Having fun with Javassist

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

CtClass  framework        =  cp.get("com.zt.Framework");

Page 84: Riga Dev Day 2016 - Having fun with Javassist

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

CtClass  framework        =  cp.get("com.zt.Framework");

class  Framework      implements  Listener  {      public  void  configure(){    }    }

Page 85: Riga Dev Day 2016 - Having fun with Javassist

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(){    }    }

Page 86: Riga Dev Day 2016 - Having fun with Javassist

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  ));

Page 87: Riga Dev Day 2016 - Having fun with Javassist

https://github.com/antonarhipov/jpoint

HowItWorks

Page 88: Riga Dev Day 2016 - Having fun with Javassist
Page 89: Riga Dev Day 2016 - Having fun with Javassist
Page 90: 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 :)

Page 91: Riga Dev Day 2016 - Having fun with Javassist

Your task

Javassist

Page 92: Riga Dev Day 2016 - Having fun with Javassist

https://speakerdeck.com/antonarhipov

http://www.slideshare.net/arhan

@antonarhipov [email protected]

http://0t.ee/rigadevday2016