package org.stagemonitor.core.instrument;
import net.bytebuddy.matcher.ElementMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stagemonitor.core.CorePlugin;
import org.stagemonitor.core.Stagemonitor;
import org.stagemonitor.core.util.ClassUtils;
/**
* Only allows transformation of classes if the target {@link ClassLoader} is able to load {@link Stagemonitor}.
* <p/>
* This avoids ClassNotFoundExceptions that can happen when instrumenting classes whose class loaders don't have
* access to stagemonitor classes, for example the Profiler class.
* <p/>
* Also, this prevents to transform classes that are loaded by another class loader hierarchy and thus avoids
* interfering with other applications which are deployed on the same application server.
*/
public class ApplicationClassLoaderMatcher extends ElementMatcher.Junction.AbstractBase<ClassLoader> {
private static final boolean DEBUG_INSTRUMENTATION = Stagemonitor.getPlugin(CorePlugin.class).isDebugInstrumentation();
private static final Logger logger = LoggerFactory.getLogger(ApplicationClassLoaderMatcher.class);
@Override
public boolean matches(ClassLoader target) {
// only returns true if this class was loaded by the provided classLoader or by a parent of it
// i.e. only if it is from the same application
final boolean result = ClassUtils.loadClassOrReturnNull(target, "org.stagemonitor.core.Stagemonitor") == Stagemonitor.class;
if (DEBUG_INSTRUMENTATION) {
logger.info("Instrumenting ClassLoader {}: {}", target, result);
}
return result;
}
}