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 craft of meta programming on JVM

782 views

Published on

Metaprogramming is a key tool of many Java frameworks, such as Spring and Hibernate. In this talk we will cover how metaprogramming can be implemented on JVM. We’ll look at annotations, reflection, bytecode manipulation and cover metaprogramming patterns you can successfully apply in your projects.

Published in: Software
  • Be the first to comment

The craft of meta programming on JVM

  1. 1. The Craft of Metaprogramming on JVM Igor Khotin E-mail: khotin@gmx.com
  2. 2. Background ● 15+ years in the IT industry ● 10+ years with Java ● Flexible design promoter After deploymentDeploying...
  3. 3. Meta Tricks Code
  4. 4. MetaData
  5. 5. MetaCode
  6. 6. Translators Domain-Specific Languages Code Instrumentation Preprocessors
  7. 7. Translators Domain-Specific Languages Code Instrumentation Preprocessors
  8. 8. LISP (defmacro setq-reversible (e1 e2 d) (case d (:normal (list 'setq e1 e2)) (:backward (list 'setq e2 e1)) (t (error ...))))
  9. 9. bash `backquotes`
  10. 10. JavaScript eval()
  11. 11. Java Motherf***er! Do you code it?
  12. 12. ClassLoader
  13. 13. Changing the bytecode
  14. 14. Just a hack
  15. 15. Code that live by itself
  16. 16. Backbone for many products
  17. 17. Boilerplate
  18. 18. Meta Tricks Code
  19. 19. Annotations Providing metadata on code since Java 1.5
  20. 20. Reflection Know your structure
  21. 21. ● Scannotation ● Reflections Scan and metadata
  22. 22. and now the bytecode time!!!
  23. 23. ● Compile-time ● Load-time ● Run-time Time?
  24. 24. Java Agent ● Ability to modify bytecode ● Not affecting the source ● Transformation handlers ● Special app startup process ● Since Java 1.5
  25. 25. Java Debugging Interface ● Limited ability to reload classes ●
  26. 26. ASM ● Event-based visitors API ● Object-based model API ● Fast ● Anything is possible
  27. 27. ● Byte Code Engineering Library ● Object-model API ● Good for static code analysis ● used by findbugs BCEL
  28. 28. ● Java Assistanct ● JBoss subproject ● High-level bytecode manipulation ● Includes simple Java compiler JAssist
  29. 29. ● Java Assistanct ● JBoss subproject ● High-level bytecode manipulation ● Includes simple Java compiler ● Simple ● Slower than ASM ● Limited capabilities compared to ASM JAssist
  30. 30. ● Conceptually high-level ● Manages cross-cutting concerns ● Uses ASM for bytecode-level manipulation AspectJ
  31. 31. ● Introduce Interface (or Superclass) ● Change visibility ● Add new method ● Add new field ● Replace method body ● Merge two classes into one Class Transformations
  32. 32. ● Insert code before/after ● Replace method call ● Replace field access ● Inline method Method Transformations
  33. 33. ● @Before ● @After ● @Around Aspects
  34. 34. Proxy and Lazy
  35. 35. Meta Tricks Code
  36. 36. @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Command { String value(); } Command
  37. 37. @Command("hi") public class Hi { public void exec() { System.out.println(this.getClass().getName()); System.out.println("Hello annotations!"); } } Hi
  38. 38. Reflections reflections = new Reflections("meta"); Set<Class<?>> annotated = reflections .getTypesAnnotatedWith(Command.class); for(Class c: annotated) { Command ca = (Command)c.getAnnotation( Command.class); System.out.println("[" + c.getSimpleName() + "] -> " + ca.value()); } Reflections
  39. 39. Class commandClass = map.get(cmd); Object command = commandClass.newInstance(); Method exec = command.getClass().getMethod(“exec”); exec.invoke(command); Reflection
  40. 40. public Class enhance(Class target) { ClassPool cp = new ClassPool(true); CtClass ctSuper = cp.get(target.getName()); CtClass ctClass = cp.makeClass("meta.InfectedClass"); ctClass.setSuperclass(ctSuper); CtMethod execMethod = CtNewMethod.make( "public void exec() {System.out.print("[ENHANCED] ");super.exec();}", ctClass); ctClass.addMethod(execMethod); ctClass.writeFile(); return ctClass.toClass(); } JAssist
  41. 41. Eval.me( '2 + 2' ) Groovy eval()
  42. 42. def list = ['Java', 'Groovy', 'Scala'] LanguageList() { def mc = new ExpandoMetaClass(LanguageList, false, true) mc.initialize() this.metaClass = mc } def methodMissing(String name, args) { // Intercept method that starts with find. if (name.startsWith("find")) { def result = list.find { it == name[4..-1] } // Add new method to class with metaClass. this.metaClass."$name" = {-> result + "[cache]" } result } else { throw new MissingMethodException( name, this.class, args) } } Groovy missing method
  43. 43. Questions? Igor Khotin E-mail: khotin@gmx.com Blog: www.ikhotin.com Twitter: chaostarter

×