oredev 2015 - taming java agents

40
Taming Java Agents @antonarhipov

Upload: anton-arhipov

Post on 16-Jan-2017

1.226 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: Oredev 2015 - Taming Java Agents

Taming Java Agents@antonarhipov

Page 2: Oredev 2015 - Taming Java Agents

MeAnton Arhipov

@antonarhipov

[email protected]

ZeroTurnaround

JRebel, XRebel

Page 3: Oredev 2015 - Taming Java Agents
Page 4: Oredev 2015 - Taming Java Agents

Agenda

• Overview of Java agent technology

• Instrumentation API

• Attach API

• HacksApplicationshttp://xkcd.com/138/

Page 5: Oredev 2015 - Taming Java Agents

BTrace

Page 6: Oredev 2015 - Taming Java Agents

Pretty much every APM tool today uses Java Agents to instrument the application

Page 7: Oredev 2015 - Taming Java Agents

A lightweight profiler for Java web apps

Page 8: Oredev 2015 - Taming Java Agents

A lightweight profiler for Java web apps

Page 9: Oredev 2015 - Taming Java Agents

A lightweight profiler for Java web apps

Page 10: Oredev 2015 - Taming Java Agents

A lightweight profiler for Java web apps

Page 11: Oredev 2015 - Taming Java Agents

A lightweight profiler for Java web apps

Page 12: Oredev 2015 - Taming Java Agents

A lightweight profiler for Java web apps

Page 13: Oredev 2015 - Taming Java Agents
Page 14: Oredev 2015 - Taming Java Agents
Page 15: Oredev 2015 - Taming Java Agents
Page 16: Oredev 2015 - Taming Java Agents

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

Page 17: Oredev 2015 - Taming Java Agents

This slide is intentionally left blank

Page 18: Oredev 2015 - Taming Java Agents
Page 19: Oredev 2015 - Taming Java Agents

public static void main(String[] args) { for (String arg : args) { new Thread(new Runnable() { public void run() { //.... } }).start();

Java app

Page 20: Oredev 2015 - Taming Java Agents

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

Bytemanrule

Page 21: Oredev 2015 - Taming Java Agents

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

Bytemanrule

Page 22: Oredev 2015 - Taming Java Agents

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

Bytemanrule

Page 23: Oredev 2015 - Taming Java Agents

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

Bytemanrule

Install agent:

Page 24: Oredev 2015 - Taming Java Agents

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

Bytemanrule

> java -classpath byteman-submit.jar \ org.jboss.byteman.agent.submit.Submit -l thread.btm

Install agent:

Submit rules:

Page 25: Oredev 2015 - Taming Java Agents

http://byteman.jboss.org

Page 26: Oredev 2015 - Taming Java Agents

Java Agent Overview

Page 27: Oredev 2015 - Taming Java Agents

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

Page 28: Oredev 2015 - Taming Java Agents

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

Page 29: Oredev 2015 - Taming Java Agents

Class loading

Instrumentation

Page 30: Oredev 2015 - Taming Java Agents

Class loading

ClassFileTransformer

ClassFileTransformer

ClassFileTransformer

Instrumentation

Page 31: Oredev 2015 - Taming Java Agents

Class loading

ClassFileTransformer

ClassFileTransformer

ClassFileTransformer

Javassist

ASM

Instrumentation

Bytebuddy

Page 32: Oredev 2015 - Taming Java Agents

https://github.com/zeroturnaround/callspy

Page 33: Oredev 2015 - Taming Java Agents

Instrumentation API

Page 34: Oredev 2015 - Taming Java Agents

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

Page 35: Oredev 2015 - Taming Java Agents

JVM JVM

Process 1 Process 2

Agent

-cp tools.jar

Attach API

Page 36: Oredev 2015 - Taming Java Agents

• 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)

Page 37: Oredev 2015 - Taming Java Agents

import com.sun.tools.attach.VirtualMachine;

//attach to target VMVirtualMachine vm = VirtualMachine.attach("2177");

//get system properties in the target VMProperties props = vm.getSystemProperties();

//load agent into the VMvm.loadAgent("agent.jar", "arg1=x,arg2=y");

//detach from VMvm.detach();

http://docs.oracle.com/javase/7/docs/jdk/api/attach/spec/com/sun/tools/attach/VirtualMachine.html

Page 38: Oredev 2015 - Taming Java Agents

https://gist.github.com/nickman/6494990

https://github.com/antonarhipov/attach-and-transform-with-mbeans

Page 39: Oredev 2015 - Taming Java Agents

https://speakerdeck.com/antonarhipov

http://www.slideshare.net/arhan

@[email protected]

Page 40: Oredev 2015 - Taming Java Agents

Resourceshttp://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/