提交 d26d925c 编写于 作者: wu-sheng's avatar wu-sheng

Fix witness class fail, because of different class loaders.

上级 5ff0e987
package org.skywalking.apm.agent.core.plugin; package org.skywalking.apm.agent.core.plugin;
import net.bytebuddy.dynamic.DynamicType; 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.agent.core.plugin.interceptor.enhance.ClassEnhancePluginDefine;
import org.skywalking.apm.util.StringUtil; import org.skywalking.apm.util.StringUtil;
import org.skywalking.apm.logging.ILog; import org.skywalking.apm.logging.ILog;
...@@ -17,8 +15,6 @@ import org.skywalking.apm.logging.LogManager; ...@@ -17,8 +15,6 @@ import org.skywalking.apm.logging.LogManager;
public abstract class AbstractClassEnhancePluginDefine { public abstract class AbstractClassEnhancePluginDefine {
private static final ILog logger = LogManager.getLogger(AbstractClassEnhancePluginDefine.class); private static final ILog logger = LogManager.getLogger(AbstractClassEnhancePluginDefine.class);
private TypePool classTypePool;
/** /**
* Main entrance of enhancing the class. * Main entrance of enhancing the class.
* *
...@@ -28,7 +24,7 @@ public abstract class AbstractClassEnhancePluginDefine { ...@@ -28,7 +24,7 @@ public abstract class AbstractClassEnhancePluginDefine {
* @throws PluginException, when set builder failure. * @throws PluginException, when set builder failure.
*/ */
public DynamicType.Builder<?> define(String transformClassName, public DynamicType.Builder<?> define(String transformClassName,
DynamicType.Builder<?> builder) throws PluginException { DynamicType.Builder<?> builder, ClassLoader classLoader) throws PluginException {
String interceptorDefineClassName = this.getClass().getName(); String interceptorDefineClassName = this.getClass().getName();
if (StringUtil.isEmpty(transformClassName)) { if (StringUtil.isEmpty(transformClassName)) {
...@@ -44,8 +40,7 @@ public abstract class AbstractClassEnhancePluginDefine { ...@@ -44,8 +40,7 @@ public abstract class AbstractClassEnhancePluginDefine {
String[] witnessClasses = witnessClasses(); String[] witnessClasses = witnessClasses();
if (witnessClasses != null) { if (witnessClasses != null) {
for (String witnessClass : witnessClasses) { for (String witnessClass : witnessClasses) {
Resolution witnessClassResolution = classTypePool.describe(witnessClass); if (!WitnessClassFinder.INSTANCE.exist(witnessClass, classLoader)) {
if (!witnessClassResolution.isResolved()) {
logger.warn("enhance class {} by plugin {} is not working. Because witness class {} is not existed.", transformClassName, interceptorDefineClassName, logger.warn("enhance class {} by plugin {} is not working. Because witness class {} is not existed.", transformClassName, interceptorDefineClassName,
witnessClass); witnessClass);
return null; return null;
...@@ -86,8 +81,4 @@ public abstract class AbstractClassEnhancePluginDefine { ...@@ -86,8 +81,4 @@ public abstract class AbstractClassEnhancePluginDefine {
protected String[] witnessClasses() { protected String[] witnessClasses() {
return new String[] {}; return new String[] {};
} }
public void setClassTypePool(TypePool classTypePool) {
this.classTypePool = classTypePool;
}
} }
package org.skywalking.apm.agent.core.plugin; package org.skywalking.apm.agent.core.plugin;
import net.bytebuddy.pool.TypePool;
import org.skywalking.apm.logging.ILog; import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager; import org.skywalking.apm.logging.LogManager;
...@@ -24,8 +23,6 @@ public class PluginBootstrap { ...@@ -24,8 +23,6 @@ public class PluginBootstrap {
* @return plugin definition list. * @return plugin definition list.
*/ */
public List<AbstractClassEnhancePluginDefine> loadPlugins() { public List<AbstractClassEnhancePluginDefine> loadPlugins() {
TypePool classTypePool = TypePool.Default.ofClassPath();
PluginResourcesResolver resolver = new PluginResourcesResolver(); PluginResourcesResolver resolver = new PluginResourcesResolver();
List<URL> resources = resolver.getResources(); List<URL> resources = resolver.getResources();
...@@ -50,7 +47,6 @@ public class PluginBootstrap { ...@@ -50,7 +47,6 @@ public class PluginBootstrap {
logger.debug("loading plugin class {}.", pluginDefine.getDefineClass()); logger.debug("loading plugin class {}.", pluginDefine.getDefineClass());
AbstractClassEnhancePluginDefine plugin = AbstractClassEnhancePluginDefine plugin =
(AbstractClassEnhancePluginDefine) Class.forName(pluginDefine.getDefineClass()).newInstance(); (AbstractClassEnhancePluginDefine) Class.forName(pluginDefine.getDefineClass()).newInstance();
plugin.setClassTypePool(classTypePool);
plugins.add(plugin); plugins.add(plugin);
} catch (Throwable t) { } catch (Throwable t) {
logger.error(t, "load plugin [{}] failure.", pluginDefine.getDefineClass()); logger.error(t, "load plugin [{}] failure.", pluginDefine.getDefineClass());
......
...@@ -62,7 +62,7 @@ public class TracingBootstrap { ...@@ -62,7 +62,7 @@ public class TracingBootstrap {
} }
DynamicType.Builder<?> newClassBuilder = DynamicType.Builder<?> newClassBuilder =
new ByteBuddy().rebase(resolution.resolve(), ClassFileLocator.ForClassLoader.ofClassPath()); 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) newClassBuilder.make(new TypeResolutionStrategy.Active()).load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded(); .getLoaded();
} }
......
package org.skywalking.apm.agent.core.plugin;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import net.bytebuddy.pool.TypePool;
/**
* The <code>WitnessClassFinder</code> 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<ClassLoader, TypePool> poolMap = new ConcurrentHashMap<ClassLoader, TypePool>();
/**
* @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();
}
...@@ -104,12 +104,12 @@ public class AbstractClassEnhancePluginDefineTest { ...@@ -104,12 +104,12 @@ public class AbstractClassEnhancePluginDefineTest {
private DynamicType.Builder<?> transformStaticMethod(DynamicType.Builder newBuilder) { private DynamicType.Builder<?> transformStaticMethod(DynamicType.Builder newBuilder) {
MockPluginStaticMethodInstrumentation staticMethodInstrumentation = new MockPluginStaticMethodInstrumentation(); 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) { private DynamicType.Builder transformInstanceMethod(DynamicType.Builder<?> builder) {
MockPluginInstanceMethodInstrumentation instrumentation = new MockPluginInstanceMethodInstrumentation(); MockPluginInstanceMethodInstrumentation instrumentation = new MockPluginInstanceMethodInstrumentation();
return instrumentation.define(WEAVE_CLASS, builder); return instrumentation.define(WEAVE_CLASS, builder, AbstractClassEnhancePluginDefineTest.class.getClassLoader());
} }
} }
......
...@@ -57,7 +57,7 @@ public class SkyWalkingAgent { ...@@ -57,7 +57,7 @@ public class SkyWalkingAgent {
ClassLoader classLoader) { ClassLoader classLoader) {
List<AbstractClassEnhancePluginDefine> pluginDefines = pluginFinder.find(typeDescription.getTypeName()); List<AbstractClassEnhancePluginDefine> pluginDefines = pluginFinder.find(typeDescription.getTypeName());
for (AbstractClassEnhancePluginDefine pluginDefine : pluginDefines) { for (AbstractClassEnhancePluginDefine pluginDefine : pluginDefines) {
DynamicType.Builder<?> newBuilder = pluginDefine.define(typeDescription.getTypeName(), builder); DynamicType.Builder<?> newBuilder = pluginDefine.define(typeDescription.getTypeName(), builder, classLoader);
if (newBuilder != null) { if (newBuilder != null) {
return newBuilder; return newBuilder;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册