Add agent's classloader to default instrumentation location strategy

The transformer needs the agent's classloader to resolve advice
classes at transform time. Also stop using reflection to register classloads.
This commit is contained in:
Andrew Kent 2017-12-07 14:44:34 -08:00
parent 6a646009fa
commit 42832e77f5
2 changed files with 30 additions and 9 deletions

View File

@ -25,7 +25,6 @@ import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import dd.trace.Instrumenter; import dd.trace.Instrumenter;
import java.lang.instrument.Instrumentation; import java.lang.instrument.Instrumentation;
import java.lang.reflect.Method;
import java.util.Collections; import java.util.Collections;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.Set; import java.util.Set;
@ -40,7 +39,12 @@ import net.bytebuddy.utility.JavaModule;
@Slf4j @Slf4j
public class TracingAgent { public class TracingAgent {
public static void premain(final String agentArgs, final Instrumentation inst) throws Exception { /** Return the classloader the core agent is running on. */
public static ClassLoader getAgentClassLoader() {
return TracingAgent.class.getClassLoader();
}
public static void premain(String agentArgs, final Instrumentation inst) throws Exception {
log.debug("Using premain for loading {}", TracingAgent.class.getSimpleName()); log.debug("Using premain for loading {}", TracingAgent.class.getSimpleName());
addByteBuddy(inst); addByteBuddy(inst);
AgentRulesManager.initialize(); AgentRulesManager.initialize();
@ -111,7 +115,7 @@ public class TracingAgent {
final JavaModule module, final JavaModule module,
final boolean loaded, final boolean loaded,
final DynamicType dynamicType) { final DynamicType dynamicType) {
log.debug("Transformed {}", typeDescription); log.debug("Transformed {} -- {}", typeDescription, classLoader);
if (classLoader == null) { if (classLoader == null) {
return; return;
@ -123,13 +127,9 @@ public class TracingAgent {
initializedClassloaders.add(classLoader); initializedClassloaders.add(classLoader);
try { try {
final Class<?> rulesManager = InstrumentationRulesManager.registerClassLoad(classLoader);
Class.forName("com.datadoghq.agent.InstrumentationRulesManager", true, classLoader);
final Method registerClassLoad =
rulesManager.getDeclaredMethod("registerClassLoad", Object.class);
registerClassLoad.invoke(null, classLoader);
} catch (final Throwable e) { } catch (final Throwable e) {
log.info("ClassLoad Registration for target " + classLoader, e); log.error("Failed ClassLoad Registration for target " + classLoader, e);
} }
} }
} }

View File

@ -1,11 +1,32 @@
package dd.trace; package dd.trace;
import java.lang.reflect.Method;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.agent.builder.AgentBuilder; import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.dynamic.ClassFileLocator;
/** A bytebuddy advice builder with default DataDog settings. */ /** A bytebuddy advice builder with default DataDog settings. */
@Slf4j
public class DDAdvice extends AgentBuilder.Transformer.ForAdvice { public class DDAdvice extends AgentBuilder.Transformer.ForAdvice {
private static ClassLoader AGENT_CLASSLOADER;
static {
try {
Class<?> agentClass =
DDAdvice.class.getClassLoader().loadClass("com.datadoghq.agent.TracingAgent");
Method getAgentClassloaderMethod = agentClass.getMethod("getAgentClassLoader");
AGENT_CLASSLOADER = (ClassLoader) getAgentClassloaderMethod.invoke(null);
} catch (Throwable t) {
log.error("Unable to locate agent classloader. Falling back to System Classloader");
AGENT_CLASSLOADER = ClassLoader.getSystemClassLoader();
}
}
public static AgentBuilder.Transformer.ForAdvice create() { public static AgentBuilder.Transformer.ForAdvice create() {
return new DDAdvice() return new DDAdvice()
.with(
new AgentBuilder.LocationStrategy.Simple(
ClassFileLocator.ForClassLoader.of(AGENT_CLASSLOADER)))
.withExceptionHandler(ExceptionHandlers.defaultExceptionHandler()); .withExceptionHandler(ExceptionHandlers.defaultExceptionHandler());
} }