Byteman - Carving up your Java code


Published on

Brown Bag talk I gave on 1st March 2012

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Other stuff == you’re screwed if you aren’t doing DI
  • Maven config needed to put byteman jar in classpath, and spin up a new JVM so that the one running the tests doesn’t get polluted
  • Byteman - Carving up your Java code

    1. 1. Byteman - Carving up your Java code Chris Sinjakli
    2. 2. A tracing/debugging tool Runtime manipulation of Java code
    3. 3. Java Agent API Muck around with the bytecode to your heart’s content
    4. 4. Java Agent API package java.lang.instrument; interface ClassFileTransformer { byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer); }
    5. 5. Who does this? • About a million tutorials – Usually print the class name – At best adding simple trace code to methods • Newer, cooler mocking frameworks – Powermock, Mockito, JMockit – Better approach then JMock & friends (which use Proxy + CGLIB) – Mock final classes/methods, plus other stuff • Pure Java profilers?
    6. 6. Not that convenient Who wants to spend their time dealing with bytecode?
    7. 7. Byteman Muck around with the Java code to your heart’s content
    8. 8. How? • Specify byteman.jar as a Java Agent when you start your app • Provide a Byteman rule script • Can provide these scripts later (to a running app) – app must be started with Byteman listener
    9. 9. Simple program package class AppMain { public static void main(String[] args) { for (int i = 0; i < args.length; i++) { System.out.println(args[i]); } } }
    10. 10. Run it > java foo bar baz foo bar baz >
    11. 11. Byteman rule script RULE trace main entry CLASS AppMain METHOD main AT ENTRY IF true DO traceln("entering main") ENDRULE
    12. 12. Byteman rule script RULE trace main exit CLASS AppMain METHOD main AT EXIT IF true DO traceln("exiting main") ENDRULE
    13. 13. Run it > java - javaagent:byteman.jar=script:appmain.btm org.m y.AppMain foo bar baz entering main foo bar baz exiting main >
    14. 14. Worth mentioning • You can use it on classes you don’t have the source for • You can even use this on core Java classes (java.lang) – Byteman makes you confirm • Works on interfaces too (all implementing classes get your injected code) • Much more sophisticated rule scripts – Different “AT” points in method – “IF” statements that do something – Access to local variables (eg “AFTER WRITE $foo”)
    15. 15. Testing
    16. 16. Testing support • Comes with a JUnit Runner • Define the rules (from earlier scripts) as test annotations • Useful for fault injection (integration tests where you’re not mocking everything out?)
    17. 17. Testing support @Test @BMRule(name=“foo”, targetClass = “FileInputStream”, targetMethod=“<init>(File)”, condition=“$1.getName().equals(“doesnt_exist.txt”)”, action=“throw new FileNotFoundException(“It’s not there!”)”) public void testReadFile() { ... myClass.processFile(“doesnt_exist.txt”); // Throws an exception ... }
    18. 18. Testing support • Rule in previous example will only be in place for that test – Can annotate class instead to apply to all tests • There’s also @BMScript to import external rule scripts • Relatively simple to run with maven (config samples on website)
    19. 19. Summary • Seems cool • Not sure what I’d actually use it for • Integration tests most likely candidate
    20. 20. Questions?