Skip attempting to retransform our agent classes
MODIFY
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java
@@ -12,8 +12,10 @@ import static net.bytebuddy.matcher.ElementMatchers.any;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.none;
+import com.google.common.collect.Iterables;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.internal.BootstrapPackagePrefixesHolder;
+import io.opentelemetry.javaagent.bootstrap.AgentClassLoader;
import io.opentelemetry.javaagent.bootstrap.AgentInitializer;
import io.opentelemetry.javaagent.instrumentation.api.SafeServiceLoader;
import io.opentelemetry.javaagent.spi.BootstrapPackagesProvider;
@@ -96,7 +98,7 @@ public class AgentInstaller {
new AgentBuilder.Default()
.disableClassFormatChanges()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
- .with(AgentBuilder.RedefinitionStrategy.DiscoveryStrategy.Reiterating.INSTANCE)
+ .with(new RedefinitionDiscoveryStrategy())
.with(AgentBuilder.DescriptionStrategy.Default.POOL_ONLY)
.with(AgentTooling.poolStrategy())
.with(new ClassLoadListener())
@@ -116,7 +118,7 @@ public class AgentInstaller {
agentBuilder =
agentBuilder
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
- .with(AgentBuilder.RedefinitionStrategy.DiscoveryStrategy.Reiterating.INSTANCE)
+ .with(new RedefinitionDiscoveryStrategy())
.with(new RedefinitionLoggingListener())
.with(new TransformLoggingListener());
}
@@ -459,6 +461,28 @@ public class AgentInstaller {
}
}
+ private static class RedefinitionDiscoveryStrategy
+ implements AgentBuilder.RedefinitionStrategy.DiscoveryStrategy {
+ private static final AgentBuilder.RedefinitionStrategy.DiscoveryStrategy delegate =
+ AgentBuilder.RedefinitionStrategy.DiscoveryStrategy.Reiterating.INSTANCE;
+
+ @Override
+ public Iterable<Iterable<Class<?>>> resolve(Instrumentation instrumentation) {
+ // filter out our agent classes and injected helper classes
+ return Iterables.transform(
+ delegate.resolve(instrumentation), i -> Iterables.filter(i, c -> !isIgnored(c)));
+ }
+
+ private static boolean isIgnored(Class<?> c) {
+ ClassLoader cl = c.getClassLoader();
+ if (cl != null && cl.getClass() == AgentClassLoader.class) {
+ return true;
+ }
+
+ return HelperInjector.isInjectedClass(c);
+ }
+ }
+
/**
* Search for java or agent-tracer sysprops which indicate that a custom log manager will be used.
* Also search for any app classes known to set a custom log manager.

MODIFY
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/HelperInjector.java
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/HelperInjector.java
@@ -48,6 +48,8 @@ public class HelperInjector implements Transformer {
}
};
+ private static final WeakMap<Class<?>, Boolean> injectedClasses = newWeakMap();
+
private final String requestingName;
private final Set<String> helperClassNames;
@@ -133,6 +135,8 @@ public class HelperInjector implements Transformer {
classes = injectClassLoader(classLoader, classnameToBytes);
}
+ classes.values().forEach(c -> injectedClasses.put(c, Boolean.TRUE));
+
// All agent helper classes are in the unnamed module
// And there's exactly one unnamed module per classloader
// Use the module of the first class for convenience
@@ -233,4 +237,8 @@ public class HelperInjector implements Transformer {
file.deleteOnExit();
}
}
+
+ public static boolean isInjectedClass(Class<?> c) {
+ return injectedClasses.containsKey(c);
+ }
}

Skip attempting to retransform our agent classes (#1919)