Programmer's Survival Kit:  Code Injection for Troubleshooting   Jakub Holý, Iterate AS http://bit.ly/codeinject
Learn code injection – it can save your day!
The power of code injection Code injection  ∈  aspect-oriented programming (AOP*): <ul><li>Modify existing  binary  classe...
Inject the same code into one or multiple places (DRY)
Lifecycle: Write aspect > weave > run </li></ul>(For AOP check Wikipedia or Spring docs.) * I will use AOP and Code Inject...
3 tools, 2 (3) examples
1. The omnipresent Java Proxy <ul><li>In JRE – java.lang.reflect.*
Not true AOP, applied manually
Can only proxy interfaces
Verbose </li></ul>
Client JDBC code: PreparedStatement rawStmt = c.prepareStatement( &quot;INSERT ...&quot; ); PreparedStatement loggingStmt ...
class  BatchLogger  implements   InvocationHandler  { public  Object  invoke (Object proxy , Method method , Object[] args...
class  BatchLogger  implements   InvocationHandler  { public  Object  invoke (Object proxy , Method method , Object[] args...
<ul><li>No run-time dependencies
Build-time weaving
Upcoming SlideShare
Loading in …5
×

Programmer's Survival Kit: Code Injection for Troubleshooting, JavaZone 2011

990 views

Published on

This presentation is aimed at giving you the knowledge of code injection that you may (or I should rather say "will") need and at persuading you that learning basics of code injection is really worth the little of your time that it takes. I'll present three different real-world cases where code injection came to my rescue, solving each one with a different tool, fitting best the constraints at hand. I'll also provide you with resources to learn the basics and tools easily and quickly.
This is a practical presentation; we won't introduce AOP and will explain code injection only briefly, plunging right into the tools and how they can help you.

See http://theholyjava.wordpress.com/2011/09/07/practical-introduction-into-code-injection-with-aspectj-javassist-and-java-proxy/

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
990
On SlideShare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • Short time -&gt; for detailed explanation and more examples see the URL
  • The key message of this presentation: Every developer should know and be able to use AOP for earlier or later it will be incredibely useful to him/her.
  • The great things about code injection
  • - !!! Start examples by asking how they would solve the challenge - Not time to go through examples in detail -&gt; check blog, source codes. I will show 3 different tools - with their pros &amp; cons - on 2 (3) real-world use cases. - each useful under different conditions
  • 1. What is (Java) proxy 2. Pros: Available everywhere. Can be set up at runtime. Cons: Not true AOP – only interfaces, apply manually. Only at runtime. Very limited and verbose.
  • Case: Inserting 1000s of rows using batches of ~100 for efficiency and it&apos;s failing for one of the batches but the exception doesn&apos;t tell you which batch and what data =&gt; can&apos;t find out which record of the 1000s is causing it. =&gt; You&apos;d need to remember data going into each batch and log them upon failure. =&gt; Use a dynamic proxy ...
  • To create a proxy you need to implement an InvocationHandler: - 1 method, invoke , taking reflect.* objects with info about the invocation, called for each method - you can use it to delegate the call to the proxied target object So far we just delegate to the original object.
  • Write code to add some behavior.
  • Having no run-time dependencies on Javassist may be crucial if your organization doesn&apos;t easily approve the deployment of new (open-source) libraries – or if you want to keep your application small.
  • Compile- x build-time weaving Powerful – add members, inject into static methods, ... Eclipse AJDT
  • The less powerful but easier to use @Aspect syntax.
  • Quite less powerful than AspectJ Requires no runtime dependencies =&gt; no need to ask permission for another OOS library (a legal issue in large corporations) See TBD:LINK2BLOG
  • Programmer's Survival Kit: Code Injection for Troubleshooting, JavaZone 2011

    1. 1. Programmer's Survival Kit: Code Injection for Troubleshooting Jakub Holý, Iterate AS http://bit.ly/codeinject
    2. 2. Learn code injection – it can save your day!
    3. 3. The power of code injection Code injection ∈ aspect-oriented programming (AOP*): <ul><li>Modify existing binary classes at build/load time
    4. 4. Inject the same code into one or multiple places (DRY)
    5. 5. Lifecycle: Write aspect > weave > run </li></ul>(For AOP check Wikipedia or Spring docs.) * I will use AOP and Code Injection interchangeably, however inaccurate that is
    6. 6. 3 tools, 2 (3) examples
    7. 7. 1. The omnipresent Java Proxy <ul><li>In JRE – java.lang.reflect.*
    8. 8. Not true AOP, applied manually
    9. 9. Can only proxy interfaces
    10. 10. Verbose </li></ul>
    11. 11. Client JDBC code: PreparedStatement rawStmt = c.prepareStatement( &quot;INSERT ...&quot; ); PreparedStatement loggingStmt = (PreparedStatement) Proxy.newProxyInstance(..., new BatchLogger(rawStmt)); for ( int i = 0; i < data. length ; i++) { loggingStmt.setString(1, data[i]); loggingStmt.addBatch(); // end a row, start a new one if (isMultipleOfBatchSize(i)) loggingStmt.executeBatch(); // Logs st. on failure } Ex.: Log data of a failed batch (0)
    12. 12. class BatchLogger implements InvocationHandler { public Object invoke (Object proxy , Method method , Object[] args) throws Throwable { try { return method.invoke ( this . target , args); } catch (BatchUpdateException e) { } } ... Ex.: Log data of a failed batch (1)
    13. 13. class BatchLogger implements InvocationHandler { public Object invoke (Object proxy , Method method , Object[] args) throws Throwable { if (isSetSomething(method)) { /* remember args = column */ } if (isAddBatch(method)) { /*add a new row */ } try { return method.invoke ( this . target , args); } catch (BatchUpdateException e) { /*log remembered rows in the batch*/ throw e; } finally { if (isExecuteBatch(method)) { /*reset remembered rows */ } } } ... Ex.: Log data of a failed batch (2)
    14. 14. <ul><li>No run-time dependencies
    15. 15. Build-time weaving
    16. 16. Somehow low-level
    17. 17. Limited power
    18. 18. Weaving manually / custom Ant task </li></ul>For an example, see the accompanying source code project and blog post. For an alternative w/o most cons see GluonJ. 2. The independent Javassist
    19. 19. 3. The almighty AspectJ <ul><li>Full-fledged AOP
    20. 20. Build-time/load-time weaving
    21. 21. Weaving with Ant or Java agentlib
    22. 22. Depends on AspectJ libraries at the run-time </li></ul>
    23. 23. @Aspect public class LoggingAspect { @Around ( &quot;execution(private void TooQuiet3rdPartyClass.failingMethod(Object))&quot; ) public Object interceptAndLog(ProceedingJoinPoint invocation) throws Throwable { try { return invocation.proceed(); } catch (Exception e) { throw new RuntimeException( &quot;Failed for: &quot; + invocation.getArgs()[0] , e); } } } Ex.: Include argument in exception
    24. 24. What it can do <ul><li>Troubleshooting: Improved logging, ...
    25. 25. Cross-cutting concerns: Security, transactions, traits, ... - see EJBs
    26. 26. Testing: code coverage, mutation testing, ...
    27. 27. Code injection/AOP is great but don't overuse it – see Glassbox.sf.net </li></ul>
    28. 28. Thank you! <ul><li>Much more detailed explanation with more topics and a link to full source codes:
    29. 29. http://bit.ly/codeinject
    30. 30. feedback via the blog post's comments welcomed! </li></ul>
    31. 31. Bonus slides
    32. 32. // Advice my.example.TargetClass.myMethod(..) with a before and after advices final ClassPool pool = ClassPool. getDefault (); final CtClass compiledClass = pool.get( &quot;my.example.TargetClass&quot; ); final CtMethod method = compiledClass .getDeclaredMethod( &quot;myMethod&quot; ); method.addLocalVariable( &quot;startMs&quot; , CtClass. longType ); method.insertBefore( &quot;startMs = System.currentTimeMillis();&quot; ); method.insertAfter( &quot;{final long endMs = System.currentTimeMillis(); System.out.println(&quot;Executed in ms: &quot; + (endMs-startMs));}&quot; ); compiledClass.writeFile( &quot;/tmp/javassist/modifiedClassesFolder&quot; ); // Enjoy the new / tmp /javassist/my/example/TargetClass.class Ex: Performance monitoring with Javassist

    ×