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

Reflection No Reflection

Reflection No Reflection

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

stephanenicolas

August 27, 2015
Tweet

More Decks by stephanenicolas

Other Decks in Programming

Transcript

  1. REFLECTION NO
    REFLECTION
    STÉPHANE

    View Slide

  2. 5IF"OESPJE5FBNJT)JSJOH

    https://jobs.groupon.com/careers/

    View Slide

  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

    View Slide

  4. THE TALK
    • Motivations
    • Reflection
    • Alternatives to reflection
    • RNЯ : reflection no reflection
    • Conclusion
    • Strongly recommend knowledge of:
    • DI & bindings (ButterKnife, Dart, etc.)
    • Annotation processing

    View Slide

  5. ROBOGUICE
    • —> But slow
    • Feature Rich
    • Easy to configure, and use
    • No manual graph definition

    View Slide

  6. 35
    IMPROVED
    PERFORMANCE
    %
    https://speakerdeck.com/stephanenicolas/blender-boosting-guice-with-annotation-processing
    ROBOGUICE 3

    View Slide

  7. But still, 35% improvement is not enough compared to Dagger 1.
    PERFORMANCES OF DI FRAMEWORK
    (all figures in ms / GenyMotion)

    View Slide

  8. REFLECTION
    IS SLOW???
    —> let’s kill reflection completely !

    View Slide

  9. Java

    Source
    Byte

    Code
    App
    JVM
    Compiler
    Reflection
    WHAT’S REFLECTION ?

    View Slide

  10. WHAT’S REFLECTION ?
    Simple and intuitive
    Close to the way devs talk about OO programs

    View Slide

  11. WHAT IS SLOW IN 

    REFLECTION ?

    View Slide

  12. Java

    Source
    Byte

    Code
    App
    JVM
    Compiler
    Reflection
    ALTERNATIVES TO REFLECTION
    Annotation Processing
    ByteCode Weaving
    AST Manipulations

    View Slide

  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

    View Slide

  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.

    View Slide

  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

    View Slide

  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

    View Slide

  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.

    View Slide

  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

    View Slide

  19. ANNOTATION PROCESSING
    Generated Java Source
    Annotation Processing Compiler

    View Slide

  20. In DI & Binding libs
    generated code is used
    to manipulate non
    private members :
    • access fields
    • call methods
    • call constructors
    GENERATED CODE
    —> Like reflection !

    View Slide

  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

    View Slide

  22. RNЯ
    Generate reflection like code

    via annotation processing

    View Slide

  23. View Slide

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

    View Slide

  25. Step 1 : Annotation processing time
    RNЯ classes
    Annotation Processing Compiler
    Annotation

    Processor using
    reflection
    Generated 

    Java Source

    View Slide

  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.

    View Slide

  27. Step 2 : RNЯ accessible at runtime
    Generate code to fill RNЯ classes
    Annotation Processing Compiler App
    RNЯ 

    Reflection

    View Slide

  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‘’)

    View Slide

  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.

    View Slide

  30. Step 3 : Write access
    Generate code 

    to fill RNЯ classes
    Annotation Processing Compiler App
    RNЯ 

    Reflection
    Class 

    Reflectors

    View Slide

  31. RNЯ reflectors
    Field
    access
    Methods 

    invocation
    Constructors
    invocation

    View Slide

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

    View Slide

  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.

    View Slide

  34. RNЯ Guice
    Guice RNЯ Guice
    scan classes 

    members
    Processing
    access field
    invoke methods
    create instances

    View Slide

  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

    View Slide

  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

    View Slide

  37. RNЯ Guice fork : results

    View Slide

  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.

    View Slide

  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.

    View Slide

  40. Java

    Source
    Byte

    Code
    App
    JVM
    Compiler
    The solution might be elsewhere…
    AOT compilation +

    JIT reflection code

    View Slide

  41. Thanks for attending 

    this reflection on reflection
    Questions ?
    Comments ?

    View Slide