diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracingContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracingContext.java index 6ba30da3a..2315f4fbe 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracingContext.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracingContext.java @@ -95,7 +95,7 @@ public class TracingContext implements AbstractTracerContext { @Override public AbstractSpan createEntrySpan(final String operationName) { AbstractTracingSpan entrySpan; - AbstractTracingSpan parentSpan = peek(); + final AbstractTracingSpan parentSpan = peek(); final int parentSpanId = parentSpan == null ? -1 : parentSpan.getSpanId(); if (parentSpan == null) { entrySpan = (AbstractTracingSpan)DictionaryManager.findOperationNameCodeSection() @@ -112,7 +112,18 @@ public class TracingContext implements AbstractTracerContext { entrySpan.start(); return push(entrySpan); } else if (parentSpan.isEntry()) { - return parentSpan.start(); + entrySpan = (AbstractTracingSpan)DictionaryManager.findOperationNameCodeSection() + .find(segment.getApplicationId(), operationName) + .doInCondition(new PossibleFound.FoundAndObtain() { + @Override public Object doProcess(int operationId) { + return parentSpan.setOperationId(operationId); + } + }, new PossibleFound.NotFoundAndObtain() { + @Override public Object doProcess() { + return parentSpan.setOperationName(operationName); + } + }); + return entrySpan.start(); } else { throw new IllegalStateException("The Entry Span can't be the child of Non-Entry Span"); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java index 4ce67ac86..f1c486234 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java @@ -113,6 +113,16 @@ public abstract class AbstractTracingSpan implements AbstractSpan { return this; } + public AbstractTracingSpan setOperationName(String operationName) { + this.operationName = operationName; + return this; + } + + public AbstractTracingSpan setOperationId(int operationId) { + this.operationId = operationId; + return this; + } + public int getSpanId() { return spanId; } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java index 3b083e550..96d05f757 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/ClassEnhancePluginDefine.java @@ -104,7 +104,7 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi for (ConstructorInterceptPoint constructorInterceptPoint : constructorInterceptPoints) { newClassBuilder = newClassBuilder.constructor(ElementMatchers.any()).intercept(SuperMethodCall.INSTANCE .andThen(MethodDelegation.withDefaultConfiguration() - .to(new ConstructorInter(constructorInterceptPoint.getConstructorInterceptor())) + .to(new ConstructorInter(constructorInterceptPoint.getConstructorInterceptor(), classLoader)) ) ); } @@ -135,7 +135,7 @@ public abstract class ClassEnhancePluginDefine extends AbstractClassEnhancePlugi newClassBuilder.method(not(isStatic()).and(instanceMethodsInterceptPoint.getMethodsMatcher())) .intercept( MethodDelegation.withDefaultConfiguration() - .to(new InstMethodsInter(interceptor)) + .to(new InstMethodsInter(interceptor, classLoader)) ); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/ConstructorInter.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/ConstructorInter.java index 67f2e6f94..07ab7fad7 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/ConstructorInter.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/ConstructorInter.java @@ -1,9 +1,11 @@ package org.skywalking.apm.agent.core.plugin.interceptor.enhance; +import java.lang.reflect.InvocationTargetException; import net.bytebuddy.implementation.bind.annotation.AllArguments; import net.bytebuddy.implementation.bind.annotation.FieldProxy; import net.bytebuddy.implementation.bind.annotation.RuntimeType; import net.bytebuddy.implementation.bind.annotation.This; +import org.skywalking.apm.agent.core.plugin.PluginException; import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader; import org.skywalking.apm.logging.ILog; import org.skywalking.apm.logging.LogManager; @@ -18,19 +20,21 @@ public class ConstructorInter { private static final ILog logger = LogManager.getLogger(ConstructorInter.class); /** - * A class full name, and instanceof {@link InstanceConstructorInterceptor} + * An {@link InstanceConstructorInterceptor} * This name should only stay in {@link String}, the real {@link Class} type will trigger classloader failure. * If you want to know more, please check on books about Classloader or Classloader appointment mechanism. */ - private String constructorInterceptorClassName; + private InstanceConstructorInterceptor interceptor; /** - * Set the name of {@link ConstructorInter#constructorInterceptorClassName} - * * @param constructorInterceptorClassName class full name. */ - public ConstructorInter(String constructorInterceptorClassName) { - this.constructorInterceptorClassName = constructorInterceptorClassName; + public ConstructorInter(String constructorInterceptorClassName, ClassLoader classLoader) throws PluginException { + try { + interceptor = InterceptorInstanceLoader.load(constructorInterceptorClassName, classLoader); + } catch (Throwable t) { + throw new PluginException("Can't create InstanceConstructorInterceptor.", t); + } } /** @@ -43,7 +47,6 @@ public class ConstructorInter { public void intercept(@This Object obj, @AllArguments Object[] allArguments) { try { - InstanceConstructorInterceptor interceptor = InterceptorInstanceLoader.load(constructorInterceptorClassName, obj.getClass().getClassLoader()); EnhancedInstance targetObject = (EnhancedInstance)obj; interceptor.onConstruct(targetObject, allArguments); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInter.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInter.java index be8c9c0eb..6b99d4d26 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInter.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInter.java @@ -1,6 +1,7 @@ package org.skywalking.apm.agent.core.plugin.interceptor.enhance; import net.bytebuddy.implementation.bind.annotation.*; +import org.skywalking.apm.agent.core.plugin.PluginException; import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader; import org.skywalking.apm.logging.ILog; import org.skywalking.apm.logging.LogManager; @@ -18,19 +19,21 @@ public class InstMethodsInter { private static final ILog logger = LogManager.getLogger(InstMethodsInter.class); /** - * A class full name, and instanceof {@link InstanceMethodsAroundInterceptor} + * An {@link InstanceMethodsAroundInterceptor} * This name should only stay in {@link String}, the real {@link Class} type will trigger classloader failure. * If you want to know more, please check on books about Classloader or Classloader appointment mechanism. */ - private String instanceMethodsAroundInterceptorClassName; + private InstanceMethodsAroundInterceptor interceptor; /** - * Set the name of {@link InstMethodsInter#instanceMethodsAroundInterceptorClassName} - * * @param instanceMethodsAroundInterceptorClassName class full name. */ - public InstMethodsInter(String instanceMethodsAroundInterceptorClassName) { - this.instanceMethodsAroundInterceptorClassName = instanceMethodsAroundInterceptorClassName; + public InstMethodsInter(String instanceMethodsAroundInterceptorClassName, ClassLoader classLoader) { + try { + interceptor = InterceptorInstanceLoader.load(instanceMethodsAroundInterceptorClassName, classLoader); + } catch (Throwable t) { + throw new PluginException("Can't create InstanceMethodsAroundInterceptor.", t); + } } /** @@ -50,8 +53,6 @@ public class InstMethodsInter { @SuperCall Callable zuper, @Origin Method method ) throws Throwable { - InstanceMethodsAroundInterceptor interceptor = InterceptorInstanceLoader - .load(instanceMethodsAroundInterceptorClassName, obj.getClass().getClassLoader()); EnhancedInstance targetObject = (EnhancedInstance)obj; MethodInterceptResult result = new MethodInterceptResult(); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInterWithOverrideArgs.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInterWithOverrideArgs.java index 3dbedf6e9..980f30e49 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInterWithOverrideArgs.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/InstMethodsInterWithOverrideArgs.java @@ -7,6 +7,7 @@ import net.bytebuddy.implementation.bind.annotation.Morph; import net.bytebuddy.implementation.bind.annotation.Origin; import net.bytebuddy.implementation.bind.annotation.RuntimeType; import net.bytebuddy.implementation.bind.annotation.This; +import org.skywalking.apm.agent.core.plugin.PluginException; import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader; import org.skywalking.apm.logging.ILog; import org.skywalking.apm.logging.LogManager; @@ -21,19 +22,21 @@ public class InstMethodsInterWithOverrideArgs { private static final ILog logger = LogManager.getLogger(InstMethodsInterWithOverrideArgs.class); /** - * A class full name, and instanceof {@link InstanceMethodsAroundInterceptor} + * An {@link InstanceMethodsAroundInterceptor} * This name should only stay in {@link String}, the real {@link Class} type will trigger classloader failure. * If you want to know more, please check on books about Classloader or Classloader appointment mechanism. */ - private String instanceMethodsAroundInterceptorClassName; + private InstanceMethodsAroundInterceptor interceptor; /** - * Set the name of {@link InstMethodsInterWithOverrideArgs#instanceMethodsAroundInterceptorClassName} - * * @param instanceMethodsAroundInterceptorClassName class full name. */ - public InstMethodsInterWithOverrideArgs(String instanceMethodsAroundInterceptorClassName) { - this.instanceMethodsAroundInterceptorClassName = instanceMethodsAroundInterceptorClassName; + public InstMethodsInterWithOverrideArgs(String instanceMethodsAroundInterceptorClassName, ClassLoader classLoader) { + try { + interceptor = InterceptorInstanceLoader.load(instanceMethodsAroundInterceptorClassName, classLoader); + } catch (Throwable t) { + throw new PluginException("Can't create InstanceMethodsAroundInterceptor.", t); + } } /** @@ -53,8 +56,6 @@ public class InstMethodsInterWithOverrideArgs { @Origin Method method, @Morph(defaultMethod = true) OverrideCallable zuper ) throws Throwable { - InstanceMethodsAroundInterceptor interceptor = InterceptorInstanceLoader - .load(instanceMethodsAroundInterceptorClassName, obj.getClass().getClassLoader()); EnhancedInstance targetObject = (EnhancedInstance)obj; MethodInterceptResult result = new MethodInterceptResult(); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/loader/InterceptorInstanceLoader.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/loader/InterceptorInstanceLoader.java index 0270b0d0e..3962d5d8c 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/loader/InterceptorInstanceLoader.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/interceptor/loader/InterceptorInstanceLoader.java @@ -38,6 +38,9 @@ public class InterceptorInstanceLoader { public static T load(String className, ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException { + if (targetClassLoader == null) { + targetClassLoader = InterceptorInstanceLoader.class.getClassLoader(); + } String instanceKey = className + "_OF_" + targetClassLoader.getClass().getName() + "@" + Integer.toHexString(targetClassLoader.hashCode()); Object inst = INSTANCE_CACHE.get(instanceKey); if (inst == null) { @@ -66,14 +69,14 @@ public class InterceptorInstanceLoader { } } - return (T) inst; + return (T)inst; } /** * load class from class binary files. * Most likely all the interceptor implementations should be loaded by this. * - * @param className interceptor class name. + * @param className interceptor class name. * @param targetClassLoader the classloader, which should load the interceptor. * @param * @return interceptor instance. @@ -82,7 +85,7 @@ public class InterceptorInstanceLoader { * @throws InstantiationException */ private static T loadBinary(String className, - ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException { + ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException { String path = "/" + className.replace('.', '/').concat(".class"); byte[] data = null; BufferedInputStream is = null; @@ -122,21 +125,21 @@ public class InterceptorInstanceLoader { } defineClassMethod.setAccessible(true); logger.debug("load binary code of {} to classloader {}", className, targetClassLoader); - Class type = (Class) defineClassMethod.invoke(targetClassLoader, className, data, 0, data.length, null); - return (T) type.newInstance(); + Class type = (Class)defineClassMethod.invoke(targetClassLoader, className, data, 0, data.length, null); + return (T)type.newInstance(); } /** * Find loaded class in the current classloader. * Just in case some classes have already been loaded for some reason. * - * @param className interceptor class name. + * @param className interceptor class name. * @param targetClassLoader the classloader, which should load the interceptor. * @param * @return interceptor instance. */ private static T findLoadedClass(String className, - ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException { + ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException { Method defineClassMethod = null; Class targetClassLoaderType = targetClassLoader.getClass(); while (defineClassMethod == null && targetClassLoaderType != null) { @@ -147,10 +150,10 @@ public class InterceptorInstanceLoader { } } defineClassMethod.setAccessible(true); - Class type = (Class) defineClassMethod.invoke(targetClassLoader, className); + Class type = (Class)defineClassMethod.invoke(targetClassLoader, className); if (type == null) { return null; } - return (T) type.newInstance(); + return (T)type.newInstance(); } }