Reflection No Reflection

Reflection No Reflection

Talk at DroidCon NY // Devoxx BE
2015
Annotation Processing, Reflection, DI, performances, Guice, RoboGuice

1f9cd9b9bad9aa6115a1ed72433c180d?s=128

stephanenicolas

August 27, 2015
Tweet

Transcript

  1. REFLECTION NO REFLECTION STÉPHANE

  2. 5IF"OESPJE5FBNJT)JSJOH
 https://jobs.groupon.com/careers/

  3. Hey! My name is Stéphane Nicolas. Senior Android Dev @

    Groupon ~20 years of Java coding OSS: RoboSpice, RoboGuice, BoundBox, Injects, Dart, … snicolas stephanenicolas +stephane nicolas
  4. THE TALK • Motivations • Reflection • Alternatives to reflection

    • RNЯ : reflection no reflection • Conclusion • Strongly recommend knowledge of: • DI & bindings (ButterKnife, Dart, etc.) • Annotation processing
  5. ROBOGUICE • —> But slow • Feature Rich • Easy

    to configure, and use • No manual graph definition
  6. 35 IMPROVED PERFORMANCE % https://speakerdeck.com/stephanenicolas/blender-boosting-guice-with-annotation-processing ROBOGUICE 3

  7. But still, 35% improvement is not enough compared to Dagger

    1. PERFORMANCES OF DI FRAMEWORK (all figures in ms / GenyMotion)
  8. REFLECTION IS SLOW??? —> let’s kill reflection completely !

  9. Java
 Source Byte
 Code App JVM Compiler Reflection WHAT’S REFLECTION

    ?
  10. WHAT’S REFLECTION ? Simple and intuitive Close to the way

    devs talk about OO programs
  11. WHAT IS SLOW IN 
 REFLECTION ?

  12. Java
 Source Byte
 Code App JVM Compiler Reflection ALTERNATIVES TO

    REFLECTION Annotation Processing ByteCode Weaving AST Manipulations
  13. BYTECODE WEAVING On Android : static byte code weaving 


    performed right after compilation. We got a full stack : the INJECTS projects
 github.com/stephanenicolas/injects
  14. ๏ Complex libs ๏ Non standard builds 
 —> High

    Maintenance ๏ Only jar & class files, not dex ๏ Jack n’Jill ? 
 —> No one knows about Jayce ๏ Modifications are invisible BYTECODE WEAVING ✓ Simple to use ✓ No boiler plate code ✓ As easy as a gradle plugin ✓ Extremely powerful ✓ ‘de facto standard’ API : Javassist.
  15. AST MANIPULATION Abstract Syntax Trees (AST) : data structures to

    represent Java statements, they are used internally by Java compilers. Lombok for Java : projectlombok.org Hrisey for Android : github.com/mg6maciej/hrisey
  16. ๏ Harder than byte code. ๏ Non standard
 (Android could

    focus on Javac) ๏ Jack n’Jill ? 
 —> No one knows about Jayce ๏ Modifications are invisible ✓ Simple to use ✓ No boiler plate code ✓ As easy as a gradle plugin ✓ Extremely powerful AST MANIPULATION
  17. ANNOTATION PROCESSING Annotation processing allows to generate new code. Some

    boiler plate is needed to invoke it. Here, ButterKnife generates code to bind resources and views to fields of an Activity.
  18. ๏ API is difficult ๏ Impossible to modify code.
 Only

    new code can be generated ๏ Every lib based on reflection
 has to be rewritten ๏ Needs boiler plate 
 to invoke generated code ✓ Simple to use ✓ Java Standard ✓ Relatively powerful ANNOTATION PROCESSING
  19. ANNOTATION PROCESSING Generated Java Source Annotation Processing Compiler

  20. In DI & Binding libs generated code is used to

    manipulate non private members : • access fields • call methods • call constructors GENERATED CODE —> Like reflection !
  21. 1) Make it easy to adapt reflection 
 based Java

    libs to Android. 2) Get the best of reflection (ease) 
 and annotation processing (speed) 3) Hide generated code RNЯ objectives
  22. RNЯ Generate reflection like code
 via annotation processing

  23. None
  24. RNЯ: 3 steps 1. Define RNЯ classes: 100 % compatible

    with reflection
 & fill these data structures during annotation processing time .
 2. Generate code so that RNЯ becomes available at runtime.
 3. Generate code that allows modification of members 
 (access fields, invoke methods and constructors).
  25. Step 1 : Annotation processing time RNЯ classes Annotation Processing

    Compiler Annotation
 Processor using reflection Generated 
 Java Source
  26. Step 1 : Results After this step, Annotation Processor can

    use the reflection API. We manipulate fields, methods, constructors & classes…
 before they are compiled ! Unification of Annotation Processing and Reflection API
 By itself it is an important theoretical achievement in Java.
  27. Step 2 : RNЯ accessible at runtime Generate code to

    fill RNЯ classes Annotation Processing Compiler App RNЯ 
 Reflection
  28. RNЯ classes • They are 100 % compatible with the

    reflection API classes • RNЯ classes are filled during annotation processing • RNЯ classes are generated to become accessible at runtime
 via Class.forName(‘’test.Foo‘’)
  29. Step 2 : Results RNЯ reflection classes : • accessible

    to libs/apps at runtime • provide read-only access to reflection information • are faster than reflection on Android. But they are read-only, unlike native reflection.
  30. Step 3 : Write access Generate code 
 to fill

    RNЯ classes Annotation Processing Compiler App RNЯ 
 Reflection Class 
 Reflectors
  31. RNЯ reflectors Field access Methods 
 invocation Constructors invocation

  32. Step 3 : Results Step 3 extends step 2. Now,

    RNЯ reflection classes : • accessible to libs/apps at runtime • provide read/write access to reflection information • are faster than reflection on Android. (Oh, Btw, there is a little detail that we gently omitted : annotation implementations…And we are proud to have succeeded in doing it.)
  33. RNЯ works, what next ? The general context of research

    on RNЯ was improving DI speed.
 so let’s fork Guice !
 
 It should be as simple as replacing native Reflection with RNЯ reflection.
  34. RNЯ Guice Guice RNЯ Guice scan classes 
 members Processing

    access field invoke methods create instances
  35. RNЯ Guice : Why it failed • Guice uses a

    lot of reflection, many if not all features of reflection
 —>The fork introduced a high volume of changes… and potential bugs. • Reflection is also linked to the compiler at a very low level via class symbolication / class literals : Reflection Compiler Symbole
  36. RNЯ Guice fork : take 2 Minimize the amount of

    changes in Guice to use RNЯ.
 Bypass native reflection for members access via reflectors. And only that. Guice RNЯ Guice scan classes 
 members Processing access field invoke methods create instances
  37. RNЯ Guice fork : results

  38. Conclusions RNЯ - Step 1, unifies Annotation Processing and Reflection

    at compile-time. RNЯ - Step 2 and Step 3 are a generalization of all the work that has been done on Android related to Annotation Processing to circumvent Reflection. RNЯ demonstrates that this approach is feasible.
  39. Conclusions RNЯ, got initiated by our desire to achieve a

    faster DI for Android. We plan to release soon a new version of Guice / RoboGuice based on the RNЯ reflectors. Not based on the full RNЯ solution.
  40. Java
 Source Byte
 Code App JVM Compiler The solution might

    be elsewhere… AOT compilation +
 JIT reflection code
  41. Thanks for attending 
 this reflection on reflection Questions ?

    Comments ?