A 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 in a fail-safe fashion.
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 in runtime, record execution flow, etc.
The presentation provides 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.
15. Example
1:
Simple
Trace
public
class
Main
{
public
staBc
void
main(String[]
args)
{
for
(int
i
=
0;
i
<
args.length;
i++)
System.out.println(args[i]);
}
}
$
java
Main
1
2
3
1
2
3
16. Example
1:
Simple
Trace
RULE
trace
main
entry
RULE
trace
main
exit
CLASS
Main
CLASS
Main
METHOD
main
METHOD
main
AT
ENTRY
AT
EXIT
IF
true
IF
true
DO
traceln("entering
main")
DO
traceln("exiBng
main")
ENDRULE
ENDRULE
$
java
–javaagent:byteman.jar=script:trace.btm
Main
entering
main
1
2
3
exiBng
main
17. Example
2:
Tracing
Threads
for
(int
i
=
0;
i
<
args.length;
i++)
{
final
String
arg
=
args[i];
Thread
thread
=
new
Thread(arg)
{
public
void
run()
{
System.out.println(arg);
}
};
thread.start();
thread.join();
}
18. Example
2:
Tracing
Threads
RULE
trace
thread
start
CLASS
java.lang.Thread
METHOD
start()
IF
true
DO
traceln("***
start
for
thread
"
+
$0.getName())
ENDRULE
19. Example
2:
Tracing
Threads
$
java
-‐Dorg.jboss.byteman.transform.all
-‐javaagent:byteman.jar=script:thread.btm,boot:byteman.jar
Main
foo
bar
baz
***
start
for
thread
foo
foo
***
start
for
thread
bar
bar
***
start
for
thread
baz
baz
20. Example
3:
Side
Effects
RULE
skip
loop
iteraBon
CLASS
Main
METHOD
main
AFTER
CALL
join
IF
($args[$i]).contains("foo")
DO
$i
=
$i
+
1
;
traceln("skipping
iteraBon
"
+
$i)
ENDRULE
21. Example
4:
Arach
to
Process
BufferedReader
in
=
new
BufferedReader(new
InputStreamReader(System.in));
String
next
=
in.readLine();
while
(next
!=
null
&&
next.length()
>
0
&&
!next.contains("end"))
{
final
String
arg
=
next;
Thread
thread
=
new
Thread(arg)
{
public
void
run()
{
System.out.println(arg);
}
};
thread.start();
thread.join();
next
=
in.readLine();
}
22. Example
4:
Arach
to
Process
$
java
Main
Hello
Hello
$
bminstall.sh
-‐b
–Dorg…
<PID>
$
bmsubmit.sh
script/ex2.btm
install
rule
trace
thread
start
Test
***
start
for
thread
Test
Test
$
bmsubmit.sh
-‐u
script/ex2.btm
uninstall
RULE
trace
thread
start
Test
Test
end
$
23. Arach
API
VirtualMachine
vm
=
VirtualMachine.arach("2177");
vm.loadAgent("agent.jar",
"arg1=x,arg2=y");
vm.detach();
LimitaBon:
can’t
change
class
schema
37. Chronon
• A
back-‐in-‐Bme
debugger
for
Java
– Recording
a
program
execuBon
– Debugging
the
recording
• What
is
recorded?
– Variable
history
– Method
calls
– ExcepBons
– Console
output
– Threads
38. Memory
buffer
Recorded
data
Flusher
threads
ApplicaBon
threads
Recording
41. Recording
Local
Variable
Changes
• Just
a
brute-‐force
idea:
– Instrument
*store
(astore,
istore,
etc)
instrucBons
to
write
the
value
to
a
store
int
i
=
2;
iconst_2
iconst_2
istore_1
istore_1
iload_1
invokestaBc
…
42.
43. Plumbr:
Memory
leak
detecBon
• RunBme
applicaBon
analysis
– vs
post-‐mortem
heap
dump
analysis
– vs
profilers
–
human
operated,
rarely
usable
in
producBon
• AdapBve
introspecBon
– Monitor
high
level
metrics,
cheap
to
obtain
– Collect
expensive
detailed
informaBon
when
suspects
are
found
44. Plumbr
• Memory
leak
in
Java
–
some
objects
are
created
Bme
a_er
Bme
but
a
reference
is
forgoren
• Look
at
when
object
was
created
and
how
long
it
lives
45. What
is
leaking?
Time (garbage collection cycles)
Instances of a class that belong to base application framework:
Class instances that handle user interaction:
Common JDK class instances:
Instances of a leaking class: