Upgrade to Pro — share decks privately, control downloads, hide ads and more …

1000 years of productivity: the JRebel story

1000 years of productivity: the JRebel story

Anton Arhipov

April 16, 2014
Tweet

More Decks by Anton Arhipov

Other Decks in Programming

Transcript

  1. Classes Libraries OldClassLoader NewClassLoader Sevlet New Classes New Libraries Sevlet

    Session Session init() App State App State Serialize/deserialize
  2. Class loaders are good for isolation, but suck at reloading

    the code … (and perfect for memory leaks)
  3. M. Dmitriev. Safe class and data evolution in large and

    long-lived java[tm] applications. Technical report, Mountain View, CA, 2001.
  4. HotSwap JRebel Changing method bodies Adding/removing methods Adding/removing constructors Adding/removing

    fields Adding/removing annotations Changing superclass Adding/removing interfaces
  5. ClassA +field1 +field2 +field3 +method1(n:int) +method2(s:String) +method3(z:double) ClassA +field1 +field2

    +field3 +proxy methods ClassA0 +method1(n:int) +method2(s:String) +method3(z:double) Transformer
  6. public class C extends X {! int y = 5;!

    int method1(int x) {! return x + y;! }! void method2(String s) {! System.out.println(s);! }! }!
  7. public class C extends X {! int y = 5;!

    int method1(int x) {! Object[] o = new Object[1];! o[0] = x;! return Runtime.redirect(this, o, "C", "method1", "(I)I");! }! void method2(String s) {! Object[] o = new Object[1];! o[0] = s;! return Runtime.redirect(! this, o, "C", "method2", "(Ljava/lang/String;)V");! }! }
  8. public abstract class C0 {! public static int method1(C c,

    int x) {! int tmp1 = Runtime.getFieldValue(c, "C", "y", "I");! return x + tmp1;! }! public static void method2(C c, String s) {! PrintStream tmp1 = Runtime.getFieldValue(! null, "java/lang/System", "out", "Ljava/io/PrintStream;");! Object[] o = new Object[1];! o[0] = s;! Runtime.redirect(! tmp1, o, "java/io/PrintStream;", "println", ! "(Ljava/lang/String;)V");! }! }!
  9. public class C extends X {! int y = 5;!

    int method1(int x) {! return x + y;! }! //...! }! public class C extends X {! int y = 5;! int z() {! return 10;! }! int method1(int x) {! return x + y + z();! }! //...! }
  10. public class C1 {! public static int z(C c) {!

    return 10;! }! public static int method1(C c, int x) {! int tmp1 = Runtime.getFieldValue(c, "C", "y", "I");! int tmp2 = Runtime.redirect(c, null, "C", "z", "(V)I");! return x + tmp1 + tmp2;! }! //...! }
  11. static { } Adding new static fields Removing static fields

    Changing values of static fields Factories etc
  12. package a;! public class A { ! int say() {return

    1;}! }! ! ! package a;! class Test {! public static void main(String args[]) {! a.A a = new b.B();! System.out.println(a.say());! }! } package b;! public class B extends a.A {! int say() {return 2;}! }! !
  13. 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 { });! }! } java –javaagent:agent.jar … META-INF/MANIFEST.MF Premain-Class: Agent
  14. 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));! ! transformClass(ct, cp); ! ! return ct.toBytecode();! }! }!
  15. 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));! ! transformClass(ct, cp); ! ! return ct.toBytecode();! }! }!
  16. @Path(“/”) public String foo() { return “Foo”; } @Path(“/foobar”) public

    String foo() { return “FooBar”; } JRebel core JRebel Spring plugin
  17. http://zeroturnaround.com/company/case-studies/ “Team velocity was increased by 40.6%, and according to

    t-test it was a statistically significant difference.” “Netty and Spring together with JRebel is real pleasure to work with. The value of time saved is over 50% of my development time.”