Magic Development with Aspects (AppDevCon 2017)

Magic Development with Aspects (AppDevCon 2017)

Cf95f93e78f6d6dd0630049396f723c6?s=128

Xavier Gouchet

March 16, 2017
Tweet

Transcript

  1. Magic development with Aspects Initiation to Aspect Oriented Programming App

    Dev Con 2017 - Amsterdam
  2. About... Xavier F. Gouchet Android Architect Jenkins/Sonar Admin Bash /

    Python tools dev Bad Puns Advocate @xgouchet on Github, StackOverflow, Twitter, …
  3. Goal for the afternoon What’s AOP The theory, and motivation

    How does it work A bit of technical details on byte code and compilation Concrete examples The part where you do the work and I relax… or not. @xgouchet
  4. “ “Let's start at the very beginning (A very good

    place to start)” Julie Andrews @xgouchet
  5. It’s NOT ... ◎ A new programming language ◎ Something

    to replace OOP ◎ The solution to all your problems ! @xgouchet
  6. It is a tool to ... ◎ Enhance modularity ◎

    Separate cross cutting concerns ◎ Focus on business logic ◎ Reduce noise in the source code @xgouchet
  7. Cross-cutting concerns ? Any concern that is not business logic

    and appears everywhere @xgouchet
  8. Cross-cutting concerns Logging Performances Security Transactions Validation Serialisation Cache Notification

    Multithreading Memoization @xgouchet
  9. “ “Let me tell you a story (to chill the

    bones)” Iron Maiden @xgouchet
  10. void foo() { Log.v("Tag", "foo"); beginTransaction(); try { bar(); //

    ... setTransactionSuccessful(); } catch (Exception e) { reportError(e); } finally { endTransaction(); } Log.v("Tag", "foo done"); } Before / After
  11. void foo() { Log.v("Tag", "foo"); beginTransaction(); try { bar(); //

    ... setTransactionSuccessful(); } catch (Exception e) { reportError(e); } finally { endTransaction(); } Log.v("Tag", "foo done"); } Before / After
  12. void foo() { Log.v("Tag", "foo"); beginTransaction(); try { bar(); //

    ... setTransactionSuccessful(); } catch (Exception e) { reportError(e); } finally { endTransaction(); } Log.v("Tag", "foo done"); } Before / After
  13. void foo() { Log.v("Tag", "foo"); beginTransaction(); try { bar(); //

    ... setTransactionSuccessful(); } catch (Exception e) { reportError(e); } finally { endTransaction(); } Log.v("Tag", "foo done"); } Before / After
  14. void foo() { Log.v("Tag", "foo"); beginTransaction(); try { bar(); //

    ... setTransactionSuccessful(); } catch (Exception e) { reportError(e); } finally { endTransaction(); } Log.v("Tag", "foo done"); } Before / After
  15. void foo() { Log.v("Tag", "foo"); beginTransaction(); try { bar(); //

    ... setTransactionSuccessful(); } catch (Exception e) { reportError(e); } finally { endTransaction(); } Log.v("Tag", "foo done"); } Before / After
  16. @Trace @SafeTransaction void foo() { bar(); // ... } Before

    / After
  17. “ “I've been browsing… (... inspectin’)” Weird Al Yankovic @xgouchet

  18. input[type=text] { font-family: monospace; } blockquote:before { content: '\201C'; font-size:

    300%; font-family: serif; } #nav-home p { color: #FF4630; cursor: pointer; } .contact img:hover { border: 1px #004080; } CSS + HTML
  19. CSS Attributes Changes in appearance applied to … Elements Nodes

    in the source code , defined by … Selectors Rules and patterns @xgouchet
  20. “ “If you know how to use CSS, Then you

    know how to use AOP” …me @xgouchet
  21. Pointcuts Rules and patterns JoinPoints Positions in the source code

    , defined by … Advices Changes in behavior applied to … Aspects @xgouchet
  22. Advice New behavior (=code) @xgouchet

  23. JoinPoint Almost every selectable step in bytecode execution @xgouchet

  24. Pointcuts Description of a (list of) joinpoints where an advice

    should be applied @xgouchet
  25. “ “You can knit a sweater by the fireside” The

    Beatles @xgouchet
  26. Bytecode weaving AspectJ @xgouchet

  27. Code Weaving class Foo {…} class Bar {…} class Baz

    {…} class Bal {…} @xgouchet
  28. “ “It's time to get our hands dirty” Natalie Grant

    @xgouchet
  29. github.com/xgouchet/magic-appdevcon

  30. Logging The “Hello World” of AOP @xgouchet

  31. public Foo(); Signature: ()V Code: Stack=1, Locals=1, Args_size=1 0: aload_0

    1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 public java.lang.String getBar(); Signature: ()Ljava/lang/String; Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: getfield #2; //Field bar:Ljava/lang/String; 4: areturn LineNumberTable: line 5: 0 public void setBar(java.lang.String); Signature: (Ljava/lang/String;)V Code: Stack=2, Locals=2, Args_size=2 0: aload_0 1: aload_1 2: putfield #2; //Field bar:Ljava/lang/String; 5: return LineNumberTable: line 8: 0 line 9: 5 } JD-GUI : http://jd.benow.ca/ But what’s going on really ? @xgouchet
  32. Monitoring Let’s measure things… @xgouchet

  33. Retry Because sh*t happens @xgouchet

  34. Threads Because #PerfMatters @xgouchet

  35. Compile Checks Too many rules to remember @xgouchet

  36. Aspects Order Finer control of all your aspects @xgouchet

  37. Memoization Because computing is hard @xgouchet

  38. Object Pool Hack your constructors @xgouchet

  39. It’s just the beginning of the journey - Many other

    pointcuts - Inter-type declarations - Change class hierarchy - Add fields - Patch jar files @xgouchet
  40. “ “It’s a kind of magic” Queen @xgouchet

  41. Wizardry or Witchcraft @Aspect public class PreventNPEAspect { @Pointcut("within(com.example.model.*)") public

    void withinModelClass() {} @Around("withinModelClass() && execution(* *(..))") public void advice(ProceeJoinPoint jp) { Object[] args = jp.getArgs(); for (int i = 0; i < args.length; i++) { if (args[i] == null) { args[i] = ""; } } jp.proceed(args); } }
  42. Wizardry or Witchcraft @Aspect public class PreventNPEAspect { @Around("execution(@PreventStringNPE *

    *(..))") public void advice(ProceeJoinPoint jp) { Object[] args = jp.getArgs(); for (int i = 0; i < args.length; i++) { if (args[i] == null) { args[i] = ""; } } jp.proceed(args); } }
  43. “ “I wanna find some answers I wanna ask for

    some help ” Bruce Springsteen @xgouchet
  44. FAQ ◎ What about stack traces ? Caused by: java.lang.RuntimeException

    at com.sample.aspectMyAspect.myAdvice(MyAspect.java:666) at com.app.model.Foo.bar(Foo.java:69) at com.app.model.Foo.<init>(Foo.java:42) at java.lang.Class.newInstance(Native Method) <9 more> ◎ What about breakpoints ? Stepping through your code is ok ◎ What about proguard ? Obfuscation performed after weaving @xgouchet
  45. “ “Forever in debt to your priceless advice” Nirvana @xgouchet

  46. Bad practices and code smells ◎ Pokemon (gotta catch’em all)

    ◎ Wizard of Oz (pay no attention to the man behind the curtain) ◎ Dr Octopus (my left tentacle doesn’t know what my right is doin’) ◎ Inception (aspects within aspects …) ◎ MacGyver (the swiss army knife @xgouchet
  47. Things to remember ◎ Focus on Cross Cutting concerns ◎

    If you can do it more easily with OOP don’t use AOP ◎ You can only weave code you own @xgouchet
  48. Writing Aspects… ◎ Inheritance, abstracts, generics, inner classes… ◎ Unit

    tests ◎ Android flavors ◎ AOP is real programming @xgouchet
  49. “ “There’s somethin’ we can use, so don't say no”

    Toni Basil @xgouchet
  50. Useful links ◎ Android AspectJ plugin ◦ https://github.com/deezer/Android-Aspectj-Plugin ◎ Counsel

    ◦ https://github.com/deezer/Counsel ◎ AspectJ Documentation ◦ https://eclipse.org/aspectj/doc/next/progguide/ ◎ Java Bytecode Viewer : JD-GUI ◦ http://jd.benow.ca/ @xgouchet
  51. https://speakerdeck.com/xgouchet Thanks for listening! Any question ? Deezer’s hiring http://jobs.deezer.com