![JAR search and dependency download from the Maven repository](/logo.png)
io.opentelemetry.javaagent.tooling.ignore.IgnoredClassLoadersMatcher Maven / Gradle / Ivy
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.tooling.ignore;
import static java.util.logging.Level.FINE;
import io.opentelemetry.instrumentation.api.internal.cache.Cache;
import io.opentelemetry.javaagent.bootstrap.PatchLogger;
import io.opentelemetry.javaagent.tooling.util.Trie;
import java.util.logging.Logger;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.matcher.ElementMatcher;
public class IgnoredClassLoadersMatcher extends ElementMatcher.Junction.AbstractBase {
private static final Logger logger = Logger.getLogger(IgnoredClassLoadersMatcher.class.getName());
/* Cache of class loader instance -> (true|false). True = skip instrumentation. False = safe to instrument. */
private static final Cache skipCache = Cache.weak();
private final Trie ignoredClassLoaders;
public IgnoredClassLoadersMatcher(Trie ignoredClassLoaders) {
this.ignoredClassLoaders = ignoredClassLoaders;
}
@Override
public boolean matches(ClassLoader cl) {
if (cl == ClassLoadingStrategy.BOOTSTRAP_LOADER) {
// Don't skip bootstrap loader
return false;
}
String name = cl.getClass().getName();
IgnoreAllow ignored = ignoredClassLoaders.getOrNull(name);
if (ignored == IgnoreAllow.ALLOW) {
return false;
} else if (ignored == IgnoreAllow.IGNORE) {
return true;
}
return skipCache.computeIfAbsent(
cl,
c -> {
// when ClassloadingInstrumentation is active, checking delegatesToBootstrap() below is
// not required, because ClassloadingInstrumentation forces all class loaders to load all
// the classes in Constants.BOOTSTRAP_PACKAGE_PREFIXES directly from the bootstrap class
// loader
//
// however, at this time we don't want to introduce the concept of a required
// instrumentation, and we don't want to introduce the concept of the tooling code
// depending on whether a particular instrumentation is active (mainly because this
// particular use case doesn't seem to justify introducing either of these new concepts)
return !delegatesToBootstrap(cl);
});
}
/**
* TODO: this turns out to be useless with OSGi: {@code
* org.eclipse.osgi.internal.loader.BundleLoader#isRequestFromVM} returns {@code true} when class
* loading is issued from this check and {@code false} for 'real' class loads. We should come up
* with some sort of hack to avoid this problem.
*/
private static boolean delegatesToBootstrap(ClassLoader loader) {
boolean delegates = true;
if (!loadsExpectedClass(loader, PatchLogger.class)) {
logger.log(FINE, "loader {0} failed to delegate bootstrap agent class", loader);
delegates = false;
}
return delegates;
}
private static boolean loadsExpectedClass(ClassLoader loader, Class> expectedClass) {
try {
return loader.loadClass(expectedClass.getName()) == expectedClass;
} catch (ClassNotFoundException e) {
return false;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy