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

Fix witness class fail, because of different class loaders.

上级 5ff0e987
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,8 +15,6 @@ 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.
*
......@@ -28,7 +24,7 @@ public abstract class AbstractClassEnhancePluginDefine {
* @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;
......@@ -86,8 +81,4 @@ public abstract class AbstractClassEnhancePluginDefine {
protected String[] witnessClasses() {
return new String[] {};
}
public void setClassTypePool(TypePool classTypePool) {
this.classTypePool = classTypePool;
}
}
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<AbstractClassEnhancePluginDefine> loadPlugins() {
TypePool classTypePool = TypePool.Default.ofClassPath();
PluginResourcesResolver resolver = new PluginResourcesResolver();
List<URL> 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());
......
......@@ -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();
}
......
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 {
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());
}
}
......
......@@ -57,7 +57,7 @@ public class SkyWalkingAgent {
ClassLoader classLoader) {
List<AbstractClassEnhancePluginDefine> 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;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册