InstrumentationModule cleanup
MODIFY
instrumentation/methods/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/methods/MethodInstrumentationModule.java
instrumentation/methods/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/methods/MethodInstrumentationModule.java
@@ -55,7 +55,7 @@ public class MethodInstrumentationModule extends InstrumentationModule {
// the default configuration has empty "otel.instrumentation.methods.include", and so doesn't
// generate any TypeInstrumentation for muzzle to analyze
@Override
- protected String[] getMuzzleHelperClassNames() {
+ public String[] getMuzzleHelperClassNames() {
return typeInstrumentations.isEmpty()
? new String[0]
: new String[] {"io.opentelemetry.javaagent.instrumentation.methods.MethodTracer"};

MODIFY
javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/InstrumentationModule.java
javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/InstrumentationModule.java
@@ -33,12 +33,12 @@ import net.bytebuddy.matcher.ElementMatcher;
*/
public abstract class InstrumentationModule implements AgentExtension {
private static final String[] EMPTY = new String[0];
+ private static final Reference[] EMPTY_REFS = new Reference[0];
private static final boolean DEFAULT_ENABLED =
Config.get().getBooleanProperty("otel.instrumentation.common.default-enabled", true);
private final Set<String> instrumentationNames;
- final boolean enabled;
/**
* Creates an instrumentation module. Note that all implementations of {@link
@@ -75,7 +75,6 @@ public abstract class InstrumentationModule implements AgentExtension {
throw new IllegalArgumentException("InstrumentationModules must be named");
}
this.instrumentationNames = new LinkedHashSet<>(instrumentationNames);
- this.enabled = Config.get().isInstrumentationEnabled(instrumentationNames, defaultEnabled());
}
private static List<String> toList(String first, String[] rest) {
@@ -101,15 +100,17 @@ public abstract class InstrumentationModule implements AgentExtension {
return instrumentationNames.iterator().next();
}
+ /** Returns true if this instrumentation module should be installed. */
+ public final boolean isEnabled() {
+ return Config.get().isInstrumentationEnabled(instrumentationNames, defaultEnabled());
+ }
+
/**
- * Returns all helper classes that will be injected into the application classloader, both ones
- * provided by the implementation and ones that were collected by muzzle during compilation.
+ * Allows instrumentation modules to disable themselves by default, or to additionally disable
+ * themselves on some other condition.
*/
- public final List<String> getAllHelperClassNames() {
- List<String> helperClassNames = new ArrayList<>();
- helperClassNames.addAll(asList(additionalHelperClassNames()));
- helperClassNames.addAll(asList(getMuzzleHelperClassNames()));
- return helperClassNames;
+ protected boolean defaultEnabled() {
+ return DEFAULT_ENABLED;
}
/**
@@ -127,6 +128,29 @@ public abstract class InstrumentationModule implements AgentExtension {
return false;
}
+ /** Returns resource names to inject into the user's classloader. */
+ public String[] helperResourceNames() {
+ return EMPTY;
+ }
+
+ /**
+ * An instrumentation module can implement this method to make sure that the classloader contains
+ * the particular library version. It is useful to implement that if the muzzle check does not
+ * fail for versions out of the instrumentation's scope.
+ *
+ * <p>E.g. supposing version 1.0 has class {@code A}, but it was removed in version 2.0; A is not
+ * used in the helper classes at all; this module is instrumenting 2.0: this method will return
+ * {@code not(hasClassesNamed("A"))}.
+ *
+ * @return A type matcher used to match the classloader under transform
+ */
+ public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
+ return any();
+ }
+
+ /** Returns a list of all individual type instrumentation in this module. */
+ public abstract List<TypeInstrumentation> typeInstrumentations();
+
/**
* Returns a list of references to helper and library classes used in this module's type
* instrumentation advices.
@@ -139,7 +163,7 @@ public abstract class InstrumentationModule implements AgentExtension {
* will not generate a new implementation, it will leave the existing one.
*/
public Reference[] getMuzzleReferences() {
- return new Reference[0];
+ return EMPTY_REFS;
}
/**
@@ -153,7 +177,7 @@ public abstract class InstrumentationModule implements AgentExtension {
* <p><b>This method is generated automatically</b>: if you override it, the muzzle compile plugin
* will not generate a new implementation, it will leave the existing one.
*/
- protected String[] getMuzzleHelperClassNames() {
+ public String[] getMuzzleHelperClassNames() {
return EMPTY;
}
@@ -168,70 +192,7 @@ public abstract class InstrumentationModule implements AgentExtension {
* <p><b>This method is generated automatically</b>: if you override it, the muzzle compile plugin
* will not generate a new implementation, it will leave the existing one.
*/
- protected Map<String, String> getMuzzleContextStoreClasses() {
+ public Map<String, String> getMuzzleContextStoreClasses() {
return Collections.emptyMap();
}
-
- /**
- * Instrumentation modules can override this method to provide additional helper classes that are
- * not located in instrumentation packages described in the {@code InstrumentationClassPredicate}
- * class and {@link #isHelperClass(String)} (and not automatically detected by muzzle). These
- * additional classes will be injected into the application classloader first.
- *
- * <p>Implementing {@link #isHelperClass(String)} is generally simpler and less error-prone
- * compared to implementing this method.
- *
- * @deprecated Use {@link #isHelperClass(String)} instead.
- */
- @Deprecated
- protected String[] additionalHelperClassNames() {
- return EMPTY;
- }
-
- /**
- * Same as {@link #order()}.
- *
- * @deprecated use {@link #order()} instead.
- */
- @Deprecated
- public int getOrder() {
- return 0;
- }
-
- /** {@inheritDoc} */
- @Override
- public int order() {
- return getOrder();
- }
-
- /** Returns resource names to inject into the user's classloader. */
- public String[] helperResourceNames() {
- return EMPTY;
- }
-
- /**
- * An instrumentation module can implement this method to make sure that the classloader contains
- * the particular library version. It is useful to implement that if the muzzle check does not
- * fail for versions out of the instrumentation's scope.
- *
- * <p>E.g. supposing version 1.0 has class {@code A}, but it was removed in version 2.0; A is not
- * used in the helper classes at all; this module is instrumenting 2.0: this method will return
- * {@code not(hasClassesNamed("A"))}.
- *
- * @return A type matcher used to match the classloader under transform
- */
- public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
- return any();
- }
-
- /** Returns a list of all individual type instrumentation in this module. */
- public abstract List<TypeInstrumentation> typeInstrumentations();
-
- /**
- * Allows instrumentation modules to disable themselves by default, or to additionally disable
- * themselves on some other condition.
- */
- protected boolean defaultEnabled() {
- return DEFAULT_ENABLED;
- }
}

MODIFY
javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/matcher/AgentElementMatchers.java
javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/matcher/AgentElementMatchers.java
@@ -16,7 +16,7 @@ import net.bytebuddy.matcher.ElementMatcher;
/**
* This class provides some custom ByteBuddy element matchers to use when applying instrumentation.
*/
-public class AgentElementMatchers {
+public final class AgentElementMatchers {
public static ElementMatcher.Junction<TypeDescription> extendsClass(
ElementMatcher<TypeDescription> matcher) {
@@ -92,4 +92,6 @@ public class AgentElementMatchers {
}
}
}
+
+ private AgentElementMatchers() {}
}

MODIFY
javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/matcher/NameMatchers.java
javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/matcher/NameMatchers.java
@@ -74,4 +74,6 @@ public final class NameMatchers {
return (include && contained) || (!include && !contained);
}
}
+
+ private NameMatchers() {}
}

DELETE
javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/spi/ByteBuddyAgentCustomizer.java
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.javaagent.spi;
-
-import io.opentelemetry.javaagent.extension.spi.AgentExtension;
-import java.lang.instrument.Instrumentation;
-import net.bytebuddy.agent.builder.AgentBuilder;
-
-/**
- * {@link ByteBuddyAgentCustomizer} customizes ByteBuddy agent builder right before the agent is
- * installed - {@link AgentBuilder#installOn(Instrumentation)}. This SPI can be used to customize
- * {@link AgentBuilder} for vendor specific needs. For example install custom listeners or exclude
- * classes. Use this SPI carefully because it can change {@link net.bytebuddy.ByteBuddy} behaviour.
- *
- * <p>This is a service provider interface that requires implementations to be registered in {@code
- * META-INF/services} folder.
- *
- * @deprecated Use {@link AgentExtension} with correct {@link AgentExtension#order()} instead.
- */
-@Deprecated
-public interface ByteBuddyAgentCustomizer {
-
- /**
- * Customize ByteBuddy agent builder before {@link AgentBuilder#installOn(Instrumentation)} is
- * called.
- *
- * @param agentBuilder ByteBuddy agent from {@code AgentInstaller}.
- * @return customized agent builder.
- */
- AgentBuilder customize(AgentBuilder agentBuilder);
-}

MODIFY
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/ActualInstrumentationExtensionImplementation.java
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/ActualInstrumentationExtensionImplementation.java
@@ -49,11 +49,11 @@ public final class ActualInstrumentationExtensionImplementation
@Override
AgentBuilder extend(
InstrumentationModule instrumentationModule, AgentBuilder parentAgentBuilder) {
- if (!instrumentationModule.enabled) {
+ if (!instrumentationModule.isEnabled()) {
log.debug("Instrumentation {} is disabled", instrumentationModule.extensionName());
return parentAgentBuilder;
}
- List<String> helperClassNames = instrumentationModule.getAllHelperClassNames();
+ List<String> helperClassNames = asList(instrumentationModule.getMuzzleHelperClassNames());
List<String> helperResourceNames = asList(instrumentationModule.helperResourceNames());
List<TypeInstrumentation> typeInstrumentations = instrumentationModule.typeInstrumentations();
if (typeInstrumentations.isEmpty()) {
@@ -68,7 +68,7 @@ public final class ActualInstrumentationExtensionImplementation
ElementMatcher.Junction<ClassLoader> moduleClassLoaderMatcher =
instrumentationModule.classLoaderMatcher();
- MuzzleMatcher muzzleMatcher = new MuzzleMatcher(instrumentationModule);
+ MuzzleMatcher muzzleMatcher = new MuzzleMatcher(instrumentationModule, helperClassNames);
AgentBuilder.Transformer helperInjector =
new HelperInjector(
instrumentationModule.extensionName(), helperClassNames, helperResourceNames);
@@ -135,11 +135,14 @@ public final class ActualInstrumentationExtensionImplementation
*/
private static class MuzzleMatcher implements AgentBuilder.RawMatcher {
private final InstrumentationModule instrumentationModule;
+ private final List<String> helperClassNames;
private final AtomicBoolean initialized = new AtomicBoolean(false);
private volatile ReferenceMatcher referenceMatcher;
- private MuzzleMatcher(InstrumentationModule instrumentationModule) {
+ private MuzzleMatcher(
+ InstrumentationModule instrumentationModule, List<String> helperClassNames) {
this.instrumentationModule = instrumentationModule;
+ this.helperClassNames = helperClassNames;
}
@Override
@@ -185,7 +188,7 @@ public final class ActualInstrumentationExtensionImplementation
if (initialized.compareAndSet(false, true)) {
referenceMatcher =
new ReferenceMatcher(
- instrumentationModule.getAllHelperClassNames(),
+ helperClassNames,
instrumentationModule.getMuzzleReferences(),
instrumentationModule::isHelperClass);
}

MODIFY
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java
@@ -20,7 +20,6 @@ import io.opentelemetry.javaagent.extension.spi.AgentExtension;
import io.opentelemetry.javaagent.instrumentation.api.SafeServiceLoader;
import io.opentelemetry.javaagent.instrumentation.api.internal.BootstrapPackagePrefixesHolder;
import io.opentelemetry.javaagent.spi.BootstrapPackagesProvider;
-import io.opentelemetry.javaagent.spi.ByteBuddyAgentCustomizer;
import io.opentelemetry.javaagent.spi.ComponentInstaller;
import io.opentelemetry.javaagent.spi.IgnoreMatcherProvider;
import io.opentelemetry.javaagent.tooling.config.ConfigInitializer;
@@ -170,7 +169,6 @@ public class AgentInstaller {
}
}
- agentBuilder = customizeByteBuddyAgent(agentBuilder);
log.debug("Installed {} instrumenter(s)", numInstrumenters);
ResettableClassFileTransformer resettableClassFileTransformer = agentBuilder.installOn(inst);
installComponentsAfterByteBuddy(componentInstallers, config);
@@ -221,15 +219,6 @@ public class AgentInstaller {
}
}
- private static AgentBuilder customizeByteBuddyAgent(AgentBuilder agentBuilder) {
- Iterable<ByteBuddyAgentCustomizer> agentCustomizers = loadByteBuddyAgentCustomizers();
- for (ByteBuddyAgentCustomizer agentCustomizer : agentCustomizers) {
- log.debug("Applying agent builder customizer {}", agentCustomizer.getClass().getName());
- agentBuilder = agentCustomizer.customize(agentBuilder);
- }
- return agentBuilder;
- }
-
private static Iterable<ComponentInstaller> loadComponentProviders() {
return ServiceLoader.load(ComponentInstaller.class, AgentInstaller.class.getClassLoader());
}
@@ -245,11 +234,6 @@ public class AgentInstaller {
return new NoopIgnoreMatcherProvider();
}
- private static Iterable<ByteBuddyAgentCustomizer> loadByteBuddyAgentCustomizers() {
- return ServiceLoader.load(
- ByteBuddyAgentCustomizer.class, AgentInstaller.class.getClassLoader());
- }
-
private static List<? extends AgentExtension> loadAgentExtensions() {
// TODO: InstrumentationModule should no longer be an SPI
Stream<? extends AgentExtension> extensions =

MODIFY
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/muzzle/collector/MuzzleCodeGenerator.java
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/muzzle/collector/MuzzleCodeGenerator.java
@@ -195,7 +195,7 @@ class MuzzleCodeGenerator implements AsmVisitorWrapper {
private void generateMuzzleHelperClassNamesMethod(ReferenceCollector collector) {
/*
- * protected String[] getMuzzleHelperClassNames() {
+ * public String[] getMuzzleHelperClassNames() {
* return new String[] {
* // sorted helper class names
* };
@@ -203,7 +203,7 @@ class MuzzleCodeGenerator implements AsmVisitorWrapper {
*/
MethodVisitor mv =
super.visitMethod(
- Opcodes.ACC_PROTECTED,
+ Opcodes.ACC_PUBLIC,
MUZZLE_HELPER_CLASSES_METHOD_NAME,
"()[Ljava/lang/String;",
null,
@@ -236,7 +236,7 @@ class MuzzleCodeGenerator implements AsmVisitorWrapper {
private void generateMuzzleReferencesMethod(ReferenceCollector collector) {
/*
- * protected synchronized Reference[] getMuzzleReferences() {
+ * public synchronized Reference[] getMuzzleReferences() {
* if (null == this.muzzleReferences) {
* this.muzzleReferences = new Reference[] {
* // reference builders
@@ -248,7 +248,7 @@ class MuzzleCodeGenerator implements AsmVisitorWrapper {
try {
MethodVisitor mv =
super.visitMethod(
- Opcodes.ACC_PROTECTED + Opcodes.ACC_SYNCHRONIZED,
+ Opcodes.ACC_PUBLIC + Opcodes.ACC_SYNCHRONIZED,
MUZZLE_REFERENCES_METHOD_NAME,
"()[Lio/opentelemetry/javaagent/extension/muzzle/Reference;",
null,
@@ -534,7 +534,7 @@ class MuzzleCodeGenerator implements AsmVisitorWrapper {
private void generateMuzzleContextStoreClassesMethod(ReferenceCollector collector) {
/*
- * protected Map<String, String> getMuzzleContextStoreClasses() {
+ * public Map<String, String> getMuzzleContextStoreClasses() {
* Map<String, String> contextStore = new HashMap();
* contextStore.put(..., ...);
* return contextStore;
@@ -542,7 +542,7 @@ class MuzzleCodeGenerator implements AsmVisitorWrapper {
*/
MethodVisitor mv =
super.visitMethod(
- Opcodes.ACC_PROTECTED,
+ Opcodes.ACC_PUBLIC,
MUZZLE_CONTEXT_STORE_CLASSES_METHOD_NAME,
"()Ljava/util/Map;",
null,

MODIFY
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/muzzle/matcher/MuzzleGradlePluginUtil.java
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/muzzle/matcher/MuzzleGradlePluginUtil.java
package io.opentelemetry.javaagent.tooling.muzzle.matcher;
+import static java.util.Arrays.asList;
+
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.muzzle.Reference;
import io.opentelemetry.javaagent.tooling.HelperInjector;
@@ -49,7 +51,7 @@ public final class MuzzleGradlePluginUtil {
ServiceLoader.load(InstrumentationModule.class, agentClassLoader)) {
ReferenceMatcher muzzle =
new ReferenceMatcher(
- instrumentationModule.getAllHelperClassNames(),
+ asList(instrumentationModule.getMuzzleHelperClassNames()),
instrumentationModule.getMuzzleReferences(),
instrumentationModule::isHelperClass);
List<Mismatch> mismatches = muzzle.getMismatchedReferenceSources(userClassLoader);
@@ -88,7 +90,7 @@ public final class MuzzleGradlePluginUtil {
ServiceLoader.load(InstrumentationModule.class, agentClassLoader)) {
try {
// verify helper injector works
- List<String> allHelperClasses = instrumentationModule.getAllHelperClassNames();
+ List<String> allHelperClasses = asList(instrumentationModule.getMuzzleHelperClassNames());
if (!allHelperClasses.isEmpty()) {
new HelperInjector(
MuzzleGradlePluginUtil.class.getSimpleName(),

RENAME
testing/agent-exporter/src/main/java/io/opentelemetry/javaagent/testing/bytebuddy/TestByteBuddyAgentCustomizer.java
testing/agent-exporter/src/main/java/io/opentelemetry/javaagent/testing/bytebuddy/TestAgentExtension.java
package io.opentelemetry.javaagent.testing.bytebuddy;
import com.google.auto.service.AutoService;
-import io.opentelemetry.javaagent.spi.ByteBuddyAgentCustomizer;
+import io.opentelemetry.javaagent.extension.spi.AgentExtension;
import net.bytebuddy.agent.builder.AgentBuilder;
-@AutoService(ByteBuddyAgentCustomizer.class)
-public class TestByteBuddyAgentCustomizer implements ByteBuddyAgentCustomizer {
+@AutoService(AgentExtension.class)
+public class TestAgentExtension implements AgentExtension {
+
@Override
- public AgentBuilder customize(AgentBuilder agentBuilder) {
+ public AgentBuilder extend(AgentBuilder agentBuilder) {
return agentBuilder.with(TestAgentListener.INSTANCE);
}
+
+ @Override
+ public String extensionName() {
+ return "test";
+ }
}

InstrumentationModule cleanup (#2925)