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

Magic Development with Aspects (AppDevCon 2017)

Magic Development with Aspects (AppDevCon 2017)

Xavier Gouchet

March 16, 2017
Tweet

More Decks by Xavier Gouchet

Other Decks in Programming

Transcript

  1. Magic development
    with Aspects
    Initiation to Aspect Oriented Programming
    App Dev Con 2017 - Amsterdam

    View Slide

  2. About...
    Xavier F. Gouchet
    Android Architect
    Jenkins/Sonar Admin
    Bash / Python tools dev
    Bad Puns Advocate
    @xgouchet on Github,
    StackOverflow, Twitter, …

    View Slide

  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

    View Slide


  4. “Let's start at the very beginning
    (A very good place to start)”
    Julie Andrews
    @xgouchet

    View Slide

  5. It’s NOT ...
    ◎ A new programming language
    ◎ Something to replace OOP
    ◎ The solution to all your problems !
    @xgouchet

    View Slide

  6. It is a tool to ...
    ◎ Enhance modularity
    ◎ Separate cross cutting concerns
    ◎ Focus on business logic
    ◎ Reduce noise in the source code
    @xgouchet

    View Slide

  7. Cross-cutting
    concerns ?
    Any concern
    that is not business logic
    and appears everywhere
    @xgouchet

    View Slide

  8. Cross-cutting concerns
    Logging
    Performances
    Security
    Transactions
    Validation
    Serialisation
    Cache
    Notification
    Multithreading Memoization
    @xgouchet

    View Slide


  9. “Let me tell you a story
    (to chill the bones)”
    Iron Maiden
    @xgouchet

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  16. @Trace
    @SafeTransaction
    void foo() {
    bar();
    // ...
    }
    Before / After

    View Slide


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

    View Slide

  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

    View Slide

  19. CSS
    Attributes
    Changes in
    appearance
    applied to …
    Elements
    Nodes in the
    source code ,
    defined by …
    Selectors
    Rules and patterns
    @xgouchet

    View Slide


  20. “If you know how to use CSS,
    Then you know how to use AOP”
    …me
    @xgouchet

    View Slide

  21. Pointcuts
    Rules and patterns
    JoinPoints
    Positions in the
    source code ,
    defined by …
    Advices
    Changes in
    behavior
    applied to …
    Aspects
    @xgouchet

    View Slide

  22. Advice
    New behavior
    (=code)
    @xgouchet

    View Slide

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

    View Slide

  24. Pointcuts
    Description of a (list of)
    joinpoints where an advice
    should be applied
    @xgouchet

    View Slide


  25. “You can knit a sweater
    by the fireside”
    The Beatles
    @xgouchet

    View Slide

  26. Bytecode
    weaving
    AspectJ
    @xgouchet

    View Slide

  27. Code Weaving
    class Foo
    {…}
    class Bar
    {…}
    class Baz
    {…}
    class Bal
    {…}
    @xgouchet

    View Slide


  28. “It's time to get our hands dirty”
    Natalie Grant
    @xgouchet

    View Slide

  29. github.com/xgouchet/magic-appdevcon

    View Slide

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

    View Slide

  31. public Foo();
    Signature: ()V
    Code:
    Stack=1, Locals=1, Args_size=1
    0: aload_0
    1: invokespecial #1; //Method java/lang/Object."":()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

    View Slide

  32. Monitoring
    Let’s measure things…
    @xgouchet

    View Slide

  33. Retry
    Because sh*t happens
    @xgouchet

    View Slide

  34. Threads
    Because #PerfMatters
    @xgouchet

    View Slide

  35. Compile Checks
    Too many rules to remember
    @xgouchet

    View Slide

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

    View Slide

  37. Memoization
    Because computing is hard
    @xgouchet

    View Slide

  38. Object Pool
    Hack your constructors
    @xgouchet

    View Slide

  39. It’s just the beginning of the journey
    - Many other
    pointcuts
    - Inter-type
    declarations
    - Change class
    hierarchy
    - Add fields
    - Patch jar files
    @xgouchet

    View Slide


  40. “It’s a kind of magic”
    Queen
    @xgouchet

    View Slide

  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);
    }
    }

    View Slide

  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);
    }
    }

    View Slide


  43. “I wanna find some answers
    I wanna ask for some help ”
    Bruce Springsteen
    @xgouchet

    View Slide

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

    View Slide


  45. “Forever in debt
    to your priceless advice”
    Nirvana
    @xgouchet

    View Slide

  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

    View Slide

  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

    View Slide

  48. Writing Aspects…
    ◎ Inheritance, abstracts, generics,
    inner classes…
    ◎ Unit tests
    ◎ Android flavors
    ◎ AOP is real programming
    @xgouchet

    View Slide


  49. “There’s somethin’ we can use,
    so don't say no”
    Toni Basil
    @xgouchet

    View Slide

  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

    View Slide

  51. https://speakerdeck.com/xgouchet
    Thanks for listening!
    Any question ?
    Deezer’s hiring
    http://jobs.deezer.com

    View Slide