Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Oredev 2015 - Taming Java Agents

1,444 views

Published on

Java agents are pluggable self contained components that run embedded in a JVM and intercept the classloading process. They were introduced in Java 5 along with the powerful java.lang.instrument package. Java agents can be loaded statically at startup or dynamically (programmatically) at runtime to attach to a running process.

Java agents were an awesome addition to the JVM as it opened a lot of opportunities for tool designers and changed Java tooling landscape quite drastically. In conjunction with Java bytecode manipulation libraries it is now possible to do amazing things to Java classes: we can experiment with programming models, redefine classes at runtime, record execution flow, etc.

I’d like to give an overview of Java agents’ functionality along with the usage examples and real world experiences. You will learn, how to implement an agent and apply Instrumentation API in combination with bytecode manipulation libraries to solve interesting tasks.

Published in: Technology
  • Be the first to comment

Oredev 2015 - Taming Java Agents

  1. 1. Taming Java Agents @antonarhipov
  2. 2. Me Anton Arhipov @antonarhipov anton@zeroturnaround.com ZeroTurnaround JRebel, XRebel
  3. 3. Agenda • Overview of Java agent technology • Instrumentation API • Attach API • HacksApplications http://xkcd.com/138/
  4. 4. BTrace
  5. 5. Pretty much every APM tool today uses Java Agents to instrument the application
  6. 6. A lightweight profiler for Java web apps
  7. 7. A lightweight profiler for Java web apps
  8. 8. A lightweight profiler for Java web apps
  9. 9. A lightweight profiler for Java web apps
  10. 10. A lightweight profiler for Java web apps
  11. 11. A lightweight profiler for Java web apps
  12. 12. my.war ClassLoader getResource("hello.html"); read("src/main/.../hello.html"); rebel.xml • Maps the running application to IDE workspace • Reloads Java classes and framework configurations in a running JVM process
  13. 13. This slide is intentionally left blank
  14. 14. public static void main(String[] args) {
 for (String arg : args) {
 new Thread(new Runnable() {
 public void run() {
 //....
 }
 }).start(); Java app
  15. 15. public static void main(String[] args) {
 for (String arg : args) {
 new Thread(new Runnable() {
 public void run() {
 //.....
 }
 }).start(); RULE  trace  thread  start   CLASS  java.lang.Thread   METHOD  start()   IF  true   DO  traceln("***  start  for  thread:  "+  $0.getName())   ENDRULE Java app Byteman rule
  16. 16. public static void main(String[] args) {
 for (String arg : args) {
 new Thread(new Runnable() {
 public void run() {
 //.....
 }
 }).start(); RULE  trace  thread  start   CLASS  java.lang.Thread   METHOD  start()   IF  true   DO  traceln("***  start  for  thread:  "+  $0.getName())   ENDRULE > java -javaagent:byteman.jar=script:thread.btm,boot:byteman.jar -Dorg.jboss.byteman.transform.all org.my.AppMain2 foo bar baz *** start for thread: foo foo *** start for thread: bar bar *** start for thread: baz baz Java app Byteman rule
  17. 17. public static void main(String[] args) {
 for (String arg : args) {
 new Thread(new Runnable() {
 public void run() {
 //.....
 }
 }).start(); RULE  trace  thread  start   CLASS  java.lang.Thread   METHOD  start()   IF  true   DO  traceln("***  start  for  thread:  "+  $0.getName())   ENDRULE Java app Byteman rule
  18. 18. public static void main(String[] args) {
 for (String arg : args) {
 new Thread(new Runnable() {
 public void run() {
 //.....
 }
 }).start(); RULE  trace  thread  start   CLASS  java.lang.Thread   METHOD  start()   IF  true   DO  traceln("***  start  for  thread:  "+  $0.getName())   ENDRULE > java -classpath byteman-install.jar org.jboss.byteman.agent.install.Install 13101 Java app Byteman rule Install agent:
  19. 19. public static void main(String[] args) {
 for (String arg : args) {
 new Thread(new Runnable() {
 public void run() {
 //.....
 }
 }).start(); RULE  trace  thread  start   CLASS  java.lang.Thread   METHOD  start()   IF  true   DO  traceln("***  start  for  thread:  "+  $0.getName())   ENDRULE > java -classpath byteman-install.jar org.jboss.byteman.agent.install.Install 13101 Java app Byteman rule > java -classpath byteman-submit.jar org.jboss.byteman.agent.submit.Submit -l thread.btm Install agent: Submit rules:
  20. 20. http://byteman.jboss.org
  21. 21. Java Agent Overview
  22. 22. import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.Instrumentation; public class Agent { public static void premain(String args, Instrumentation inst) { inst.addTransformer(new ClassFileTransformer { … }); } public static void agentmain(String args, Instrumentation inst) { premain(args, inst); } } META-­‐INF/MANIFEST.MF   Premain-­‐Class:  Agent $>  java  –javaagent:agent.jar  application.Main
  23. 23. java.lang.instrument.ClassFileTransformer public class MyTransformer implements ClassFileTransformer { public void byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain pd, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); // transform the bytes as required, // for instance - with Javassist return ct.toBytecode(); } }
  24. 24. Class loading Instrumentation
  25. 25. Class loading ClassFileTransformer ClassFileTransformer ClassFileTransformer Instrumentation
  26. 26. Class loading ClassFileTransformer ClassFileTransformer ClassFileTransformer Javassist ASM Instrumentation Bytebuddy
  27. 27. https://github.com/zeroturnaround/callspy
  28. 28. Instrumentation API
  29. 29. java.lang.instrument.Instrumentation void addTransformer(ClassFileTransformer transformer, boolean canRetransform); void appendToBootstrapClassLoaderSearch(JarFile jarfile); void appendToSystemClassLoaderSearch(JarFile jarfile); Class[] getAllLoadedClasses(); Class[] getInitiatedClasses(ClassLoader loader); void redefineClasses(ClassDefinition... classes); void retransformClasses(Class<?>... classes);
  30. 30. JVM JVM Process 1 Process 2 Agent -cp tools.jar Attach API
  31. 31. • Executed when the agent attaches to the running JVM • Instrumentation parameter is optional • META-INF/MANIFEST.MF is required • Requires support for loading agents in JVM • Allows adding the code to JVM post-factum public static void agentmain(String args, Instrumentation inst)
  32. 32. import com.sun.tools.attach.VirtualMachine; //attach to target VM VirtualMachine vm = VirtualMachine.attach("2177"); //get system properties in the target VM Properties props = vm.getSystemProperties(); //load agent into the VM vm.loadAgent("agent.jar", "arg1=x,arg2=y"); //detach from VM vm.detach(); http://docs.oracle.com/javase/7/docs/jdk/api/attach/spec/com/sun/tools/attach/VirtualMachine.html
  33. 33. https://gist.github.com/nickman/6494990 https://github.com/antonarhipov/attach-and-transform-with-mbeans
  34. 34. https://speakerdeck.com/antonarhipov http://www.slideshare.net/arhan @antonarhipov anton@zeroturnaround.com
  35. 35. Resources http://byteman.jboss.org http://www.javassist.org https://github.com/zeroturnaround/callspy https://github.com/antonarhipov/attach-and-transform-with-mbeans https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package- summary.html http://docs.oracle.com/javase/8/docs/jdk/api/attach/spec/com/sun/tools/ attach/VirtualMachine.html http://asm.ow2.org/ http://bytebuddy.net/

×