diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/loader/InterceptorInstanceLoader.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/loader/InterceptorInstanceLoader.java index 7b2efeead54dd6c4522ab0708d17a678f1293ae9..9e25d54d8d7e47e28c603e09ede8011f4ee7c9c0 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/loader/InterceptorInstanceLoader.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/loader/InterceptorInstanceLoader.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantLock; + import org.skywalking.apm.agent.core.boot.AgentPackageNotFoundException; import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; @@ -58,8 +59,23 @@ public class InterceptorInstanceLoader { private static Map EXTEND_PLUGIN_CLASSLOADERS = new HashMap(); + /** + * Load an instance of interceptor, and keep it singleton. + * Create {@link AgentClassLoader} for each targetClassLoader, as an extend classloader. + * It can load interceptor classes from plugins, activations folders. + * + * @param className + * @param targetClassLoader + * @param + * @return + * @throws InvocationTargetException + * @throws IllegalAccessException + * @throws InstantiationException + * @throws ClassNotFoundException + * @throws AgentPackageNotFoundException + */ public static T load(String className, ClassLoader targetClassLoader) - throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException, AgentPackageNotFoundException { + throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException, AgentPackageNotFoundException { if (targetClassLoader == null) { targetClassLoader = InterceptorInstanceLoader.class.getClassLoader(); } @@ -82,7 +98,7 @@ public class InterceptorInstanceLoader { } } - return (T)inst; + return (T) inst; } /** @@ -98,7 +114,7 @@ public class InterceptorInstanceLoader { * @throws ClassNotFoundException */ public static T load0(String className, ClassLoader targetClassLoader) - throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException { + throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException { if (targetClassLoader == null) { targetClassLoader = InterceptorInstanceLoader.class.getClassLoader(); } @@ -130,14 +146,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. @@ -146,7 +162,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; @@ -186,21 +202,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) { @@ -211,10 +227,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(); } }