diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java
index f4cda75569a57406ad926aca3f114608bdee6cf7..b28f1a79c048b2c4fe19072883619a88fae73cd7 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java
@@ -1,8 +1,6 @@
package org.skywalking.apm.agent.core.plugin;
import net.bytebuddy.dynamic.DynamicType;
-import net.bytebuddy.pool.TypePool;
-import net.bytebuddy.pool.TypePool.Resolution;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassEnhancePluginDefine;
import org.skywalking.apm.util.StringUtil;
import org.skywalking.apm.logging.ILog;
@@ -17,18 +15,16 @@ import org.skywalking.apm.logging.LogManager;
public abstract class AbstractClassEnhancePluginDefine {
private static final ILog logger = LogManager.getLogger(AbstractClassEnhancePluginDefine.class);
- private TypePool classTypePool;
-
/**
* Main entrance of enhancing the class.
*
* @param transformClassName target class.
- * @param builder byte-buddy's builder to manipulate target class's bytecode.
+ * @param builder byte-buddy's builder to manipulate target class's bytecode.
* @return the new builder, or null
if not be enhanced.
* @throws PluginException, when set builder failure.
*/
public DynamicType.Builder> define(String transformClassName,
- DynamicType.Builder> builder) throws PluginException {
+ DynamicType.Builder> builder, ClassLoader classLoader) throws PluginException {
String interceptorDefineClassName = this.getClass().getName();
if (StringUtil.isEmpty(transformClassName)) {
@@ -44,8 +40,7 @@ public abstract class AbstractClassEnhancePluginDefine {
String[] witnessClasses = witnessClasses();
if (witnessClasses != null) {
for (String witnessClass : witnessClasses) {
- Resolution witnessClassResolution = classTypePool.describe(witnessClass);
- if (!witnessClassResolution.isResolved()) {
+ if (!WitnessClassFinder.INSTANCE.exist(witnessClass, classLoader)) {
logger.warn("enhance class {} by plugin {} is not working. Because witness class {} is not existed.", transformClassName, interceptorDefineClassName,
witnessClass);
return null;
@@ -64,7 +59,7 @@ public abstract class AbstractClassEnhancePluginDefine {
}
protected abstract DynamicType.Builder> enhance(String enhanceOriginClassName,
- DynamicType.Builder> newClassBuilder) throws PluginException;
+ DynamicType.Builder> newClassBuilder) throws PluginException;
/**
* Define the classname of target class.
@@ -86,8 +81,4 @@ public abstract class AbstractClassEnhancePluginDefine {
protected String[] witnessClasses() {
return new String[] {};
}
-
- public void setClassTypePool(TypePool classTypePool) {
- this.classTypePool = classTypePool;
- }
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginBootstrap.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginBootstrap.java
index cad9fa8a137c4280435a87105287b51ccc241c12..d1b72047d63f246f155156a33e62675226226bf0 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginBootstrap.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginBootstrap.java
@@ -1,6 +1,5 @@
package org.skywalking.apm.agent.core.plugin;
-import net.bytebuddy.pool.TypePool;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
@@ -24,8 +23,6 @@ public class PluginBootstrap {
* @return plugin definition list.
*/
public List loadPlugins() {
- TypePool classTypePool = TypePool.Default.ofClassPath();
-
PluginResourcesResolver resolver = new PluginResourcesResolver();
List resources = resolver.getResources();
@@ -50,7 +47,6 @@ public class PluginBootstrap {
logger.debug("loading plugin class {}.", pluginDefine.getDefineClass());
AbstractClassEnhancePluginDefine plugin =
(AbstractClassEnhancePluginDefine) Class.forName(pluginDefine.getDefineClass()).newInstance();
- plugin.setClassTypePool(classTypePool);
plugins.add(plugin);
} catch (Throwable t) {
logger.error(t, "load plugin [{}] failure.", pluginDefine.getDefineClass());
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/TracingBootstrap.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/TracingBootstrap.java
index 8ba5e4c3e1166145002807ee5f2078d4b0a95294..00e004a4ab953f58cbc75ecaec179e28ba5311e3 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/TracingBootstrap.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/TracingBootstrap.java
@@ -30,7 +30,7 @@ public class TracingBootstrap {
* Main entrance for testing.
*
* @param args includes target classname ( which exists "public static void main(String[] args)" ) and arguments
- * list.
+ * list.
* @throws PluginException
* @throws ClassNotFoundException
* @throws NoSuchMethodException
@@ -62,7 +62,7 @@ public class TracingBootstrap {
}
DynamicType.Builder> newClassBuilder =
new ByteBuddy().rebase(resolution.resolve(), ClassFileLocator.ForClassLoader.ofClassPath());
- newClassBuilder = ((AbstractClassEnhancePluginDefine) plugin).define(enhanceClassName, newClassBuilder);
+ newClassBuilder = ((AbstractClassEnhancePluginDefine)plugin).define(enhanceClassName, newClassBuilder, TracingBootstrap.class.getClassLoader());
newClassBuilder.make(new TypeResolutionStrategy.Active()).load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded();
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/WitnessClassFinder.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/WitnessClassFinder.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f28b0fa9eea6c761d7ae727aeb908f10e6becfc
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/WitnessClassFinder.java
@@ -0,0 +1,42 @@
+package org.skywalking.apm.agent.core.plugin;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import net.bytebuddy.pool.TypePool;
+
+/**
+ * The WitnessClassFinder
represents a pool of {@link TypePool}s,
+ * each {@link TypePool} matches a {@link ClassLoader},
+ * which helps to find the class define existed or not.
+ *
+ * @author wusheng
+ */
+public enum WitnessClassFinder {
+ INSTANCE;
+
+ private Map poolMap = new ConcurrentHashMap();
+
+ /**
+ * @param witnessClass
+ * @param classLoader for finding the witnessClass
+ * @return true, if the given witnessClass exists, through the given classLoader.
+ */
+ public boolean exist(String witnessClass, ClassLoader classLoader) {
+ ClassLoader mappingKey = classLoader == null ? NullClassLoader.INSTANCE : classLoader;
+ if (!poolMap.containsKey(witnessClass)) {
+ synchronized (poolMap) {
+ if (!poolMap.containsKey(witnessClass)) {
+ TypePool classTypePool = classLoader == null ? TypePool.Default.ofClassPath() : TypePool.Default.of(classLoader);
+ poolMap.put(mappingKey, classTypePool);
+ }
+ }
+ }
+ TypePool typePool = poolMap.get(mappingKey);
+ TypePool.Resolution witnessClassResolution = typePool.describe(witnessClass);
+ return witnessClassResolution.isResolved();
+ }
+}
+
+final class NullClassLoader extends ClassLoader {
+ static NullClassLoader INSTANCE = new NullClassLoader();
+}
diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefineTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefineTest.java
index a35ca44799947722c5140e56591a082339296e15..3a9076ee395849aa7f13cb717dc405e0db091e9b 100644
--- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefineTest.java
+++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefineTest.java
@@ -104,12 +104,12 @@ public class AbstractClassEnhancePluginDefineTest {
private DynamicType.Builder> transformStaticMethod(DynamicType.Builder newBuilder) {
MockPluginStaticMethodInstrumentation staticMethodInstrumentation = new MockPluginStaticMethodInstrumentation();
- return staticMethodInstrumentation.define(WEAVE_CLASS, newBuilder);
+ return staticMethodInstrumentation.define(WEAVE_CLASS, newBuilder, AbstractClassEnhancePluginDefineTest.class.getClassLoader());
}
private DynamicType.Builder transformInstanceMethod(DynamicType.Builder> builder) {
MockPluginInstanceMethodInstrumentation instrumentation = new MockPluginInstanceMethodInstrumentation();
- return instrumentation.define(WEAVE_CLASS, builder);
+ return instrumentation.define(WEAVE_CLASS, builder, AbstractClassEnhancePluginDefineTest.class.getClassLoader());
}
}
diff --git a/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/SkyWalkingAgent.java b/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/SkyWalkingAgent.java
index 2fe77d5baa79a8fb6d539157a2a1fde3413ddfbe..3b91cf12c6e904e5e43691f555a5dd44c448f4e8 100644
--- a/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/SkyWalkingAgent.java
+++ b/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/SkyWalkingAgent.java
@@ -57,7 +57,7 @@ public class SkyWalkingAgent {
ClassLoader classLoader) {
List pluginDefines = pluginFinder.find(typeDescription.getTypeName());
for (AbstractClassEnhancePluginDefine pluginDefine : pluginDefines) {
- DynamicType.Builder> newBuilder = pluginDefine.define(typeDescription.getTypeName(), builder);
+ DynamicType.Builder> newBuilder = pluginDefine.define(typeDescription.getTypeName(), builder, classLoader);
if (newBuilder != null) {
return newBuilder;
}