Fix race condition on loading SDK (#165)

This broke during last merge from DataDog repo because context class
loader is no longer set to the agent's class loader.
This commit is contained in:
Trask Stalnaker 2020-02-13 12:46:49 -08:00 committed by GitHub
parent e718b3067e
commit 75d807add9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 5 deletions

View File

@ -54,11 +54,22 @@ public class AgentInstaller {
public static ResettableClassFileTransformer installBytebuddyAgent( public static ResettableClassFileTransformer installBytebuddyAgent(
final Instrumentation inst, final AgentBuilder.Listener... listeners) { final Instrumentation inst, final AgentBuilder.Listener... listeners) {
// need to trigger loading of OpenTelemetry SDK before instrumentation can possibly cause final ClassLoader savedContextClassLoader = Thread.currentThread().getContextClassLoader();
// io.opentelemetry.OpenTelemetry to be loaded, since as soon as io.opentelemetry.OpenTelemetry, try {
// it looks up implementation via SPI, and if it doesn't find one, it loads the No-op // calling (shaded) OpenTelemetry.getTracerFactory() with context class loader set to the
// implementation and it cannot be replaced later // agent class loader, so that SPI finds the agent's (isolated) SDK, and (shaded)
OpenTelemetry.getTracerFactory(); // OpenTelemetry registers it, and then when instrumentation calls (shaded)
// OpenTelemetry.getTracerFactory() later, they get back the agent's (isolated) SDK
//
// but if we don't trigger this early registration, then if instrumentation is the first to
// call (shaded) OpenTelemetry.getTracerFactory(), then SPI can't see the agent class loader,
// and so (shaded) OpenTelemetry registers the no-op TracerFactory, and it cannot be replaced
// later
Thread.currentThread().setContextClassLoader(AgentInstaller.class.getClassLoader());
OpenTelemetry.getTracerFactory();
} finally {
Thread.currentThread().setContextClassLoader(savedContextClassLoader);
}
INSTRUMENTATION = inst; INSTRUMENTATION = inst;