Slide 1

Slide 1 text

REFLECTION NO REFLECTION STÉPHANE

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

WHAT IS SLOW IN 
 REFLECTION ?

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

BYTECODE WEAVING On Android : static byte code weaving 
 performed right after compilation. We got a full stack : the INJECTS projects
 github.com/stephanenicolas/injects

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

๏ 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

Slide 17

Slide 17 text

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.

Slide 18

Slide 18 text

๏ 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

Slide 19

Slide 19 text

ANNOTATION PROCESSING Generated Java Source Annotation Processing Compiler

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

RNЯ Generate reflection like code
 via annotation processing

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

Step 1 : Annotation processing time RNЯ classes Annotation Processing Compiler Annotation
 Processor using reflection Generated 
 Java Source

Slide 26

Slide 26 text

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.

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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.

Slide 30

Slide 30 text

Step 3 : Write access Generate code 
 to fill RNЯ classes Annotation Processing Compiler App RNЯ 
 Reflection Class 
 Reflectors

Slide 31

Slide 31 text

RNЯ reflectors Field access Methods 
 invocation Constructors invocation

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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.

Slide 34

Slide 34 text

RNЯ Guice Guice RNЯ Guice scan classes 
 members Processing access field invoke methods create instances

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

RNЯ Guice fork : results

Slide 38

Slide 38 text

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.

Slide 39

Slide 39 text

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.

Slide 40

Slide 40 text

Java
 Source Byte
 Code App JVM Compiler The solution might be elsewhere… AOT compilation +
 JIT reflection code

Slide 41

Slide 41 text

Thanks for attending 
 this reflection on reflection Questions ? Comments ?