/* * Copyright The OpenTelemetry Authors * SPDX-License-Identifier: Apache-2.0 */ package io.opentelemetry.javaagent.bootstrap; import java.lang.instrument.Instrumentation; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import org.checkerframework.checker.nullness.qual.Nullable; /** * Agent start up logic. * *
This class is loaded and called by {@code io.opentelemetry.javaagent.OpenTelemetryAgent} * *
The intention is for this class to be loaded by bootstrap classloader to make sure we have
* unimpeded access to the rest of agent parts.
*/
public final class AgentInitializer {
// Accessed via reflection from tests.
// fields must be managed under class lock
@Nullable private static ClassLoader agentClassLoader = null;
// called via reflection in the OpenTelemetryAgent class
public static void initialize(Instrumentation inst, URL bootstrapUrl) throws Exception {
startAgent(inst, bootstrapUrl);
}
private static synchronized void startAgent(Instrumentation inst, URL bootstrapUrl)
throws Exception {
if (agentClassLoader == null) {
agentClassLoader = createAgentClassLoader("inst", bootstrapUrl);
Class> agentInstallerClass =
agentClassLoader.loadClass("io.opentelemetry.javaagent.tooling.AgentInstaller");
Method agentInstallerMethod =
agentInstallerClass.getMethod("installBytebuddyAgent", Instrumentation.class);
ClassLoader savedContextClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(agentClassLoader);
agentInstallerMethod.invoke(null, inst);
} finally {
Thread.currentThread().setContextClassLoader(savedContextClassLoader);
}
}
}
// TODO misleading name
public static synchronized ClassLoader getAgentClassLoader() {
return agentClassLoader;
}
/**
* Create the agent classloader. This must be called after the bootstrap jar has been appended to
* the bootstrap classpath.
*
* @param innerJarFilename Filename of internal jar to use for the classpath of the agent
* classloader
* @return Agent Classloader
*/
@SuppressWarnings("unchecked")
private static ClassLoader createAgentClassLoader(String innerJarFilename, URL bootstrapUrl)
throws Exception {
ClassLoader agentParent;
if (isJavaBefore9()) {
agentParent = null; // bootstrap
} else {
// platform classloader is parent of system in java 9+
agentParent = getPlatformClassLoader();
}
Class> loaderClass =
ClassLoader.getSystemClassLoader()
.loadClass("io.opentelemetry.javaagent.bootstrap.AgentClassLoader");
Constructor