Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
The hitchhiker’s guide to
Java class reloading
JEEConf 2017
@antonarhipov
whoami
Anton Arhipov
@antonarhipov
whoami
Anton Arhipov
@antonarhipov
HotSwap
HotSwap
Class loaders
HotSwap
Class loaders
Java agents & instrumentation
hotswapEST. 2001
HOW ABOUT…
refactoring?
JDB
instanceKlass constantPoolOop
constants()
pool_holder()
klassVTable
Embedded
klassITable
Embedded
Embedded
statics
M. Dmit...
instanceKlass constantPoolOop
constants()
constantPoolCacheOop
cache()
pool_holder()
klassVTable
Embedded
klassITable
Embe...
instanceKlass constantPoolOop
constants()
constantPoolCacheOop
cache()
pool_holder()
klassVTable
Embedded
klassITable
Embe...
instanceKlass constantPoolOop
constants()
constantPoolCacheOop
cache()
pool_holder()
klassVTable
Embedded
klassITable
Embe...
What if…
hotswap++
Dynamic Code Evolution for Java
T. Würthinger, C. Wimmer, L. Stadler. 2010
Dynamic Code Evolution for Java
T. Würthinger, C. Wimmer, L. Stadler. 2010
Statements
Dynamic Code Evolution for Java
T. Würthinger, C. Wimmer, L. Stadler. 2010
Statements
Methods
Dynamic Code Evolution for Java
T. Würthinger, C. Wimmer, L. Stadler. 2010
Statements
Methods Fields
Dynamic Code Evolution for Java
T. Würthinger, C. Wimmer, L. Stadler. 2010
Statements
Methods Fields Hierarchy
Dynamic Code Evolution for Java
T. Würthinger, C. Wimmer, L. Stadler. 2010
Statements
Methods Fields Hierarchy
Dynamic Code Evolution for Java
T. Würthinger, C. Wimmer, L. Stadler. 2010
Statements
Methods Fields Hierarchy
+ + +
Binar...
Dynamic Code Evolution for Java
T. Würthinger, C. Wimmer, L. Stadler. 2010
Statements
Methods Fields Hierarchy
+ + +
x x x...
Classloaders
Class<?> uc1 = User.class;
Class<?> uc2 = new DynamicClassLoader().load("com.zt.User");
out.println(uc1.getName()); // com...
Class<?> uc1 = User.class;
Class<?> uc2 = new DynamicClassLoader().load("com.zt.User");
out.println(uc1.getName()); // com...
Class<?> uc1 = User.class;
Class<?> uc2 = new DynamicClassLoader().load("com.zt.User");
out.println(uc1.getName()); // com...
Class<?> uc1 = User.class;
Class<?> uc2 = new DynamicClassLoader().load("com.zt.User");
out.println(uc1.getName()); // com...
Class<?> uc1 = User.class;
Class<?> uc2 = new DynamicClassLoader().load("com.zt.User");
out.println(uc1.getName()); // com...
while(true) {
Class<?> uc = new DynamicClassLoader().load("com.zt.User");
ReflectUtil.invokeStatic("getHobby", uc);
}
publ...
while(true) {
Class<?> uc = new DynamicClassLoader().load("com.zt.User");
ReflectUtil.invokeStatic("getHobby", uc);
}
publ...
public static class Context {
public HobbyService hobbyService = new HobbyService();
public void init() {
hobbyService.use...
public static class Context {
public HobbyService hobbyService = new HobbyService();
public AnyService anyService = new An...
public static class Context {
public HobbyService hobbyService = new HobbyService();
public AnyService anyService = new An...
DynamicClassLoader
Context class
HobbyService class
User class
Context object
HobbyService object
User object
Live thread
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</sco...
Java agents
ClassFileTransformer
ClassA
ClassA
ClassA0
+field1
+field2
+field3
+method1
+method2
+method3
+method1
+method2
+method3
+...
ClassFileTransformer
ClassA
ClassA
ClassA0
+field1
+field2
+field3
+method1
+method2
+method3
+method1
+method2
+method3
+...
DEMO
HotSwap
HotSwap
Class loaders
HotSwap
Class loaders
Java agents & instrumentation
anton@zeroturnaround.com
@antonarhipov
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
JEEConf 2017 - The hitchhiker’s guide to Java class reloading
Upcoming SlideShare
Loading in …5
×

JEEConf 2017 - The hitchhiker’s guide to Java class reloading

2,590 views

Published on

In Java, a typical workflow involves restarting the application (almost) with every class change. For some applications it is not a problem at all, for some – it is a disaster.

From HotSwap to agent-based reloading. In this session, we are going to take a look at the options available for Java class reloading. There is plenty of tools that you can use for this task: rely on standard JVM HotSwap, redesign your application to rely on dynamic class loaders, to comprehend the Zen of OSGi, or to integrate a reloading agent. Every option has its own drawbacks and benefits and we’re going to take a deep dive on the subject.

Finally, there are also the conceptual challenges in reloading Java classes. What to do with the state? What should happen with the static initialisers? What if super class changes? Join this session to gain a better understanding of class reloading technologies and become more productive Java developer.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

JEEConf 2017 - The hitchhiker’s guide to Java class reloading

  1. 1. The hitchhiker’s guide to Java class reloading JEEConf 2017 @antonarhipov
  2. 2. whoami Anton Arhipov @antonarhipov
  3. 3. whoami Anton Arhipov @antonarhipov
  4. 4. HotSwap
  5. 5. HotSwap Class loaders
  6. 6. HotSwap Class loaders Java agents & instrumentation
  7. 7. hotswapEST. 2001
  8. 8. HOW ABOUT… refactoring?
  9. 9. JDB
  10. 10. instanceKlass constantPoolOop constants() pool_holder() klassVTable Embedded klassITable Embedded Embedded statics M. Dmitriev. Safe class and data evolution in large and long-lived Java (тм) applications. Technical report, Mountain View. 2001
  11. 11. instanceKlass constantPoolOop constants() constantPoolCacheOop cache() pool_holder() klassVTable Embedded klassITable Embedded Embedded statics M. Dmitriev. Safe class and data evolution in large and long-lived Java (тм) applications. Technical report, Mountain View. 2001
  12. 12. instanceKlass constantPoolOop constants() constantPoolCacheOop cache() pool_holder() klassVTable Embedded klassITable Embedded Embedded statics objArrayOop methodOop methods() M. Dmitriev. Safe class and data evolution in large and long-lived Java (тм) applications. Technical report, Mountain View. 2001
  13. 13. instanceKlass constantPoolOop constants() constantPoolCacheOop cache() pool_holder() klassVTable Embedded klassITable Embedded Embedded statics nmethod code() method() constants() objArrayOop methodOop methods() M. Dmitriev. Safe class and data evolution in large and long-lived Java (тм) applications. Technical report, Mountain View. 2001
  14. 14. What if… hotswap++
  15. 15. Dynamic Code Evolution for Java T. Würthinger, C. Wimmer, L. Stadler. 2010
  16. 16. Dynamic Code Evolution for Java T. Würthinger, C. Wimmer, L. Stadler. 2010 Statements
  17. 17. Dynamic Code Evolution for Java T. Würthinger, C. Wimmer, L. Stadler. 2010 Statements Methods
  18. 18. Dynamic Code Evolution for Java T. Würthinger, C. Wimmer, L. Stadler. 2010 Statements Methods Fields
  19. 19. Dynamic Code Evolution for Java T. Würthinger, C. Wimmer, L. Stadler. 2010 Statements Methods Fields Hierarchy
  20. 20. Dynamic Code Evolution for Java T. Würthinger, C. Wimmer, L. Stadler. 2010 Statements Methods Fields Hierarchy
  21. 21. Dynamic Code Evolution for Java T. Würthinger, C. Wimmer, L. Stadler. 2010 Statements Methods Fields Hierarchy + + + Binary-compatible
  22. 22. Dynamic Code Evolution for Java T. Würthinger, C. Wimmer, L. Stadler. 2010 Statements Methods Fields Hierarchy + + + x x x Binary-compatible Binary-incompatible
  23. 23. Classloaders
  24. 24. Class<?> uc1 = User.class; Class<?> uc2 = new DynamicClassLoader().load("com.zt.User"); out.println(uc1.getName()); // com.zt.User out.println(uc2.getName()); // com.zt.User out.println(uc1.getClassLoader()); // sun.misc.Launcher$AppClassLoader@18b4aac2 out.println(uc2.getClassLoader()); // com.zt.DynamicClassLoader@22b4bba7 User.age = 11; out.println((int) ReflectUtil.getStaticFieldValue("age", uc1)); // 11 out.println((int) ReflectUtil.getStaticFieldValue("age", uc2)); // 10 public class User { public static int age = 10; }
  25. 25. Class<?> uc1 = User.class; Class<?> uc2 = new DynamicClassLoader().load("com.zt.User"); out.println(uc1.getName()); // com.zt.User out.println(uc2.getName()); // com.zt.User out.println(uc1.getClassLoader()); // sun.misc.Launcher$AppClassLoader@18b4aac2 out.println(uc2.getClassLoader()); // com.zt.DynamicClassLoader@22b4bba7 User.age = 11; out.println((int) ReflectUtil.getStaticFieldValue("age", uc1)); // 11 out.println((int) ReflectUtil.getStaticFieldValue("age", uc2)); // 10 public class User { public static int age = 10; }
  26. 26. Class<?> uc1 = User.class; Class<?> uc2 = new DynamicClassLoader().load("com.zt.User"); out.println(uc1.getName()); // com.zt.User out.println(uc2.getName()); // com.zt.User out.println(uc1.getClassLoader()); // sun.misc.Launcher$AppClassLoader@18b4aac2 out.println(uc2.getClassLoader()); // com.zt.DynamicClassLoader@22b4bba7 User.age = 11; out.println((int) ReflectUtil.getStaticFieldValue("age", uc1)); // 11 out.println((int) ReflectUtil.getStaticFieldValue("age", uc2)); // 10 public class User { public static int age = 10; }
  27. 27. Class<?> uc1 = User.class; Class<?> uc2 = new DynamicClassLoader().load("com.zt.User"); out.println(uc1.getName()); // com.zt.User out.println(uc2.getName()); // com.zt.User out.println(uc1.getClassLoader()); // sun.misc.Launcher$AppClassLoader@18b4aac2 out.println(uc2.getClassLoader()); // com.zt.DynamicClassLoader@22b4bba7 User.age = 11; out.println((int) ReflectUtil.getStaticFieldValue("age", uc1)); // 11 out.println((int) ReflectUtil.getStaticFieldValue("age", uc2)); // 10 public class User { public static int age = 10; }
  28. 28. Class<?> uc1 = User.class; Class<?> uc2 = new DynamicClassLoader().load("com.zt.User"); out.println(uc1.getName()); // com.zt.User out.println(uc2.getName()); // com.zt.User out.println(uc1.getClassLoader()); // sun.misc.Launcher$AppClassLoader@18b4aac2 out.println(uc2.getClassLoader()); // com.zt.DynamicClassLoader@22b4bba7 User.age = 11; out.println((int) ReflectUtil.getStaticFieldValue("age", uc1)); // 11 out.println((int) ReflectUtil.getStaticFieldValue("age", uc2)); // 10 public class User { public static int age = 10; }
  29. 29. while(true) { Class<?> uc = new DynamicClassLoader().load("com.zt.User"); ReflectUtil.invokeStatic("getHobby", uc); } public class User { public Hobby getHobby() { return Basketball(); } }
  30. 30. while(true) { Class<?> uc = new DynamicClassLoader().load("com.zt.User"); ReflectUtil.invokeStatic("getHobby", uc); } public class User { public Hobby getHobby() { return Basketball(); } }
  31. 31. public static class Context { public HobbyService hobbyService = new HobbyService(); public void init() { hobbyService.user = new User(); anyService.initialize() } }
  32. 32. public static class Context { public HobbyService hobbyService = new HobbyService(); public AnyService anyService = new AnyService(); public void init() { hobbyService.user = new User(); anyService.initialize() } }
  33. 33. public static class Context { public HobbyService hobbyService = new HobbyService(); public AnyService anyService = new AnyService(); public void init() { hobbyService.user = new User(); anyService.initialize() } } while(true) { Class<?> c = new DynamicClassLoader().load("com.zt.Context"); Object context = c.newInstance(); ReflectUtil.invokeMethod("init", context); invokeService(context); }
  34. 34. DynamicClassLoader Context class HobbyService class User class Context object HobbyService object User object Live thread
  35. 35. <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> DEMO
  36. 36. Java agents
  37. 37. ClassFileTransformer ClassA ClassA ClassA0 +field1 +field2 +field3 +method1 +method2 +method3 +method1 +method2 +method3 +field1 +field2 +field3 +proxy_methods A thousand years of productivity: the JRebel story E. Kabanov, V. Vene, 2012
  38. 38. ClassFileTransformer ClassA ClassA ClassA0 +field1 +field2 +field3 +method1 +method2 +method3 +method1 +method2 +method3 +field1 +field2 +field3 +proxy_methods A thousand years of productivity: the JRebel story E. Kabanov, V. Vene, 2012
  39. 39. DEMO
  40. 40. HotSwap
  41. 41. HotSwap Class loaders
  42. 42. HotSwap Class loaders Java agents & instrumentation
  43. 43. anton@zeroturnaround.com @antonarhipov

×