Java agents are a little-known but extremely powerful part of the Java ecosystem. Agents are able to transform existing classes at runtime, allowing scenarios such as logging and monitoring, hot reload or gathering code coverage. However, their usage presents a number of pitfalls as well.
In this talk we will present the steps of writing a java agent from scratch, indicate various common mistakes and pain points and draw conclusions on best practices.
After this talk participants will have a better understanding of the Java instrumentation API and about should / should not be done with it.
16. Spring-AOP
@Aspect
public class Aspects {
@Pointcut("execution(* service(..))")
public void webRequest() {}
}
@Aspect
public class LoggerHandler {
@Before("com.myapp.Aspects.webRequest()")
public void logWebRequest(Request request) {
System.out.println("Handling web request " + request);
}
}
16
17. Spring-AOP
Simplified deployment - Spring beans
Simplified programming model
Powerful DSL to express interception targets
Only intercepts calls to Spring beans
Spring-only solution
17
18. OSGi-WeavingHooks
@Component
public class SimpleWeavingHook implements WeavingHook {
public void weave(WovenClass wovenClass) {
if ( !wovenClass.getClassName().equals(CLASS_TO_WEAVE) )
return;
try {
wovenClass.setBytes(weave0(wovenClass));
} catch (NotFoundException | CannotCompileException | IOException e) {
LOGGER.warn("Failed weaving class {}", wovenClass.getClassName(), e);
}
}
}
18
21. Thechallenges
Java agents...
must be packaged as a Jar file, with a specific manifest
not trivially attached to the current process
usually a one-way deal, no support for rolling back class changes
21
22. Asolution
Build a testing harness that...
launch Java process with custom agents attached
require separate communication channel with java agent
no out-of-the-box support for code coverage and other tools
22
23. Bootstrappingthetest
// 1. which java?
String javaHome = System.getProperty("java.home");
Path javaExe = Paths.get(javaHome, "bin", "java");
// 2. which jar?
String ja = findAgentJar();
// 3. which classpath?
String classPath = buildClassPath();
// 4. launch
ProcessBuilder pb = new ProcessBuilder(
javaExe.toString(), "-javaagent:" + ja,
"-cp", classPath,
TestApplication.class.getName()
);
23