diff --git a/.github/ISSUE_TEMPLATE/----.md b/.github/ISSUE_TEMPLATE/----.md deleted file mode 100644 index e4063178..00000000 --- a/.github/ISSUE_TEMPLATE/----.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: 问题报告 -about: 描述清楚问题和当前环境 - ---- - -**操作环境** - -|...|...| -|---|---| -|操作系统|Linux| -|JVM版本|OpenJDK-8.0.5| -|沙箱容器版本|1.1.0| -|沙箱API版本|1.0.16| - -**问题描述** - -简明扼要的描述清楚遇到的问题 - -**重现步骤** - -描述通过怎样的操作重现你的问题和疑惑 -1. 第一步 -2. 第二步 -3. 第三步 -4. ... - -**附件(如有)** - -在这个环节添加上可能的附件 diff --git a/.gitignore b/.gitignore index 331306b5..ae9d54f8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,12 @@ ## for maven pom.xml.versionsBackup +sandbox-api/target/ +sandbox-common-api/target/ +sandbox-core/target/ +sandbox-provider-api/target/ +sandbox-spy/target/ +sandbox-agent/target/ +sandbox-debug-module/target/ +sandbox-mgr-module/target/ +sandbox-mgr-provider/target/ diff --git a/bin/sandbox.properties b/bin/sandbox.properties index a1e9f2fe..65555b0e 100755 --- a/bin/sandbox.properties +++ b/bin/sandbox.properties @@ -24,9 +24,3 @@ user_module=~/.sandbox-module; # switch the sandbox can enhance system class unsafe.enable=true -# define the sandbox event pool arguments(min/max/total) -event.pool.enable=true -event.pool.max.total=6000 -event.pool.min.idle.per.event=50 -event.pool.max.idle.per.event=100 -event.pool.max.total.per.event=2000 diff --git a/bin/sandbox.sh b/bin/sandbox.sh index 7385e877..575d7ada 100755 --- a/bin/sandbox.sh +++ b/bin/sandbox.sh @@ -307,43 +307,43 @@ function main() { # -v show version [[ ! -z ${OP_VERSION} ]] \ - && sandbox_curl_with_exit "info/version" + && sandbox_curl_with_exit "sandbox-info/version" # -l list loaded modules [[ ! -z ${OP_MODULE_LIST} ]] \ - && sandbox_curl_with_exit "module-mgr/list" + && sandbox_curl_with_exit "sandbox-module-mgr/list" # -F force flush module [[ ! -z ${OP_MODULE_FORCE_FLUSH} ]] \ - && sandbox_curl_with_exit "module-mgr/flush" "&force=true" + && sandbox_curl_with_exit "sandbox-module-mgr/flush" "&force=true" # -f flush module [[ ! -z ${OP_MODULE_FLUSH} ]] \ - && sandbox_curl_with_exit "module-mgr/flush" "&force=false" + && sandbox_curl_with_exit "sandbox-module-mgr/flush" "&force=false" # -R reset sandbox [[ ! -z ${OP_MODULE_RESET} ]] \ - && sandbox_curl_with_exit "module-mgr/reset" + && sandbox_curl_with_exit "sandbox-module-mgr/reset" # -u unload module [[ ! -z ${OP_MODULE_UNLOAD} ]] \ - && sandbox_curl_with_exit "module-mgr/unload" "&action=unload&ids=${ARG_MODULE_UNLOAD}" + && sandbox_curl_with_exit "sandbox-module-mgr/unload" "&action=unload&ids=${ARG_MODULE_UNLOAD}" # -a active module [[ ! -z ${OP_MODULE_ACTIVE} ]] \ - && sandbox_curl_with_exit "module-mgr/active" "&ids=${ARG_MODULE_ACTIVE}" + && sandbox_curl_with_exit "sandbox-module-mgr/active" "&ids=${ARG_MODULE_ACTIVE}" # -A frozen module [[ ! -z ${OP_MODULE_FROZEN} ]] \ - && sandbox_curl_with_exit "module-mgr/frozen" "&ids=${ARG_MODULE_FROZEN}" + && sandbox_curl_with_exit "sandbox-module-mgr/frozen" "&ids=${ARG_MODULE_FROZEN}" # -m module detail [[ ! -z ${OP_MODULE_DETAIL} ]] \ - && sandbox_curl_with_exit "module-mgr/detail" "&id=${ARG_MODULE_DETAIL}" + && sandbox_curl_with_exit "sandbox-module-mgr/detail" "&id=${ARG_MODULE_DETAIL}" # -S shutdown [[ ! -z ${OP_SHUTDOWN} ]] \ - && sandbox_curl_with_exit "control/shutdown" + && sandbox_curl_with_exit "sandbox-control/shutdown" # -d debug if [[ ! -z ${OP_DEBUG} ]]; then @@ -352,7 +352,7 @@ function main() { fi # default - sandbox_curl "info/version" + sandbox_curl "sandbox-info/version" exit } diff --git a/doc/JVM-SANDBOX-USER-GUIDE-Chinese.md b/doc/JVM-SANDBOX-USER-GUIDE-Chinese.md index abdcc29b..d0d2d355 100644 --- a/doc/JVM-SANDBOX-USER-GUIDE-Chinese.md +++ b/doc/JVM-SANDBOX-USER-GUIDE-Chinese.md @@ -157,7 +157,7 @@ EVENT_POOL_KEY_MAX : 2000 1. 必须实现`com.alibaba.jvm.sandbox.api.Module`接口 1. 必须完成`META-INF/services/com.alibaba.jvm.sandbox.api.Module`文件中的注册(Java SPI规范要求) - - 同一个JAR包所声明的所有模块共享同一个ModuleClassLoader + - 同一个JAR包所声明的所有模块共享同一个ModuleJarClassLoader - 模块一共有四种状态 @@ -234,7 +234,7 @@ EVENT_POOL_KEY_MAX : 2000 - HTTP链接 - WEBSOCKET链接 - - ModuleClassLoader + - ModuleJarClassLoader - 待卸载模块引起的事件插桩 - `-f` @@ -261,7 +261,7 @@ EVENT_POOL_KEY_MAX : 2000 - `-a` - 激活模块,模块激活后才能受到沙箱事件 + 激活模块,模块激活后才能收到沙箱事件 - `-A` @@ -283,7 +283,7 @@ EVENT_POOL_KEY_MAX : 2000 > STATE : FROZEN > MODE : {AGENT,ATTACH} > CLASS : class com.alibaba.jvm.sandbox.module.mgr.ModuleMgrModule - > LOADER : ModuleClassLoader[crc32=1721245995;file=/Users/luanjia/opt/sandbox/lib/../module/sandbox-mgr-module.jar;] + > LOADER : ModuleJarClassLoader[crc32=1721245995;file=/Users/luanjia/opt/sandbox/lib/../module/sandbox-mgr-module.jar;] > cCnt : 0 > mCnt : 0 > ``` diff --git a/doc/JVM-SANDBOX-USER-GUIDE-English.md b/doc/JVM-SANDBOX-USER-GUIDE-English.md index 7a82b6a3..de4bdfe4 100644 --- a/doc/JVM-SANDBOX-USER-GUIDE-English.md +++ b/doc/JVM-SANDBOX-USER-GUIDE-English.md @@ -155,7 +155,7 @@ Then the success of the start, the sandbox has been successfully implanted in th 2. You must implement the `com.alibaba.jvm.sandbox.api.Module` interface 3. You must complete the registration in the `META-INF / services / com.alibaba.jvm.sandbox.api.Module` file (Java SPI specification requirements) - - All modules declared in the same JAR package share the same ModuleClassLoader + - All modules declared in the same JAR package share the same ModuleJarClassLoader - There are four states in the module @@ -234,7 +234,7 @@ Then the success of the start, the sandbox has been successfully implanted in th - HTTP link - WEBSOCKET link - - ModuleClassLoader + - ModuleJarClassLoader - The event is caused by the unloading of the module - `-f` @@ -283,7 +283,7 @@ Then the success of the start, the sandbox has been successfully implanted in th > STATE : FROZEN > MODE : {AGENT,ATTACH} > CLASS : class com.alibaba.jvm.sandbox.module.mgr.ModuleMgrModule - > LOADER : ModuleClassLoader[crc32=1721245995;file=/Users/vlinux/opt/sandbox/lib/../module/sandbox-mgr-module.jar;] + > LOADER : ModuleJarClassLoader[crc32=1721245995;file=/Users/vlinux/opt/sandbox/lib/../module/sandbox-mgr-module.jar;] > cCnt : 0 > mCnt : 0 > ``` diff --git a/pom.xml b/pom.xml index d03352bd..5f263e92 100644 --- a/pom.xml +++ b/pom.xml @@ -5,14 +5,14 @@ com.alibaba.jvm.sandbox sandbox - 1.1.2-SNAPSHOT + 1.2.0-SNAPSHOT pom sandbox ${sandbox.version} UTF-8 - 1.1.2-SNAPSHOT + 1.2.0-SNAPSHOT diff --git a/sandbox-agent/pom.xml b/sandbox-agent/pom.xml index 6037e4a7..5ce9c8c8 100755 --- a/sandbox-agent/pom.xml +++ b/sandbox-agent/pom.xml @@ -6,7 +6,7 @@ com.alibaba.jvm.sandbox sandbox - 1.1.2-SNAPSHOT + 1.2.0-SNAPSHOT sandbox-agent sandbox-agent ${sandbox.version} diff --git a/sandbox-agent/src/main/java/com/alibaba/jvm/sandbox/agent/AgentLauncher.java b/sandbox-agent/src/main/java/com/alibaba/jvm/sandbox/agent/AgentLauncher.java index 3b331223..d14db8c5 100755 --- a/sandbox-agent/src/main/java/com/alibaba/jvm/sandbox/agent/AgentLauncher.java +++ b/sandbox-agent/src/main/java/com/alibaba/jvm/sandbox/agent/AgentLauncher.java @@ -15,39 +15,14 @@ /** * SandboxAgent启动器 * * * @author luanjia@taobao.com */ public class AgentLauncher { -// // sandbox配置文件目录 -// private static final String SANDBOX_CFG_PATH -// = SANDBOX_HOME + File.separatorChar + "cfg"; -// -// // 模块目录 -// private static final String SANDBOX_MODULE_PATH -// = SANDBOX_HOME + File.separatorChar + "module"; -// -// -// // sandbox核心工程文件 -// private static final String SANDBOX_CORE_JAR_PATH -// = SANDBOX_HOME + File.separatorChar + "lib" + File.separator + "sandbox-core.jar"; -// -// // sandbox-spy工程文件 -// private static final String SANDBOX_SPY_JAR_PATH -// = SANDBOX_HOME + File.separatorChar + "lib" + File.separator + "sandbox-spy.jar"; -// -// private static final String SANDBOX_PROPERTIES_PATH -// = SANDBOX_CFG_PATH + File.separator + "sandbox.properties"; -// -// // sandbox-provider库目录 -// private static final String SANDBOX_PROVIDER_LIB_PATH -// = SANDBOX_HOME + File.separatorChar + "provider"; - - private static String getSandboxCfgPath(String sandboxHome) { return sandboxHome + File.separatorChar + "cfg"; } @@ -114,7 +89,7 @@ private static String getSandboxProviderPath(String sandboxHome) { */ public static void premain(String featureString, Instrumentation inst) { LAUNCH_MODE = LAUNCH_MODE_AGENT; - main(toFeatureMap(featureString), inst); + install(toFeatureMap(featureString), inst); } /** @@ -130,7 +105,7 @@ public static void agentmain(String featureString, Instrumentation inst) { writeAttachResult( getNamespace(featureMap), getToken(featureMap), - main(featureMap, inst) + install(featureMap, inst) ); } @@ -202,40 +177,37 @@ private static synchronized ClassLoader loadOrDefineClassLoader(final String nam } /** - * 获取当前命名空间下的ClassLoader - *

- * 该方法将会被{@code ControlModule#shutdown}通过反射调用, - * 请保持方法声明一致 + * 删除指定命名空间下的jvm-sandbox * - * @param namespace 命名空间 - * @return 当前的ClassLoader - * @since {@code sandbox-api:1.0.15} + * @param namespace 指定命名空间 + * @throws Throwable 删除失败 */ @SuppressWarnings("unused") - public static ClassLoader getClassLoader(final String namespace) { - return sandboxClassLoaderMap.get(namespace); + public static synchronized void uninstall(final String namespace) throws Throwable { + final SandboxClassLoader sandboxClassLoader = sandboxClassLoaderMap.get(namespace); + if (null == sandboxClassLoader) { + return; + } + + // 关闭服务器 + final Class classOfProxyServer = sandboxClassLoader.loadClass(CLASS_OF_PROXY_CORE_SERVER); + classOfProxyServer.getMethod("destroy") + .invoke(classOfProxyServer.getMethod("getInstance").invoke(null)); + + // 关闭SandboxClassLoader + sandboxClassLoader.closeIfPossible(); + sandboxClassLoaderMap.remove(namespace); } /** - * 清理namespace所指定的ClassLoader - *

- * 该方法将会被{@code ControlModule#shutdown}通过反射调用, - * 请保持方法声明一致 + * 在当前JVM安装jvm-sandbox * - * @param namespace 命名空间 - * @return 被清理的ClassLoader + * @param featureMap 启动参数配置 + * @param inst inst + * @return 服务器IP:PORT */ - @SuppressWarnings("unused") - public static synchronized ClassLoader cleanClassLoader(final String namespace) { - final SandboxClassLoader sandboxClassLoader = sandboxClassLoaderMap.remove(namespace); - if (null != sandboxClassLoader) { - sandboxClassLoader.closeIfPossible(); - } - return sandboxClassLoader; - } - - private static synchronized InetSocketAddress main(final Map featureMap, - final Instrumentation inst) { + private static synchronized InetSocketAddress install(final Map featureMap, + final Instrumentation inst) { final String namespace = getNamespace(featureMap); final String propertiesFilePath = getPropertiesFilePath(featureMap); @@ -250,29 +222,29 @@ private static synchronized InetSocketAddress main(final Map fea ))); // 构造自定义的类加载器,尽量减少Sandbox对现有工程的侵蚀 - final ClassLoader agentLoader = loadOrDefineClassLoader( + final ClassLoader sandboxClassLoader = loadOrDefineClassLoader( namespace, getSandboxCoreJarPath(getSandboxHome(featureMap)) // SANDBOX_CORE_JAR_PATH ); // CoreConfigure类定义 - final Class classOfConfigure = agentLoader.loadClass(CLASS_OF_CORE_CONFIGURE); + final Class classOfConfigure = sandboxClassLoader.loadClass(CLASS_OF_CORE_CONFIGURE); // 反序列化成CoreConfigure类实例 final Object objectOfCoreConfigure = classOfConfigure.getMethod("toConfigure", String.class, String.class) .invoke(null, coreFeatureString, propertiesFilePath); // CoreServer类定义 - final Class classOfProxyServer = agentLoader.loadClass(CLASS_OF_PROXY_CORE_SERVER); + final Class classOfProxyServer = sandboxClassLoader.loadClass(CLASS_OF_PROXY_CORE_SERVER); // 获取CoreServer单例 - final Object objectOfCoreServer = classOfProxyServer + final Object objectOfProxyServer = classOfProxyServer .getMethod("getInstance") .invoke(null); // CoreServer.isBind() - final boolean isBind = (Boolean) classOfProxyServer.getMethod("isBind").invoke(objectOfCoreServer); + final boolean isBind = (Boolean) classOfProxyServer.getMethod("isBind").invoke(objectOfProxyServer); // 如果未绑定,则需要绑定一个地址 @@ -280,9 +252,9 @@ private static synchronized InetSocketAddress main(final Map fea try { classOfProxyServer .getMethod("bind", classOfConfigure, Instrumentation.class) - .invoke(objectOfCoreServer, objectOfCoreConfigure, inst); + .invoke(objectOfProxyServer, objectOfCoreConfigure, inst); } catch (Throwable t) { - classOfProxyServer.getMethod("destroy").invoke(objectOfCoreServer); + classOfProxyServer.getMethod("destroy").invoke(objectOfProxyServer); throw t; } @@ -291,7 +263,7 @@ private static synchronized InetSocketAddress main(final Map fea // 返回服务器绑定的地址 return (InetSocketAddress) classOfProxyServer .getMethod("getLocal") - .invoke(objectOfCoreServer); + .invoke(objectOfProxyServer); } catch (Throwable cause) { diff --git a/sandbox-agent/target/classes/com/alibaba/jvm/sandbox/agent/AgentLauncher.class b/sandbox-agent/target/classes/com/alibaba/jvm/sandbox/agent/AgentLauncher.class deleted file mode 100644 index 241b74a2..00000000 Binary files a/sandbox-agent/target/classes/com/alibaba/jvm/sandbox/agent/AgentLauncher.class and /dev/null differ diff --git a/sandbox-agent/target/classes/com/alibaba/jvm/sandbox/agent/SandboxClassLoader.class b/sandbox-agent/target/classes/com/alibaba/jvm/sandbox/agent/SandboxClassLoader.class deleted file mode 100644 index 9aa22bb4..00000000 Binary files a/sandbox-agent/target/classes/com/alibaba/jvm/sandbox/agent/SandboxClassLoader.class and /dev/null differ diff --git a/sandbox-api/pom.xml b/sandbox-api/pom.xml index 038bf51d..b46b7570 100755 --- a/sandbox-api/pom.xml +++ b/sandbox-api/pom.xml @@ -6,7 +6,7 @@ com.alibaba.jvm.sandbox sandbox - 1.1.2-SNAPSHOT + 1.2.0-SNAPSHOT sandbox-api sandbox-api ${sandbox.version} @@ -25,6 +25,8 @@ javax.servlet javax.servlet-api + + diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/annotation/Command.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/annotation/Command.java new file mode 100644 index 00000000..b103c9a8 --- /dev/null +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/annotation/Command.java @@ -0,0 +1,34 @@ +package com.alibaba.jvm.sandbox.api.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 模块命令注解,拥有此注解的模块方法将能接收到从{@code sandbox.sh -d} 发出的命令 + *

+ * 有这个注解的方法只能接收四类型的参数: + *

+ * + * @author luanjia@taobao.com + * @since {@code sandbox-api:1.2.0} + */ +@Target(METHOD) +@Retention(RUNTIME) +public @interface Command { + + /** + * 命令名称 + * + * @return 命令名称 + */ + String value(); + +} diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/event/BeforeEvent.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/event/BeforeEvent.java index e79f68f4..4415d503 100755 --- a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/event/BeforeEvent.java +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/event/BeforeEvent.java @@ -43,7 +43,7 @@ public class BeforeEvent extends InvokeEvent { * @param processId 调用过程ID * @param invokeId 调用ID * @param javaClassLoader 触发调用事件的ClassLoader - * @param javaClassName 触发调用事件的类名称java.lang.String + * @param javaClassName 触发调用事件的类名称 * @param javaMethodName 触发调用事件的方法名称 * @param javaMethodDesc 触发调用事件的方法签名 * @param target 触发调用事件的对象(静态方法为null) @@ -51,9 +51,12 @@ public class BeforeEvent extends InvokeEvent { */ public BeforeEvent(final int processId, final int invokeId, - final ClassLoader javaClassLoader, String javaClassName, - final String javaMethodName, String javaMethodDesc, - final Object target, Object[] argumentArray) { + final ClassLoader javaClassLoader, + final String javaClassName, + final String javaMethodName, + final String javaMethodDesc, + final Object target, + final Object[] argumentArray) { super(processId, invokeId, Type.BEFORE); this.javaClassLoader = javaClassLoader; this.javaClassName = javaClassName; diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/Http.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/Http.java index 39badc2d..699c165b 100755 --- a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/Http.java +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/Http.java @@ -9,9 +9,11 @@ * HTTP服务请求 * * @author luanjia@taobao.com + * @deprecated 请使用 {@link com.alibaba.jvm.sandbox.api.annotation.Command} */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) +@Deprecated public @interface Http { /** diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/TextMessageListener.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/TextMessageListener.java index 3181020c..3ce92aa6 100755 --- a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/TextMessageListener.java +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/TextMessageListener.java @@ -5,6 +5,7 @@ * * @author luanjia@taobao.com */ +@Deprecated public interface TextMessageListener extends WebSocketConnectionListener { /** diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketAcceptor.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketAcceptor.java index 4b09cb3a..38f72f61 100755 --- a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketAcceptor.java +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketAcceptor.java @@ -7,6 +7,7 @@ * * @author luanjia@taobao.com */ +@Deprecated public interface WebSocketAcceptor { /** diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnection.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnection.java index e1017804..9839562a 100755 --- a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnection.java +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnection.java @@ -7,6 +7,7 @@ * * @author luanjia@taobao.com */ +@Deprecated public interface WebSocketConnection { /** diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnectionListener.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnectionListener.java index 22e19918..e8801e08 100755 --- a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnectionListener.java +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnectionListener.java @@ -5,6 +5,7 @@ * * @author luanjia@taobao.com */ +@Deprecated public interface WebSocketConnectionListener { /** diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/EventListenerFactory.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/EventListenerFactory.java index acd0a3e9..21fdebc6 100644 --- a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/EventListenerFactory.java +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/EventListenerFactory.java @@ -5,7 +5,9 @@ * * @author luanjia@taobao.com * @since {@code sandbox-api:1.0.10} + * @deprecated */ +@Deprecated public interface EventListenerFactory { /** diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/Sentry.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/Sentry.java index 99f5ceca..01a0aac6 100644 --- a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/Sentry.java +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/Sentry.java @@ -12,7 +12,9 @@ * @param 哨点类型,一般喜欢用枚举 * @author luanjia@taobao.com * @since {@code sandbox-api:1.0.10} + * @deprecated */ +@Deprecated public class Sentry implements Attachment { /** diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/ThreadSafeEventListener.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/ThreadSafeEventListener.java index 966e8448..66a78994 100644 --- a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/ThreadSafeEventListener.java +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/ThreadSafeEventListener.java @@ -10,7 +10,9 @@ * * @author luanjia@taobao.com * @since {@code sandbox-api:1.0.10} + * @deprecated */ +@Deprecated public class ThreadSafeEventListener implements EventListener { private final EventListenerFactory factory; diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener.java index 57378215..4a547f42 100644 --- a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener.java +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener.java @@ -33,6 +33,23 @@ protected OpStack initialValue() { @Override final public void onEvent(final Event event) throws Throwable { + final OpStack opStack = opStackRef.get(); + try { + switchEvent(opStack, event); + } finally { + // 如果执行到TOP的最后一个事件,则需要主动清理占用的资源 + if (opStack.isEmpty()) { + opStackRef.remove(); + } + } + + } + + + // 执行事件 + private void switchEvent(final OpStack opStack, + final Event event) throws Throwable { + switch (event.type) { case BEFORE: { final BeforeEvent bEvent = (BeforeEvent) event; @@ -50,7 +67,6 @@ final public void onEvent(final Event event) throws Throwable { bEvent.target ); - final OpStack opStack = opStackRef.get(); final Advice top; final Advice parent; @@ -78,11 +94,12 @@ final public void onEvent(final Event event) throws Throwable { case IMMEDIATELY_THROWS: case IMMEDIATELY_RETURN: { final InvokeEvent invokeEvent = (InvokeEvent) event; - opStackRef.get().popByExpectInvokeId(invokeEvent.invokeId); + opStack.popByExpectInvokeId(invokeEvent.invokeId); + // 修复#123 + break; } case RETURN: { - final OpStack opStack = opStackRef.get(); final ReturnEvent rEvent = (ReturnEvent) event; final WrapAdvice wrapAdvice = opStack.popByExpectInvokeId(rEvent.invokeId); if (null != wrapAdvice) { @@ -91,7 +108,6 @@ final public void onEvent(final Event event) throws Throwable { break; } case THROWS: { - final OpStack opStack = opStackRef.get(); final ThrowsEvent tEvent = (ThrowsEvent) event; final WrapAdvice wrapAdvice = opStack.popByExpectInvokeId(tEvent.invokeId); if (null != wrapAdvice) { @@ -101,7 +117,6 @@ final public void onEvent(final Event event) throws Throwable { } case CALL_BEFORE: { - final OpStack opStack = opStackRef.get(); final CallBeforeEvent cbEvent = (CallBeforeEvent) event; final WrapAdvice wrapAdvice = opStack.peekByExpectInvokeId(cbEvent.invokeId); if (null == wrapAdvice) { @@ -125,7 +140,6 @@ final public void onEvent(final Event event) throws Throwable { } case CALL_RETURN: { - final OpStack opStack = opStackRef.get(); final CallReturnEvent crEvent = (CallReturnEvent) event; final WrapAdvice wrapAdvice = opStack.peekByExpectInvokeId(crEvent.invokeId); if (null == wrapAdvice) { @@ -147,7 +161,6 @@ final public void onEvent(final Event event) throws Throwable { } case CALL_THROWS: { - final OpStack opStack = opStackRef.get(); final CallThrowsEvent ctEvent = (CallThrowsEvent) event; final WrapAdvice wrapAdvice = opStack.peekByExpectInvokeId(ctEvent.invokeId); if (null == wrapAdvice) { @@ -170,7 +183,6 @@ final public void onEvent(final Event event) throws Throwable { } case LINE: { - final OpStack opStack = opStackRef.get(); final LineEvent lEvent = (LineEvent) event; final WrapAdvice wrapAdvice = opStack.peekByExpectInvokeId(lEvent.invokeId); if (null == wrapAdvice) { @@ -208,6 +220,12 @@ void pushForBegin(final Advice advice) { adviceStack.push(new WrapAdvice(advice)); } + WrapAdvice pop() { + return !adviceStack.isEmpty() + ? adviceStack.pop() + : null; + } + /** * 在通知堆栈中,BEFORE:[RETURN/THROWS]的invokeId是配对的, * 如果发生错位则说明BEFORE的事件没有被成功压入堆栈,没有被正确的处理,外界没有正确感知BEFORE diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder.java index a06a3e80..3b363ed5 100644 --- a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder.java +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder.java @@ -672,6 +672,8 @@ public EventWatcher onWatch(AdviceListener adviceListener) { eventTypeSet.add(BEFORE); eventTypeSet.add(RETURN); eventTypeSet.add(THROWS); + eventTypeSet.add(IMMEDIATELY_RETURN); + eventTypeSet.add(IMMEDIATELY_THROWS); return build( new AdviceAdapterListener(adviceListener), toProgressGroup(progresses), diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/resource/EventMonitor.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/resource/EventMonitor.java index 48943dc6..21971d3a 100644 --- a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/resource/EventMonitor.java +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/resource/EventMonitor.java @@ -7,7 +7,9 @@ * * @author luanjia@taobao.com * @since {@code sandbox-api:1.0.9} + * @deprecated 后续不再支持事件池 */ +@Deprecated public interface EventMonitor { /** @@ -15,6 +17,7 @@ public interface EventMonitor { * * @author luanjia@taobao.com * @since {@code sandbox-api:1.0.9} + * @deprecated 后续不再支持事件池 */ interface EventPoolInfo { diff --git a/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/spi/ModuleJarUnLoadSpi.java b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/spi/ModuleJarUnLoadSpi.java new file mode 100644 index 00000000..e3922e56 --- /dev/null +++ b/sandbox-api/src/main/java/com/alibaba/jvm/sandbox/api/spi/ModuleJarUnLoadSpi.java @@ -0,0 +1,16 @@ +package com.alibaba.jvm.sandbox.api.spi; + +/** + * 模块文件卸载 + * + * @author oldmanpushcart@gmail.com + * @since {@code sandbox-api:1.2.0} + */ +public interface ModuleJarUnLoadSpi { + + /** + * 模块Jar文件卸载完所有模块后,正式卸载Jar文件之前调用! + */ + void onJarUnLoadCompleted(); + +} diff --git a/sandbox-api/src/test/java/com/alibaba/jvm/sandbox/qatest/api/EventWatchBuilderTestCase.java b/sandbox-api/src/test/java/com/alibaba/jvm/sandbox/qatest/api/EventWatchBuilderTestCase.java index ac88c617..5d7a2143 100644 --- a/sandbox-api/src/test/java/com/alibaba/jvm/sandbox/qatest/api/EventWatchBuilderTestCase.java +++ b/sandbox-api/src/test/java/com/alibaba/jvm/sandbox/qatest/api/EventWatchBuilderTestCase.java @@ -6,7 +6,6 @@ import com.alibaba.jvm.sandbox.api.listener.ext.AdviceListener; import com.alibaba.jvm.sandbox.api.listener.ext.EventWatchBuilder; import com.alibaba.jvm.sandbox.qatest.api.mock.MockForBuilderModuleEventWatcher; -import com.alibaba.jvm.sandbox.qatest.api.mock.MockForBuilderProgress; import com.alibaba.jvm.sandbox.qatest.api.util.ApiQaArrayUtils; import org.junit.Assert; import org.junit.Test; @@ -15,24 +14,39 @@ public class EventWatchBuilderTestCase { + @Test + public void test$$EventWatchBuilder$$normal$$normal() { + + final MockForBuilderModuleEventWatcher mockForBuilderModuleEventWatcher + = new MockForBuilderModuleEventWatcher(); + new EventWatchBuilder(mockForBuilderModuleEventWatcher) + .onClass(String.class) + .onBehavior("toString") + .onWatch(new AdviceListener()); + + Assert.assertEquals(5, mockForBuilderModuleEventWatcher.getEventTypeArray().length); + Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.RETURN, mockForBuilderModuleEventWatcher.getEventTypeArray())); + Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.THROWS, mockForBuilderModuleEventWatcher.getEventTypeArray())); + Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.BEFORE, mockForBuilderModuleEventWatcher.getEventTypeArray())); + Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.IMMEDIATELY_RETURN, mockForBuilderModuleEventWatcher.getEventTypeArray())); + Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.IMMEDIATELY_THROWS, mockForBuilderModuleEventWatcher.getEventTypeArray())); + Assert.assertEquals(1, mockForBuilderModuleEventWatcher.getEventWatchCondition().getOrFilterArray().length); + } @Test public void test$$EventWatchBuilder$$normal$$all() { final MockForBuilderModuleEventWatcher mockForBuilderModuleEventWatcher = new MockForBuilderModuleEventWatcher(); - final MockForBuilderProgress mockForBuilderProgress - = new MockForBuilderProgress(); new EventWatchBuilder(mockForBuilderModuleEventWatcher) .onClass(String.class) .onBehavior("toString") .onWatching() .withCall() .withLine() - .withProgress(mockForBuilderProgress) .onWatch(new AdviceListener()); - Assert.assertEquals(7, mockForBuilderModuleEventWatcher.getEventTypeArray().length); + Assert.assertEquals(9, mockForBuilderModuleEventWatcher.getEventTypeArray().length); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.RETURN, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.THROWS, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.BEFORE, mockForBuilderModuleEventWatcher.getEventTypeArray())); @@ -40,6 +54,8 @@ public class EventWatchBuilderTestCase { Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.CALL_THROWS, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.CALL_RETURN, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.LINE, mockForBuilderModuleEventWatcher.getEventTypeArray())); + Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.IMMEDIATELY_RETURN, mockForBuilderModuleEventWatcher.getEventTypeArray())); + Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.IMMEDIATELY_THROWS, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertEquals(1, mockForBuilderModuleEventWatcher.getEventWatchCondition().getOrFilterArray().length); } @@ -48,23 +64,22 @@ public class EventWatchBuilderTestCase { final MockForBuilderModuleEventWatcher mockForBuilderModuleEventWatcher = new MockForBuilderModuleEventWatcher(); - final MockForBuilderProgress mockForBuilderProgress - = new MockForBuilderProgress(); new EventWatchBuilder(mockForBuilderModuleEventWatcher) .onClass(String.class) .onBehavior("toString") .onWatching() .withCall() - .withProgress(mockForBuilderProgress) .onWatch(new AdviceListener()); - Assert.assertEquals(6, mockForBuilderModuleEventWatcher.getEventTypeArray().length); + Assert.assertEquals(8, mockForBuilderModuleEventWatcher.getEventTypeArray().length); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.RETURN, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.THROWS, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.BEFORE, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.CALL_BEFORE, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.CALL_THROWS, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.CALL_RETURN, mockForBuilderModuleEventWatcher.getEventTypeArray())); + Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.IMMEDIATELY_RETURN, mockForBuilderModuleEventWatcher.getEventTypeArray())); + Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.IMMEDIATELY_THROWS, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertFalse(ApiQaArrayUtils.has(Event.Type.LINE, mockForBuilderModuleEventWatcher.getEventTypeArray())); } @@ -74,17 +89,14 @@ public class EventWatchBuilderTestCase { final MockForBuilderModuleEventWatcher mockForBuilderModuleEventWatcher = new MockForBuilderModuleEventWatcher(); - final MockForBuilderProgress mockForBuilderProgress - = new MockForBuilderProgress(); new EventWatchBuilder(mockForBuilderModuleEventWatcher) .onClass(String.class) .onBehavior("toString") .onWatching() .withLine() - .withProgress(mockForBuilderProgress) .onWatch(new AdviceListener()); - Assert.assertEquals(4, mockForBuilderModuleEventWatcher.getEventTypeArray().length); + Assert.assertEquals(6, mockForBuilderModuleEventWatcher.getEventTypeArray().length); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.RETURN, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.THROWS, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.BEFORE, mockForBuilderModuleEventWatcher.getEventTypeArray())); @@ -92,6 +104,8 @@ public class EventWatchBuilderTestCase { Assert.assertFalse(ApiQaArrayUtils.has(Event.Type.CALL_THROWS, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertFalse(ApiQaArrayUtils.has(Event.Type.CALL_RETURN, mockForBuilderModuleEventWatcher.getEventTypeArray())); Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.LINE, mockForBuilderModuleEventWatcher.getEventTypeArray())); + Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.IMMEDIATELY_RETURN, mockForBuilderModuleEventWatcher.getEventTypeArray())); + Assert.assertTrue(ApiQaArrayUtils.has(Event.Type.IMMEDIATELY_THROWS, mockForBuilderModuleEventWatcher.getEventTypeArray())); } diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/LoadCompleted.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/LoadCompleted.class deleted file mode 100644 index e0c8a17b..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/LoadCompleted.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/ModuleLifecycle.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/ModuleLifecycle.class deleted file mode 100644 index bca61491..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/ModuleLifecycle.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/ProcessControlException$State.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/ProcessControlException$State.class deleted file mode 100644 index a6be8d69..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/ProcessControlException$State.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/ProcessControlException.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/ProcessControlException.class deleted file mode 100644 index a74823fa..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/ProcessControlException.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/ProcessController.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/ProcessController.class deleted file mode 100644 index e86fe456..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/ProcessController.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/annotation/IncludeBootstrap.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/annotation/IncludeBootstrap.class deleted file mode 100644 index 9c5e5fd7..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/annotation/IncludeBootstrap.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/annotation/IncludeSubClasses.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/annotation/IncludeSubClasses.class deleted file mode 100644 index d64b857d..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/annotation/IncludeSubClasses.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/annotation/Stealth.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/annotation/Stealth.class deleted file mode 100644 index f5a45dfb..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/annotation/Stealth.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/BeforeEvent.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/BeforeEvent.class deleted file mode 100644 index 3e86af8f..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/BeforeEvent.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/CallBeforeEvent.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/CallBeforeEvent.class deleted file mode 100644 index 79e59670..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/CallBeforeEvent.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/CallReturnEvent.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/CallReturnEvent.class deleted file mode 100644 index 0fda01f2..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/CallReturnEvent.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/CallThrowsEvent.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/CallThrowsEvent.class deleted file mode 100644 index 412cd19c..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/CallThrowsEvent.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/Event$Type.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/Event$Type.class deleted file mode 100644 index f9d632f2..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/Event$Type.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/Event.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/Event.class deleted file mode 100644 index b9297c59..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/Event.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/ImmediatelyReturnEvent.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/ImmediatelyReturnEvent.class deleted file mode 100644 index 142201af..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/ImmediatelyReturnEvent.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/ImmediatelyThrowsEvent.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/ImmediatelyThrowsEvent.class deleted file mode 100644 index dbfbe855..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/ImmediatelyThrowsEvent.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/InvokeEvent.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/InvokeEvent.class deleted file mode 100644 index 0ced2205..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/InvokeEvent.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/LineEvent.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/LineEvent.class deleted file mode 100644 index adcc939c..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/LineEvent.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/ReturnEvent.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/ReturnEvent.class deleted file mode 100644 index 03c9b1f6..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/ReturnEvent.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/ThrowsEvent.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/ThrowsEvent.class deleted file mode 100644 index 07854871..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/event/ThrowsEvent.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/AccessFlags.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/AccessFlags.class deleted file mode 100644 index cd4f6bde..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/AccessFlags.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/ExtFilter$ExtFilterFactory$1.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/ExtFilter$ExtFilterFactory$1.class deleted file mode 100644 index e90cb035..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/ExtFilter$ExtFilterFactory$1.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/ExtFilter$ExtFilterFactory.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/ExtFilter$ExtFilterFactory.class deleted file mode 100644 index 033897e8..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/ExtFilter$ExtFilterFactory.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/ExtFilter.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/ExtFilter.class deleted file mode 100644 index 1f8a7a46..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/ExtFilter.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/Filter.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/Filter.class deleted file mode 100644 index 16f3de36..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/Filter.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/NameRegexFilter.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/NameRegexFilter.class deleted file mode 100644 index 6e141be2..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/NameRegexFilter.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/OrGroupFilter.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/OrGroupFilter.class deleted file mode 100644 index ec2c4152..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/filter/OrGroupFilter.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/Http$Method.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/Http$Method.class deleted file mode 100644 index f683b5ca..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/Http$Method.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/Http.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/Http.class deleted file mode 100644 index cce836da..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/Http.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/printer/ConcurrentLinkedQueuePrinter.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/printer/ConcurrentLinkedQueuePrinter.class deleted file mode 100644 index 84e88d8c..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/printer/ConcurrentLinkedQueuePrinter.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/printer/Printer.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/printer/Printer.class deleted file mode 100644 index 64113ec1..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/printer/Printer.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/websocket/TextMessageListener.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/websocket/TextMessageListener.class deleted file mode 100644 index 64332b4e..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/websocket/TextMessageListener.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketAcceptor.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketAcceptor.class deleted file mode 100644 index 0898c4d0..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketAcceptor.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnection.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnection.class deleted file mode 100644 index 112e6292..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnection.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnectionListener.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnectionListener.class deleted file mode 100644 index 26b5d32c..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/http/websocket/WebSocketConnectionListener.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/EventListener.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/EventListener.class deleted file mode 100644 index 2c605dea..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/EventListener.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/EventListenerFactory.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/EventListenerFactory.class deleted file mode 100644 index 4eef0dad..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/EventListenerFactory.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/Sentry$1.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/Sentry$1.class deleted file mode 100644 index 4d35e84c..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/Sentry$1.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/Sentry$WrapData.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/Sentry$WrapData.class deleted file mode 100644 index 259d373e..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/Sentry$WrapData.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/Sentry.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/Sentry.class deleted file mode 100644 index 2d2abaad..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/Sentry.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ThreadSafeEventListener$1.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ThreadSafeEventListener$1.class deleted file mode 100644 index a997f999..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ThreadSafeEventListener$1.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ThreadSafeEventListener.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ThreadSafeEventListener.class deleted file mode 100644 index ec5c3c4f..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ThreadSafeEventListener.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Advice.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Advice.class deleted file mode 100644 index a06906dd..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Advice.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$1.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$1.class deleted file mode 100644 index a4487c47..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$1.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$2.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$2.class deleted file mode 100644 index 1060fb38..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$2.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$3.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$3.class deleted file mode 100644 index 34199cbe..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$3.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$BehaviorCacheKey.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$BehaviorCacheKey.class deleted file mode 100644 index 156c0d80..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$BehaviorCacheKey.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$CallTarget.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$CallTarget.class deleted file mode 100644 index 609cdf24..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$CallTarget.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$OpStack.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$OpStack.class deleted file mode 100644 index e44f71ed..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$OpStack.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$WrapAdvice.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$WrapAdvice.class deleted file mode 100644 index 58e03e60..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener$WrapAdvice.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener.class deleted file mode 100644 index f6ec9618..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceAdapterListener.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceListener.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceListener.class deleted file mode 100644 index 458de9ca..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/AdviceListener.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Attachment.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Attachment.class deleted file mode 100644 index 54d38acb..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Attachment.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Behavior$ConstructorImpl.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Behavior$ConstructorImpl.class deleted file mode 100644 index 1741d4b7..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Behavior$ConstructorImpl.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Behavior$MethodImpl.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Behavior$MethodImpl.class deleted file mode 100644 index 024fc7e6..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Behavior$MethodImpl.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Behavior.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Behavior.class deleted file mode 100644 index 98169437..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/Behavior.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$1.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$1.class deleted file mode 100644 index 2a34c21e..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$1.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$2.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$2.class deleted file mode 100644 index 6bd7c986..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$2.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$3.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$3.class deleted file mode 100644 index 39a293c3..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$3.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$4.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$4.class deleted file mode 100644 index 973aad96..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$4.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$BuildingForBehavior.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$BuildingForBehavior.class deleted file mode 100644 index d314b40c..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$BuildingForBehavior.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$BuildingForClass.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$BuildingForClass.class deleted file mode 100644 index d9b5c5d3..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$BuildingForClass.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$BuildingForWatching.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$BuildingForWatching.class deleted file mode 100644 index 5c80aaa1..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$BuildingForWatching.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$Group.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$Group.class deleted file mode 100644 index 785add92..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$Group.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$IBuildingForBehavior.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$IBuildingForBehavior.class deleted file mode 100644 index 1bdea718..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$IBuildingForBehavior.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$IBuildingForClass.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$IBuildingForClass.class deleted file mode 100644 index 15483608..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$IBuildingForClass.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$IBuildingForUnWatching.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$IBuildingForUnWatching.class deleted file mode 100644 index 6ad723e0..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$IBuildingForUnWatching.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$IBuildingForWatching.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$IBuildingForWatching.class deleted file mode 100644 index 90d5fb00..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$IBuildingForWatching.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$PatternGroupList.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$PatternGroupList.class deleted file mode 100644 index 9067052b..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$PatternGroupList.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$PatternType.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$PatternType.class deleted file mode 100644 index eb055ef1..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$PatternType.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$ProgressGroup.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$ProgressGroup.class deleted file mode 100644 index 5a1c133c..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder$ProgressGroup.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder.class deleted file mode 100644 index 1cac3b15..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchBuilder.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchCondition.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchCondition.class deleted file mode 100644 index 8049cd70..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatchCondition.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatcher.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatcher.class deleted file mode 100644 index d1dee247..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/listener/ext/EventWatcher.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/EventMonitor$EventPoolInfo.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/EventMonitor$EventPoolInfo.class deleted file mode 100644 index f569e7bb..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/EventMonitor$EventPoolInfo.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/EventMonitor.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/EventMonitor.class deleted file mode 100644 index 99445eb6..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/EventMonitor.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/LoadedClassDataSource.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/LoadedClassDataSource.class deleted file mode 100644 index bcfed26e..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/LoadedClassDataSource.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleController.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleController.class deleted file mode 100644 index a838fb3b..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleController.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleEventWatcher$Progress.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleEventWatcher$Progress.class deleted file mode 100644 index 40c9c1bb..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleEventWatcher$Progress.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleEventWatcher$WatchCallback.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleEventWatcher$WatchCallback.class deleted file mode 100644 index 1e56d4f7..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleEventWatcher$WatchCallback.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleEventWatcher.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleEventWatcher.class deleted file mode 100644 index 13891554..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleEventWatcher.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleManager.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleManager.class deleted file mode 100644 index 2c34f2d3..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ModuleManager.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/BehaviorDescriptor$Type.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/BehaviorDescriptor$Type.class deleted file mode 100644 index b92dbd78..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/BehaviorDescriptor$Type.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/BehaviorDescriptor.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/BehaviorDescriptor.class deleted file mode 100644 index 2b212529..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/BehaviorDescriptor.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/CacheGet$CacheLoadUnCaughtException.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/CacheGet$CacheLoadUnCaughtException.class deleted file mode 100644 index 1c01ff2a..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/CacheGet$CacheLoadUnCaughtException.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/CacheGet.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/CacheGet.class deleted file mode 100644 index 38e22710..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/CacheGet.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/GaArrayUtils.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/GaArrayUtils.class deleted file mode 100644 index 957c5bad..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/GaArrayUtils.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/GaCollectionUtils.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/GaCollectionUtils.class deleted file mode 100644 index 9140c10f..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/GaCollectionUtils.class and /dev/null differ diff --git a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/GaStringUtils.class b/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/GaStringUtils.class deleted file mode 100644 index 30c8a46d..00000000 Binary files a/sandbox-api/target/classes/com/alibaba/jvm/sandbox/api/util/GaStringUtils.class and /dev/null differ diff --git a/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/AdviceListenerTestCase$1.class b/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/AdviceListenerTestCase$1.class deleted file mode 100644 index 6dfad96f..00000000 Binary files a/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/AdviceListenerTestCase$1.class and /dev/null differ diff --git a/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/AdviceListenerTestCase.class b/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/AdviceListenerTestCase.class deleted file mode 100644 index 00f6b5d1..00000000 Binary files a/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/AdviceListenerTestCase.class and /dev/null differ diff --git a/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/EventWatchBuilderTestCase.class b/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/EventWatchBuilderTestCase.class deleted file mode 100644 index 7f0e59fe..00000000 Binary files a/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/EventWatchBuilderTestCase.class and /dev/null differ diff --git a/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/mock/MockForBuilderModuleEventWatcher.class b/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/mock/MockForBuilderModuleEventWatcher.class deleted file mode 100644 index df83b55f..00000000 Binary files a/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/mock/MockForBuilderModuleEventWatcher.class and /dev/null differ diff --git a/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/mock/MockForBuilderProgress.class b/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/mock/MockForBuilderProgress.class deleted file mode 100644 index e1736ce7..00000000 Binary files a/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/mock/MockForBuilderProgress.class and /dev/null differ diff --git a/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/util/ApiQaArrayUtils.class b/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/util/ApiQaArrayUtils.class deleted file mode 100644 index fb7f5cc0..00000000 Binary files a/sandbox-api/target/test-classes/com/alibaba/jvm/sandbox/qatest/api/util/ApiQaArrayUtils.class and /dev/null differ diff --git a/sandbox-api/target/test-classes/logback.xml b/sandbox-api/target/test-classes/logback.xml deleted file mode 100755 index c7f37818..00000000 --- a/sandbox-api/target/test-classes/logback.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - %d{yyyy-MM-dd HH:mm:ss} %5level %msg%n   - - - - - - - - \ No newline at end of file diff --git a/sandbox-common-api/pom.xml b/sandbox-common-api/pom.xml index d823e237..d70f595d 100644 --- a/sandbox-common-api/pom.xml +++ b/sandbox-common-api/pom.xml @@ -6,7 +6,7 @@ sandbox com.alibaba.jvm.sandbox - 1.1.2-SNAPSHOT + 1.2.0-SNAPSHOT sandbox-common-api sandbox-common-api ${sandbox.version} diff --git a/sandbox-common-api/src/main/java/com/alibaba/jvm/sandbox/api/resource/ConfigInfo.java b/sandbox-common-api/src/main/java/com/alibaba/jvm/sandbox/api/resource/ConfigInfo.java index 8df7453b..d58cbc6f 100755 --- a/sandbox-common-api/src/main/java/com/alibaba/jvm/sandbox/api/resource/ConfigInfo.java +++ b/sandbox-common-api/src/main/java/com/alibaba/jvm/sandbox/api/resource/ConfigInfo.java @@ -93,7 +93,9 @@ public interface ConfigInfo { *

${SANDBOX_HOME}/cfg/sandbox.properties#event.pool.enable中进行开启关闭

* * @return true:启用;false:不启用 + * @deprecated 后续不再支持事件池 */ + @Deprecated boolean isEnableEventPool(); /** @@ -101,7 +103,9 @@ public interface ConfigInfo { * * @return 单个事件类型缓存最小数量 * @deprecated 已经被废弃,推荐使用{@link #getEventPoolMaxIdlePerEvent()} + * @deprecated 后续不再支持事件池 */ + @Deprecated int getEventPoolKeyMin(); /** @@ -109,7 +113,9 @@ public interface ConfigInfo { * * @return 单个事件类型缓存最大数量 * @deprecated 已被废弃,推荐使用{@link #getEventPoolMaxTotalPerEvent()} + * @deprecated 后续不再支持事件池 */ + @Deprecated int getEventPoolKeyMax(); /** @@ -117,7 +123,9 @@ public interface ConfigInfo { * * @return 所有事件类型缓存最大总数量 * @deprecated 已被废弃,推荐使用{@link #getEventPoolMaxTotal()} + * @deprecated 后续不再支持事件池 */ + @Deprecated int getEventPoolTotal(); /** @@ -125,7 +133,9 @@ public interface ConfigInfo { * * @return 事件池最大容量 * @since {@code sandbox-common-api:1.0.1} + * @deprecated 后续不再支持事件池 */ + @Deprecated int getEventPoolMaxTotal(); /** @@ -133,7 +143,9 @@ public interface ConfigInfo { * * @return 事件池每个事件最小空闲容量 * @since {@code sandbox-common-api:1.0.1} + * @deprecated 后续不再支持事件池 */ + @Deprecated int getEventPoolMinIdlePerEvent(); /** @@ -141,7 +153,9 @@ public interface ConfigInfo { * * @return 事件池每个事件最大空闲容量 * @since {@code sandbox-common-api:1.0.1} + * @deprecated 后续不再支持事件池 */ + @Deprecated int getEventPoolMaxIdlePerEvent(); /** @@ -149,7 +163,9 @@ public interface ConfigInfo { * * @return 事件池每个事件最大容量 * @since {@code sandbox-common-api:1.0.1} + * @deprecated 后续不再支持事件池 */ + @Deprecated int getEventPoolMaxTotalPerEvent(); diff --git a/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/Information$Mode.class b/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/Information$Mode.class deleted file mode 100644 index 7e211bf8..00000000 Binary files a/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/Information$Mode.class and /dev/null differ diff --git a/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/Information.class b/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/Information.class deleted file mode 100644 index 8b255194..00000000 Binary files a/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/Information.class and /dev/null differ diff --git a/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/Module.class b/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/Module.class deleted file mode 100644 index 1630ef51..00000000 Binary files a/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/Module.class and /dev/null differ diff --git a/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/ModuleException$ErrorCode.class b/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/ModuleException$ErrorCode.class deleted file mode 100644 index 5a6759c3..00000000 Binary files a/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/ModuleException$ErrorCode.class and /dev/null differ diff --git a/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/ModuleException.class b/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/ModuleException.class deleted file mode 100644 index 5bc9e065..00000000 Binary files a/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/ModuleException.class and /dev/null differ diff --git a/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ConfigInfo.class b/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ConfigInfo.class deleted file mode 100644 index 7b9235a7..00000000 Binary files a/sandbox-common-api/target/classes/com/alibaba/jvm/sandbox/api/resource/ConfigInfo.class and /dev/null differ diff --git a/sandbox-core/pom.xml b/sandbox-core/pom.xml index 23b3c037..a7a10421 100755 --- a/sandbox-core/pom.xml +++ b/sandbox-core/pom.xml @@ -6,7 +6,7 @@ com.alibaba.jvm.sandbox sandbox - 1.1.2-SNAPSHOT + 1.2.0-SNAPSHOT sandbox-core sandbox-core ${sandbox.version} @@ -58,7 +58,7 @@ maven-surefire-plugin once - -Xbootclasspath/p:./src/test/resources/lib/sandbox-spy-1.1.0-for-qatest.jar + -Xbootclasspath/p:./src/test/resources/lib/sandbox-spy-1.2.0-for-qatest.jar diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/CoreConfigure.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/CoreConfigure.java index a16011a2..a6f654ac 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/CoreConfigure.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/CoreConfigure.java @@ -1,7 +1,6 @@ package com.alibaba.jvm.sandbox.core; import com.alibaba.jvm.sandbox.api.Information; -import com.alibaba.jvm.sandbox.api.event.Event; import com.alibaba.jvm.sandbox.core.util.FeatureCodec; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -34,16 +33,6 @@ public class CoreConfigure { private static final String KEY_CFG_LIB_PATH = "cfg"; private static final String VAL_LAUNCH_MODE_AGENT = "agent"; private static final String VAL_LAUNCH_MODE_ATTACH = "attach"; - private static final String KEY_EVENT_POOL_ENABLE = "event.pool.enable"; - - // ------------------------------------- 事件池配置 ------------------------------------- - private static final String KEY_EVENT_POOL_MAX_TOTAL = "event.pool.max.total"; - private static final String KEY_EVENT_POOL_MIN_IDLE_PER_EVENT = "event.pool.min.idle.per.event"; - private static final int DEFAULT_VAL_EVENT_POOL_MIN_IDLE_PER_EVENT = 50; - private static final String KEY_EVENT_POOL_MAX_IDLE_PER_EVENT = "event.pool.max.idle.per.event"; - private static final int DEFAULT_VAL_EVENT_POOL_MAX_IDLE_PER_EVENT = 100; - private static final String KEY_EVENT_POOL_MAX_TOTAL_PER_EVENT = "event.pool.max.total.per.event"; - private static final int DEFAULT_VAL_EVENT_POOL_MAX_TOTAL_PER_EVENT = 2000; private static final String KEY_UNSAFE_ENABLE = "unsafe.enable"; @@ -176,16 +165,6 @@ public synchronized File[] getUserModuleLibFiles() { } } -// final DirectoryScanner scanner = new DirectoryScanner(); -// scanner.setIncludes(getUserModuleLibPaths()); -// scanner.setCaseSensitive(false); -// scanner.scan(); -// final String[] filePaths = scanner.getIncludedDirectories(); -// final File[] files = new File[filePaths.length]; -// for (int index = 0; index < filePaths.length; index++) { -// files[index] = new File(filePaths[index]); -// } - return GET_USER_MODULE_LIB_FILES_CACHE = foundModuleJarFiles.toArray(new File[]{}); } @@ -254,45 +233,6 @@ public Information.Mode getLaunchMode() { return Information.Mode.ATTACH; } - - public int getEventPoolMaxTotal() { - return NumberUtils.toInt( - featureMap.get(KEY_EVENT_POOL_MAX_TOTAL), - getEventPoolMaxTotalPerEvent() * Event.Type.values().length - ); - } - - public int getEventPoolMinIdlePerEvent() { - return NumberUtils.toInt( - featureMap.get(KEY_EVENT_POOL_MIN_IDLE_PER_EVENT), - DEFAULT_VAL_EVENT_POOL_MIN_IDLE_PER_EVENT - ); - } - - public int getEventPoolMaxIdlePerEvent() { - return NumberUtils.toInt( - featureMap.get(KEY_EVENT_POOL_MAX_IDLE_PER_EVENT), - DEFAULT_VAL_EVENT_POOL_MAX_IDLE_PER_EVENT - ); - } - - public int getEventPoolMaxTotalPerEvent() { - return NumberUtils.toInt( - featureMap.get(KEY_EVENT_POOL_MAX_TOTAL_PER_EVENT), - DEFAULT_VAL_EVENT_POOL_MAX_TOTAL_PER_EVENT - ); - } - - - /** - * 是否启用事件池 - * - * @return event.pool.enable - */ - public boolean isEventPoolEnable() { - return BooleanUtils.toBoolean(featureMap.get(KEY_EVENT_POOL_ENABLE)); - } - /** * 是否启用Unsafe功能 * diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/CoreLauncher.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/CoreLauncher.java index 8847a7bf..40cff20a 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/CoreLauncher.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/CoreLauncher.java @@ -16,11 +16,6 @@ public CoreLauncher(final String targetJvmPid, final String agentJarPath, final String token) throws Exception { - System.out.println(String.format("attaching to JVM(%s), agent-jar=%s;", - targetJvmPid, - agentJarPath - )); - // 加载agent attachAgent(targetJvmPid, agentJarPath, token); diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/CoreModule.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/CoreModule.java new file mode 100755 index 00000000..eef72aa6 --- /dev/null +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/CoreModule.java @@ -0,0 +1,296 @@ +package com.alibaba.jvm.sandbox.core; + +import com.alibaba.jvm.sandbox.api.Module; +import com.alibaba.jvm.sandbox.core.classloader.ModuleJarClassLoader; +import com.alibaba.jvm.sandbox.core.manager.impl.SandboxClassFileTransformer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.lang.ref.WeakReference; +import java.util.*; + +/** + * 沙箱模块内核封装对象 + * + * @author luanjia@taobao.com + */ +public class CoreModule { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + // 全局唯一编号 + private final String uniqueId; + + // 模块归属Jar文件 + private final File jarFile; + + // 模块加载的ClassLoader + private final ModuleJarClassLoader loader; + + // 模块 + private final Module module; + + // 模块的类转换器 + private final Set sandboxClassFileTransformers + = new LinkedHashSet(); + + // 模块所持有的可释放资源 + private final List> releaseResources + = new ArrayList>(); + + // 是否已经激活 + private boolean isActivated; + + // 是否已被加载 + private boolean isLoaded; + + /** + * 模块业务对象 + * + * @param uniqueId 模块ID + * @param jarFile 模块归属Jar文件 + * @param loader 模块加载ClassLoader + * @param module 模块 + */ + public CoreModule(final String uniqueId, + final File jarFile, + final ModuleJarClassLoader loader, + final Module module) { + this.uniqueId = uniqueId; + this.jarFile = jarFile; + this.loader = loader; + this.module = module; + } + + /** + * 判断模块是否已被激活 + * + * @return TRUE:已激活;FALSE:未激活 + */ + public boolean isActivated() { + return isActivated; + } + + /** + * 标记模块激活状态 + * + * @param isActivated 模块激活状态 + * @return this + */ + public CoreModule markActivated(boolean isActivated) { + this.isActivated = isActivated; + return this; + } + + /** + * 判断模块是否已经被加载 + * + * @return TRUE:被加载;FALSE:未被加载 + */ + public boolean isLoaded() { + return isLoaded; + } + + + /** + * 标记模块加载状态 + * + * @param isLoaded 模块加载状态 + * @return this + */ + public CoreModule markLoaded(boolean isLoaded) { + this.isLoaded = isLoaded; + return this; + } + + /** + * 获取ModuleJar文件 + * + * @return ModuleJar文件 + */ + public File getJarFile() { + return jarFile; + } + + /** + * 获取对应的ModuleJarClassLoader + * + * @return ModuleJarClassLoader + */ + public ModuleJarClassLoader getLoader() { + return loader; + } + + /** + * 获取模块ID + * + * @return 模块ID + */ + public String getUniqueId() { + return uniqueId; + } + + /** + * 获取模块实例 + * + * @return 模块实例 + */ + public Module getModule() { + return module; + } + + /** + * 获取模块所创建的SandboxClassFileTransformer集合 + * + * @return 模块所创建的SandboxClassFileTransformer集合 + */ + public Set getSandboxClassFileTransformers() { + return sandboxClassFileTransformers; + } + + /** + * 获取模块所编织的类个数 + * + * @return 模块所编织的类个数 + */ + public int cCnt() { + int cCnt = 0; + for (final SandboxClassFileTransformer sandboxClassFileTransformer : sandboxClassFileTransformers) { + cCnt += sandboxClassFileTransformer.getAffectStatistic().cCnt(); + } + return cCnt; + } + + /** + * 获取模块所编织的方法个数 + * + * @return 模块所编织的方法个数 + */ + public int mCnt() { + int mCnt = 0; + for (final SandboxClassFileTransformer sandboxClassFileTransformer : sandboxClassFileTransformers) { + mCnt += sandboxClassFileTransformer.getAffectStatistic().mCnt(); + } + return mCnt; + } + + @Override + public String toString() { + return String.format( + "module[id=%s;class=%s;]", + uniqueId, + module.getClass() + ); + } + + + /** + * 在模块下追加一个可释放资源 + * + * @param resource 可释放资源封装 + * @param 资源实体 + * @return 资源实体本身 + */ + public T append(ReleaseResource resource) { + if (null == resource + || null == resource.get()) { + return null; + } + releaseResources.add(resource); + logger.debug("append resource={} in module[id={};]", resource.get(), uniqueId); + return resource.get(); + } + + /** + * 在当前模块下释放一个可释放资源 + * + * @param target 待释放的资源实体 + */ + public void release(Object target) { + final Iterator> resourceRefIt = releaseResources.iterator(); + while (resourceRefIt.hasNext()) { + final ReleaseResource resourceRef = resourceRefIt.next(); + + // 删除掉无效的资源 + if (null == resourceRef) { + resourceRefIt.remove(); + logger.info("remove null resource in module={}", uniqueId); + continue; + } + + // 删除掉已经被GC掉的资源 + final Object resource = resourceRef.get(); + if (null == resource) { + resourceRefIt.remove(); + logger.info("remove empty resource in module={}", uniqueId); + continue; + } + + if (target.equals(resource)) { + resourceRefIt.remove(); + logger.debug("release resource={} in module={}", resourceRef.get(), uniqueId); + try { + resourceRef.release(); + } catch (Exception cause) { + logger.warn("release resource occur error in module={};", uniqueId, cause); + } + } + } + } + + /** + * 在当前模块下移除所有可释放资源 + */ + public void releaseAll() { + final Iterator> resourceRefIt = releaseResources.iterator(); + while (resourceRefIt.hasNext()) { + final ReleaseResource resourceRef = resourceRefIt.next(); + resourceRefIt.remove(); + if (null != resourceRef) { + logger.debug("release resource={} in module={}", resourceRef.get(), uniqueId); + try { + resourceRef.release(); + } catch (Exception cause) { + logger.warn("release resource occur error in module={};", uniqueId, cause); + } + } + } + } + + /** + * 可释放资源 + * + * @param 资源类型 + */ + public static abstract class ReleaseResource { + + // 资源弱引用,允许被GC回收 + private final WeakReference reference; + + /** + * 构造释放资源 + * + * @param resource 资源目标 + */ + public ReleaseResource(T resource) { + this.reference = new WeakReference(resource); + } + + /** + * 释放资源 + */ + public abstract void release(); + + /** + * 获取资源实体 + * + * @return 资源实体 + */ + public T get() { + return reference.get(); + } + + } + +} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/JvmSandbox.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/JvmSandbox.java new file mode 100644 index 00000000..8cc52c9a --- /dev/null +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/JvmSandbox.java @@ -0,0 +1,61 @@ +package com.alibaba.jvm.sandbox.core; + +import com.alibaba.jvm.sandbox.core.enhance.weaver.EventListenerHandlers; +import com.alibaba.jvm.sandbox.core.manager.CoreModuleManager; +import com.alibaba.jvm.sandbox.core.manager.impl.DefaultCoreModuleManager; +import com.alibaba.jvm.sandbox.core.manager.impl.DefaultLoadedClassDataSource; +import com.alibaba.jvm.sandbox.core.manager.impl.DefaultProviderManager; +import com.alibaba.jvm.sandbox.core.util.SpyUtils; + +import java.lang.instrument.Instrumentation; + +/** + * 沙箱 + */ +public class JvmSandbox { + + private final CoreConfigure cfg; + private final CoreModuleManager coreModuleManager; + + public JvmSandbox(final CoreConfigure cfg, + final Instrumentation inst) { + EventListenerHandlers.getSingleton(); + this.cfg = cfg; + this.coreModuleManager = new DefaultCoreModuleManager( + cfg, + inst, + new DefaultLoadedClassDataSource(inst, cfg.isEnableUnsafe()), + new DefaultProviderManager(cfg) + ); + + init(); + } + + private void init() { + SpyUtils.init(cfg.getNamespace()); + } + + + /** + * 获取模块管理器 + * + * @return 模块管理器 + */ + public CoreModuleManager getCoreModuleManager() { + return coreModuleManager; + } + + /** + * 销毁沙箱 + */ + public void destroy() { + + // 卸载所有的模块 + coreModuleManager.unloadAll(); + + // 清理Spy + SpyUtils.clean(cfg.getNamespace()); + + } + +} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/classloader/ModuleClassLoader.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/classloader/ModuleJarClassLoader.java similarity index 72% rename from sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/classloader/ModuleClassLoader.java rename to sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/classloader/ModuleJarClassLoader.java index 77cac513..3204a82c 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/classloader/ModuleClassLoader.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/classloader/ModuleJarClassLoader.java @@ -1,6 +1,7 @@ package com.alibaba.jvm.sandbox.core.classloader; import com.alibaba.jvm.sandbox.api.annotation.Stealth; +import com.alibaba.jvm.sandbox.api.spi.ModuleJarUnLoadSpi; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; @@ -17,9 +18,11 @@ import java.security.ProtectionDomain; import java.util.Collection; import java.util.LinkedHashSet; +import java.util.ServiceLoader; import java.util.Set; import java.util.jar.JarFile; +import static com.alibaba.jvm.sandbox.api.util.GaStringUtils.getJavaClassName; import static com.alibaba.jvm.sandbox.core.util.SandboxReflectUtils.*; /** @@ -28,7 +31,7 @@ * @author luanjia@taobao.com */ @Stealth -public class ModuleClassLoader extends RoutingURLClassLoader { +public class ModuleJarClassLoader extends RoutingURLClassLoader { private final Logger logger = LoggerFactory.getLogger(getClass()); private final File moduleJarFile; @@ -42,18 +45,16 @@ private static File copyToTempFile(final File moduleJarFile) throws IOException return tempFile; } - public ModuleClassLoader(final File moduleJarFile, - final ClassLoader sandboxClassLoader) throws IOException { - this(moduleJarFile, copyToTempFile(moduleJarFile), sandboxClassLoader); + public ModuleJarClassLoader(final File moduleJarFile) throws IOException { + this(moduleJarFile, copyToTempFile(moduleJarFile)); } - private ModuleClassLoader(final File moduleJarFile, - final File tempModuleJarFile, - final ClassLoader sandboxClassLoader) throws IOException { + private ModuleJarClassLoader(final File moduleJarFile, + final File tempModuleJarFile) throws IOException { super( new URL[]{new URL("file:" + tempModuleJarFile.getPath())}, new Routing( - sandboxClassLoader, + ModuleJarClassLoader.class.getClassLoader(), "^com\\.alibaba\\.jvm\\.sandbox\\.api\\..*", "^javax\\.servlet\\..*", "^javax\\.annotation\\.Resource.*$" @@ -64,7 +65,7 @@ private ModuleClassLoader(final File moduleJarFile, this.tempModuleJarFile = tempModuleJarFile; try { - cleanProtectionDomainWhichCameFromModuleClassLoader(); + cleanProtectionDomainWhichCameFromModuleJarClassLoader(); logger.debug("clean ProtectionDomain in {}'s acc success.", this); } catch (Throwable e) { logger.warn("clean ProtectionDomain in {}'s acc failed.", this, e); @@ -73,12 +74,12 @@ private ModuleClassLoader(final File moduleJarFile, } /** - * 清理来自URLClassLoader.acc.ProtectionDomain[]中,来自上一个ModuleClassLoader的ProtectionDomain + * 清理来自URLClassLoader.acc.ProtectionDomain[]中,来自上一个ModuleJarClassLoader的ProtectionDomain * 这样写好蛋疼,而且还有不兼容的风险,从JDK6+都必须要这样清理,但我找不出更好的办法。 - * 在重置沙箱时,遇到MgrModule模块无法正确卸载类的情况,主要的原因是在于URLClassLoader.acc.ProtectionDomain[]中包含了上一个ModuleClassLoader的引用 + * 在重置沙箱时,遇到MgrModule模块无法正确卸载类的情况,主要的原因是在于URLClassLoader.acc.ProtectionDomain[]中包含了上一个ModuleJarClassLoader的引用 * 所以必须要在这里清理掉,否则随着重置次数的增加,类会越累积越多 */ - private void cleanProtectionDomainWhichCameFromModuleClassLoader() { + private void cleanProtectionDomainWhichCameFromModuleJarClassLoader() { // got ProtectionDomain[] from URLClassLoader's acc final AccessControlContext acc = unCaughtGetClassDeclaredJavaFieldValue(URLClassLoader.class, "acc", this); @@ -87,12 +88,12 @@ private void cleanProtectionDomainWhichCameFromModuleClassLoader() { acc ); - // remove ProtectionDomain which loader is ModuleClassLoader + // remove ProtectionDomain which loader is ModuleJarClassLoader final Set cleanProtectionDomainSet = new LinkedHashSet(); if (ArrayUtils.isNotEmpty(protectionDomainArray)) { for (final ProtectionDomain protectionDomain : protectionDomainArray) { if (protectionDomain.getClassLoader() == null - || !StringUtils.equals(ModuleClassLoader.class.getName(), protectionDomain.getClassLoader().getClass().getName())) { + || !StringUtils.equals(ModuleJarClassLoader.class.getName(), protectionDomain.getClassLoader().getClass().getName())) { cleanProtectionDomainSet.add(protectionDomain); } } @@ -104,9 +105,24 @@ private void cleanProtectionDomainWhichCameFromModuleClassLoader() { } + private void onJarUnLoadCompleted() { + try { + final ServiceLoader moduleJarUnLoadSpiServiceLoader + = ServiceLoader.load(ModuleJarUnLoadSpi.class, this); + for (final ModuleJarUnLoadSpi moduleJarUnLoadSpi : moduleJarUnLoadSpiServiceLoader) { + logger.info("unloading module-jar: onJarUnLoadCompleted() loader={};moduleJarUnLoadSpi={};", + this, + getJavaClassName(moduleJarUnLoadSpi.getClass()) + ); + moduleJarUnLoadSpi.onJarUnLoadCompleted(); + } + } catch (Throwable cause) { + logger.warn("unloading module-jar: onJarUnLoadCompleted() occur error! loader={};", this, cause); + } + } public void closeIfPossible() { - + onJarUnLoadCompleted(); try { // 如果是JDK7+的版本, URLClassLoader实现了Closeable接口,直接调用即可 @@ -116,7 +132,7 @@ public void closeIfPossible() { final Method closeMethod = unCaughtGetClassDeclaredJavaMethod(URLClassLoader.class, "close"); closeMethod.invoke(this); } catch (Throwable cause) { - logger.warn("close ModuleClassLoader[file={}] failed. JDK7+", moduleJarFile, cause); + logger.warn("close ModuleJarClassLoader[file={}] failed. JDK7+", moduleJarFile, cause); } return; } @@ -144,7 +160,7 @@ public void closeIfPossible() { } } catch (Throwable cause) { - logger.warn("close ModuleClassLoader[file={}] failed. probably not a HOTSPOT VM", moduleJarFile, cause); + logger.warn("close ModuleJarClassLoader[file={}] failed. probably not a HOTSPOT VM", moduleJarFile, cause); } } finally { @@ -162,7 +178,7 @@ public File getModuleJarFile() { @Override public String toString() { - return String.format("ModuleClassLoader[crc32=%s;file=%s;]", checksumCRC32, moduleJarFile); + return String.format("ModuleJarClassLoader[crc32=%s;file=%s;]", checksumCRC32, moduleJarFile); } public long getChecksumCRC32() { diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/domain/CoreModule.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/domain/CoreModule.java deleted file mode 100755 index 3d198460..00000000 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/domain/CoreModule.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.alibaba.jvm.sandbox.core.domain; - -import com.alibaba.jvm.sandbox.api.Module; -import com.alibaba.jvm.sandbox.core.classloader.ModuleClassLoader; -import com.alibaba.jvm.sandbox.core.manager.impl.SandboxClassFileTransformer; - -import java.io.File; -import java.util.LinkedHashSet; -import java.util.Set; - -/** - * 沙箱模块内核封装对象 - * Created by luanjia on 16/10/4. - */ -public class CoreModule { - - // 全局唯一编号 - private final String uniqueId; - - // 模块归属Jar文件 - private final File jarFile; - - // 模块加载的ClassLoader - private final ModuleClassLoader loader; - - // 模块 - private final Module module; - - // 模块的类转换器 - private final Set sandboxClassFileTransformers - = new LinkedHashSet(); - - // 是否已经激活 - private boolean activated; - - // 是否已被加载 - private boolean loaded; - - /** - * 模块业务对象 - * - * @param uniqueId 模块ID - * @param jarFile 模块归属Jar文件 - * @param loader 模块加载ClassLoader - * @param module 模块 - */ - public CoreModule(final String uniqueId, - final File jarFile, - final ModuleClassLoader loader, - final Module module) { - this.uniqueId = uniqueId; - this.jarFile = jarFile; - this.loader = loader; - this.module = module; - } - - public boolean isActivated() { - return activated; - } - - public CoreModule setActivated(boolean activated) { - this.activated = activated; - return this; - } - - public boolean isLoaded() { - return loaded; - } - - public CoreModule setLoaded(boolean loaded) { - this.loaded = loaded; - return this; - } - - public File getJarFile() { - return jarFile; - } - - public ModuleClassLoader getLoader() { - return loader; - } - - public Module getModule() { - return module; - } - - public Set getSandboxClassFileTransformers() { - return sandboxClassFileTransformers; - } - - public String getUniqueId() { - return uniqueId; - } - - public int cCnt() { - int cCnt = 0; - for (final SandboxClassFileTransformer sandboxClassFileTransformer : sandboxClassFileTransformers) { - cCnt += sandboxClassFileTransformer.getAffectStatistic().cCnt(); - } - return cCnt; - } - - public int mCnt() { - int mCnt = 0; - for (final SandboxClassFileTransformer sandboxClassFileTransformer : sandboxClassFileTransformers) { - mCnt += sandboxClassFileTransformer.getAffectStatistic().mCnt(); - } - return mCnt; - } - - @Override - public String toString() { - return String.format( - "module[id:%s;class:%s;]", - uniqueId, - module.getClass() - ); - } -} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/EventEnhancer.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/EventEnhancer.java index 84343980..b35b1a40 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/EventEnhancer.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/EventEnhancer.java @@ -2,17 +2,18 @@ import com.alibaba.jvm.sandbox.api.event.Event; import com.alibaba.jvm.sandbox.core.enhance.weaver.asm.EventWeaver; +import com.alibaba.jvm.sandbox.core.util.AsmUtils; import com.alibaba.jvm.sandbox.core.util.ObjectIDs; -import com.alibaba.jvm.sandbox.core.util.SpyUtils; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.IOException; import java.util.Set; -import static com.alibaba.jvm.sandbox.core.util.SandboxStringUtils.toInternalClassName; -import static com.alibaba.jvm.sandbox.core.util.SandboxStringUtils.toJavaClassName; +import static org.apache.commons.io.FileUtils.writeByteArrayToFile; import static org.objectweb.asm.ClassReader.EXPAND_FRAMES; import static org.objectweb.asm.ClassWriter.COMPUTE_FRAMES; import static org.objectweb.asm.ClassWriter.COMPUTE_MAXS; @@ -20,7 +21,8 @@ /** * 事件代码增强器 - * Created by luanjia@taobao.com on 16/7/12. + * + * @author luanjia@taobao.com */ public class EventEnhancer implements Enhancer { @@ -47,45 +49,52 @@ private ClassWriter createClassWriter(final ClassLoader targetClassLoader, */ @Override protected String getCommonSuperClass(String type1, String type2) { - Class c, d; - try { - c = Class.forName(toJavaClassName(type1), false, targetClassLoader); - d = Class.forName(toJavaClassName(type2), false, targetClassLoader); - } catch (Exception e) { - throw new RuntimeException(e); - } - if (c.isAssignableFrom(d)) { - return type1; - } - if (d.isAssignableFrom(c)) { - return type2; - } - if (c.isInterface() || d.isInterface()) { - return "java/lang/Object"; - } else { - do { - c = c.getSuperclass(); - } while (!c.isAssignableFrom(d)); - return toInternalClassName(c.getName()); - } + return AsmUtils.getCommonSuperClass(type1, type2, targetClassLoader); } }; } - /** - * 编织事件方法 - * - * @param sourceByteCodeArray 原始字节码数组 - * @return 编织后的字节码数组 + private static final boolean isDumpClass = false; + + /* + * dump class to file + * 用于代码调试 */ - private byte[] weavingEvent(final ClassLoader targetClassLoader, - final byte[] sourceByteCodeArray, - final Set signCodes, - final String namespace, - final int listenerId, - final Event.Type[] eventTypeArray) { - final ClassReader cr = new ClassReader(sourceByteCodeArray); + private static byte[] dumpClassIfNecessary(String className, byte[] data) { + if (!isDumpClass) { + return data; + } + final File dumpClassFile = new File("./sandbox-class-dump/" + className + ".class"); + final File classPath = new File(dumpClassFile.getParent()); + + // 创建类所在的包路径 + if (!classPath.mkdirs() + && !classPath.exists()) { + logger.warn("create dump classpath={} failed.", classPath); + return data; + } + + // 将类字节码写入文件 + try { + writeByteArrayToFile(dumpClassFile, data); + logger.info("dump {} to {} success.", className, dumpClassFile); + } catch (IOException e) { + logger.warn("dump {} to {} failed.", className, dumpClassFile, e); + } + + return data; + } + + @Override + public byte[] toByteCodeArray(final ClassLoader targetClassLoader, + final byte[] byteCodeArray, + final Set signCodes, + final String namespace, + final int listenerId, + final Event.Type[] eventTypeArray) { + // 返回增强后字节码 + final ClassReader cr = new ClassReader(byteCodeArray); final ClassWriter cw = createClassWriter(targetClassLoader, cr); final int targetClassLoaderObjectID = ObjectIDs.instance.identity(targetClassLoader); cr.accept( @@ -98,55 +107,7 @@ private byte[] weavingEvent(final ClassLoader targetClassLoader, ), EXPAND_FRAMES ); - return cw.toByteArray(); - // return dumpClassIfNecessary(SandboxStringUtils.toJavaClassName(cr.getClassName()), cw.toByteArray()); - } - - -// /* -// * dump class to file -// * 用于代码调试 -// */ -// private static byte[] dumpClassIfNecessary(String className, byte[] data) { -// final File dumpClassFile = new File("./sandbox-class-dump/" + className + ".class"); -// final File classPath = new File(dumpClassFile.getParent()); -// -// // 创建类所在的包路径 -// if (!classPath.mkdirs() -// && !classPath.exists()) { -// logger.warn("create dump classpath={} failed.", classPath); -// return data; -// } -// -// // 将类字节码写入文件 -// try { -// writeByteArrayToFile(dumpClassFile, data); -// logger.info("dump {} to {} success.", className, dumpClassFile); -// } catch (IOException e) { -// logger.warn("dump {} to {} failed.", className, dumpClassFile, e); -// } -// -// return data; -// } - - @Override - public byte[] toByteCodeArray(final ClassLoader targetClassLoader, - final byte[] byteCodeArray, - final Set signCodes, - final String namespace, - final int listenerId, - final Event.Type[] eventTypeArray) { - // 如果定义间谍类失败了,则后续不需要增强 - try { - SpyUtils.init(namespace); - // defineSpyIfNecessary(targetClassLoader); - } catch (Throwable cause) { - logger.warn("define Spy to target ClassLoader={} failed.", targetClassLoader, cause); - return byteCodeArray; - } - - // 返回增强后字节码 - return weavingEvent(targetClassLoader, byteCodeArray, signCodes, namespace, listenerId, eventTypeArray); + return dumpClassIfNecessary(cr.getClassName(), cw.toByteArray()); } } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/annotation/Interrupted.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/annotation/Interrupted.java index df1657ba..5a9969b0 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/annotation/Interrupted.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/annotation/Interrupted.java @@ -5,7 +5,7 @@ /** * 中断式事件处理器 * 当事件处理器处理事件抛出异常时,将会中断原有方法调用 - * Created by luanjia@taobao.com on 16/7/26. + * @author luanjia@taobao.com */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers.java index f9121a79..6017dc49 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers.java @@ -3,25 +3,23 @@ import com.alibaba.jvm.sandbox.api.ProcessControlException; import com.alibaba.jvm.sandbox.api.event.BeforeEvent; import com.alibaba.jvm.sandbox.api.event.Event; -import com.alibaba.jvm.sandbox.api.event.ReturnEvent; -import com.alibaba.jvm.sandbox.api.event.ThrowsEvent; +import com.alibaba.jvm.sandbox.api.event.ImmediatelyReturnEvent; +import com.alibaba.jvm.sandbox.api.event.ImmediatelyThrowsEvent; import com.alibaba.jvm.sandbox.api.listener.EventListener; -import com.alibaba.jvm.sandbox.core.enhance.annotation.Interrupted; -import com.alibaba.jvm.sandbox.core.util.EventPool; import com.alibaba.jvm.sandbox.core.util.ObjectIDs; -import com.alibaba.jvm.sandbox.core.util.Sequencer; -import com.alibaba.jvm.sandbox.core.util.collection.GaStack; -import com.alibaba.jvm.sandbox.core.util.collection.ThreadUnsafeGaStack; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.com.alibaba.jvm.sandbox.spy.Spy; -import java.lang.reflect.Method; import java.util.Map; -import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; -import static com.alibaba.jvm.sandbox.core.util.SandboxReflectUtils.unCaughtGetClassDeclaredJavaMethod; +import static com.alibaba.jvm.sandbox.api.event.Event.Type.IMMEDIATELY_RETURN; +import static com.alibaba.jvm.sandbox.api.event.Event.Type.IMMEDIATELY_THROWS; +import static com.alibaba.jvm.sandbox.core.util.SandboxReflectUtils.isInterruptEventHandler; +import static java.com.alibaba.jvm.sandbox.spy.Spy.Ret.newInstanceForNone; +import static org.apache.commons.lang3.ArrayUtils.contains; import static org.apache.commons.lang3.StringUtils.join; /** @@ -34,40 +32,28 @@ public class EventListenerHandlers { private final Logger logger = LoggerFactory.getLogger(getClass()); // 调用序列生成器 - private final Sequencer invokeIdSequencer = new Sequencer(1000); + // private final Sequencer invokeIdSequencer = new Sequencer(); + private final AtomicInteger invokeIdSequencer = new AtomicInteger(1000); // 全局处理器ID:处理器映射集合 - private final Map globalEventListenerMap - = new ConcurrentHashMap(); - - // 事件对象池 - private final EventPool eventPool = new EventPool(); - - /** - * 获取事件对象池 - * - * @return 事件对象池 - */ - public EventPool getEventPool() { - return eventPool; - } + private final Map mappingOfEventProcessor + = new ConcurrentHashMap(); /** * 注册事件处理器 * - * @param listenerId 事件监听器ID - * @param listener 事件监听器 - * @param eventTypeArray 监听事件集合 + * @param listenerId 事件监听器ID + * @param listener 事件监听器 + * @param eventTypes 监听事件集合 */ public void active(final int listenerId, final EventListener listener, - final Event.Type[] eventTypeArray) { - final EventListenerWrap wrap = new EventListenerWrap(listenerId, listener, eventTypeArray); - globalEventListenerMap.put(listenerId, wrap); + final Event.Type[] eventTypes) { + mappingOfEventProcessor.put(listenerId, new EventProcessor(listenerId, listener, eventTypes)); logger.info("activated listener[id={};target={};] event={}", listenerId, listener, - join(eventTypeArray, ",") + join(eventTypes, ",") ); } @@ -77,16 +63,18 @@ public void active(final int listenerId, * @param listenerId 事件处理器ID */ public void frozen(int listenerId) { - final EventListenerWrap wrap = globalEventListenerMap.remove(listenerId); - if (null == wrap) { - logger.debug("ignore frozen listener[id={};], because not found."); + final EventProcessor processor = mappingOfEventProcessor.remove(listenerId); + if (null == processor) { + logger.debug("ignore frozen listener={}, because not found.", listenerId); return; } logger.info("frozen listener[id={};target={};]", listenerId, - wrap.listener + processor.listener ); + + // processor.clean(); } /** @@ -96,7 +84,7 @@ public void frozen(int listenerId) { * @param processId 调用过程ID * @param invokeId 调用ID * @param event 调用事件 - * @param wrap 事件处理器封装 + * @param processor 事件处理器 * @return 处理返回结果 * @throws Throwable 当出现未知异常时,且事件处理器为中断流程事件时抛出 */ @@ -104,20 +92,22 @@ private Spy.Ret handleEvent(final int listenerId, final int processId, final int invokeId, final Event event, - final EventListenerWrap wrap) throws Throwable { - final EventListener listener = wrap.listener; + final EventProcessor processor) throws Throwable { + final EventListener listener = processor.listener; try { - // 调用事件处理 - listener.onEvent(event); - if (logger.isDebugEnabled()) { - logger.debug("on-event: event|{}|{}|{}@listener|{}", - event.type, - processId, - invokeId, - listenerId - ); + if (contains(processor.eventTypes, event.type)) { + // 调用事件处理 + listener.onEvent(event); + if (logger.isDebugEnabled()) { + logger.debug("on-event: event|{}|{}|{}@listener|{}", + event.type, + processId, + invokeId, + listenerId + ); + } } } @@ -125,6 +115,8 @@ private Spy.Ret handleEvent(final int listenerId, // 代码执行流程变更 catch (ProcessControlException pce) { + final EventProcessor.Process process = processor.processRef.get(); + final ProcessControlException.State state = pce.getState(); logger.debug("on-event: event|{}|{}|{};listener|{}, process-changed: {}. isIgnoreProcessEvent={};", event.type, @@ -135,12 +127,10 @@ private Spy.Ret handleEvent(final int listenerId, pce.isIgnoreProcessEvent() ); - final EventListenerWrap.EventProcess eventProcess = wrap.eventProcessRef.get(); - // 如果流程控制要求忽略后续处理所有事件,则需要在此处进行标记 // 标记当前线程中、当前EventListener中需要主动忽略的ProcessId if (pce.isIgnoreProcessEvent()) { - eventProcess.markIgnoreProcessEvent(processId); + process.markIgnoreProcessId(processId); } switch (state) { @@ -148,38 +138,51 @@ private Spy.Ret handleEvent(final int listenerId, // 立即返回对象 case RETURN_IMMEDIATELY: { - // 将BEFORE压入的堆栈弹出 + // 如果在BeforeEvent处理过程中发生ProcessControl行为,将会造成堆栈错位 + // 所以这里需要将错位的堆栈进行补齐 if (event instanceof BeforeEvent) { - final GaStack stack = wrap.eventProcessRef.get().processStack; - stack.pop(); - wrap.cleanIfLast(); - if (logger.isDebugEnabled()) { - logger.debug("invoke-stack mock pop, IMMEDIATELY-RETURN deep={};listener={};pid={};iid={}", - stack.deep(), - listenerId, - processId, - invokeId - ); - } + process.popInvokeId(); } // 如果已经禁止后续返回任何事件了,则不进行后续的操作 if (pce.isIgnoreProcessEvent()) { + logger.debug("on-event: event|{}|{}|{};listener|{}, ignore immediately-return-event, isIgnored.", + event.type, + processId, + invokeId, + listenerId + ); return Spy.Ret.newInstanceForReturn(pce.getRespond()); } - final ReturnEvent replaceReturnEvent = eventPool.borrowReturnEvent(processId, invokeId, pce.getRespond()); + // 如果没有注册监听ImmediatelyEvent事件,则不进行后续的操作 + if (!contains(processor.eventTypes, IMMEDIATELY_RETURN)) { + logger.debug("on-event: event|{}|{}|{};listener|{}, ignore immediately-return-event, not contains.", + event.type, + processId, + invokeId, + listenerId + ); + return Spy.Ret.newInstanceForReturn(pce.getRespond()); + } + + // 这里需要补偿ImmediatelyEvent + final ImmediatelyReturnEvent immediatelyReturnEvent + = process + .getEventFactory() + .makeImmediatelyReturnEvent(processId, invokeId, pce.getRespond()); + final Spy.Ret ret; try { ret = handleEvent( listenerId, processId, invokeId, - replaceReturnEvent, - wrap + immediatelyReturnEvent, + processor ); } finally { - eventPool.returnEvent(replaceReturnEvent); + process.getEventFactory().returnEvent(immediatelyReturnEvent); } if (ret.state == Spy.Ret.RET_STATE_NONE) { @@ -194,52 +197,65 @@ private Spy.Ret handleEvent(final int listenerId, // 立即抛出异常 case THROWS_IMMEDIATELY: { - // 将BEFORE压入的堆栈弹出 + final Throwable throwable = (Throwable) pce.getRespond(); + + // 如果在BeforeEvent处理过程中发生ProcessControl行为,将会造成堆栈错位 + // 所以这里需要将错位的堆栈进行补齐 if (event instanceof BeforeEvent) { - final GaStack stack = wrap.eventProcessRef.get().processStack; - stack.pop(); - wrap.cleanIfLast(); - if (logger.isDebugEnabled()) { - logger.debug("invoke-stack mock pop, IMMEDIATELY-THROWS deep={};listener={};pid={};iid={}", - stack.deep(), - listenerId, - processId, - invokeId - ); - } + process.popInvokeId(); } - final Throwable throwable = (Throwable) pce.getRespond(); + // 如果已经禁止后续返回任何事件了,则不进行后续的操作 + if (pce.isIgnoreProcessEvent()) { + logger.debug("on-event: event|{}|{}|{};listener|{}, ignore immediately-throws-event, isIgnored.", + event.type, + processId, + invokeId, + listenerId + ); + return Spy.Ret.newInstanceForThrows(throwable); + } + + // 如果没有注册监听ImmediatelyEvent事件,则不进行后续的操作 + if (!contains(processor.eventTypes, IMMEDIATELY_THROWS)) { + logger.debug("on-event: event|{}|{}|{};listener|{}, ignore immediately-throws-event, not contains.", + event.type, + processId, + invokeId, + listenerId + ); + return Spy.Ret.newInstanceForThrows(throwable); + } // 如果已经禁止后续返回任何事件了,则不进行后续的操作 if (pce.isIgnoreProcessEvent()) { return Spy.Ret.newInstanceForThrows(throwable); } - if (!(event instanceof BeforeEvent)) { - - final ThrowsEvent replaceThrowsEvent = eventPool.borrowThrowsEvent(processId, invokeId, throwable); - final Spy.Ret ret; - try { - ret = handleEvent( - listenerId, - processId, - invokeId, - replaceThrowsEvent, - wrap - ); - } finally { - eventPool.returnEvent(replaceThrowsEvent); - } - - if (ret.state == Spy.Ret.RET_STATE_NONE) { - return Spy.Ret.newInstanceForThrows(throwable); - } else { - // 如果不是,则返回最新的处理结果 - return ret; - } - } else { + final ImmediatelyThrowsEvent immediatelyThrowsEvent + = process + .getEventFactory() + .makeImmediatelyThrowsEvent(processId, invokeId, throwable); + + + final Spy.Ret ret; + try { + ret = handleEvent( + listenerId, + processId, + invokeId, + immediatelyThrowsEvent, + processor + ); + } finally { + process.getEventFactory().returnEvent(immediatelyThrowsEvent); + } + + if (ret.state == Spy.Ret.RET_STATE_NONE) { return Spy.Ret.newInstanceForThrows(throwable); + } else { + // 如果不是,则返回最新的处理结果 + return ret; } } @@ -247,7 +263,7 @@ private Spy.Ret handleEvent(final int listenerId, // 什么都不操作,立即返回 case NONE_IMMEDIATELY: default: { - return Spy.Ret.newInstanceForNone(); + return newInstanceForNone(); } } @@ -264,7 +280,7 @@ private Spy.Ret handleEvent(final int listenerId, // 普通事件处理器则可以打个日志后,直接放行 else { - logger.debug("on-event: event|{}|{}|{};listener|{} occur an error.", + logger.warn("on-event: event|{}|{}|{};listener|{} occur an error.", event.type, processId, invokeId, @@ -275,73 +291,11 @@ private Spy.Ret handleEvent(final int listenerId, } // 默认返回不进行任何流程变更 - return Spy.Ret.newInstanceForNone(); - } - - private boolean isInterruptEventHandler(final Class listenerClass) { - return listenerClass.isAnnotationPresent(Interrupted.class); - } - - - private final WeakHashMap spyNewInstanceForNoneMethodCache = new WeakHashMap(); - private final WeakHashMap spyNewInstanceForReturnMethodCache = new WeakHashMap(); - private final WeakHashMap spyNewInstanceForThrowsMethodCache = new WeakHashMap(); - - // 转换当前的Spy.Ret到目标类所在ClassLoader的Spy.Ret - private Object toSpyRetInTargetClassLoader(final Spy.Ret ret, final Class spyRetClassInTargetClassLoader) throws Throwable { - - // 如果两个Spy.Ret的类相等,说明他们在同一个ClassLoader空间 - // 可以直接返回当前我们自己构造的Spy.Ret,不需要走如此复杂的反射 - if (Spy.Ret.class == spyRetClassInTargetClassLoader) { - return ret; - } - - // 如果当前Spy.Ret和目标ClassLoader中的Spy.Ret不一致,说明他们来自不同的ClassLoader空间 - // 此时就需要性能比较高昂的转换了,这里稍微加了几个MethodCache做了性能缓冲,尽量减少性能开销 - // 但此时我觉得必要性可能不大,后续考虑可以直接优化掉这个几个MethodCache - switch (ret.state) { - case Spy.Ret.RET_STATE_NONE: { - - final Method method; - if (spyNewInstanceForNoneMethodCache.containsKey(spyRetClassInTargetClassLoader)) { - method = spyNewInstanceForNoneMethodCache.get(spyRetClassInTargetClassLoader); - } else { - method = unCaughtGetClassDeclaredJavaMethod(spyRetClassInTargetClassLoader, "newInstanceForNone"); - spyNewInstanceForNoneMethodCache.put(spyRetClassInTargetClassLoader, method); - } - return method.invoke(null); - } - - case Spy.Ret.RET_STATE_RETURN: { - final Method method; - if (spyNewInstanceForReturnMethodCache.containsKey(spyRetClassInTargetClassLoader)) { - method = spyNewInstanceForReturnMethodCache.get(spyRetClassInTargetClassLoader); - } else { - method = unCaughtGetClassDeclaredJavaMethod(spyRetClassInTargetClassLoader, "newInstanceForReturn", Object.class); - spyNewInstanceForReturnMethodCache.put(spyRetClassInTargetClassLoader, method); - } - return method.invoke(null, ret.respond); - } - - case Spy.Ret.RET_STATE_THROWS: { - final Method method; - if (spyNewInstanceForThrowsMethodCache.containsKey(spyRetClassInTargetClassLoader)) { - method = spyNewInstanceForThrowsMethodCache.get(spyRetClassInTargetClassLoader); - } else { - method = unCaughtGetClassDeclaredJavaMethod(spyRetClassInTargetClassLoader, "newInstanceForThrows", Throwable.class); - spyNewInstanceForThrowsMethodCache.put(spyRetClassInTargetClassLoader, method); - } - return method.invoke(null, (Throwable) ret.respond); - } - - default: { - throw new IllegalStateException("illegal Spy.Ret.state=" + ret.state); - } - } + return newInstanceForNone(); } private Spy.Ret handleOnBefore(final int listenerId, - final ClassLoader javaClassLoader, + final int targetClassLoaderObjectID, final String javaClassName, final String javaMethodName, final String javaMethodDesc, @@ -349,47 +303,32 @@ private Spy.Ret handleOnBefore(final int listenerId, final Object[] argumentArray) throws Throwable { // 获取事件处理器 - final EventListenerWrap wrap = globalEventListenerMap.get(listenerId); + final EventProcessor wrap = mappingOfEventProcessor.get(listenerId); // 如果尚未注册,则直接返回,不做任何处理 if (null == wrap) { logger.debug("listener={} is not activated, ignore processing before-event.", listenerId); - return Spy.Ret.newInstanceForNone(); + return newInstanceForNone(); } // 获取调用跟踪信息 - final EventListenerWrap.EventProcess eventProcess = wrap.eventProcessRef.get(); - final GaStack stack = eventProcess.processStack; + final EventProcessor.Process process = wrap.processRef.get(); // 调用ID - final int invokeId = invokeIdSequencer.next(); + final int invokeId = invokeIdSequencer.getAndIncrement(); + process.pushInvokeId(invokeId); // 调用过程ID - final int processId = stack.isEmpty() - ? invokeId - : stack.peekLast(); - - // 将当前调用压栈 - stack.push(invokeId); - - if (logger.isDebugEnabled()) { - logger.debug("invoke-stack push, deep={};listener={};pid={};iid={}", - stack.deep(), - listenerId, - processId, - invokeId - ); - } + final int processId = process.getProcessId(); // 如果当前处理ID被忽略,则立即返回 - // 放在stack.push后边是为了对齐执行栈 - if (eventProcess.isIgnoreProcessEvent(processId)) { - return Spy.Ret.newInstanceForNone(); - } else { - eventProcess.cleanIgnoreProcessEvent(); + if (process.touchIsIgnoreProcess(processId)) { + process.popInvokeId(); + return newInstanceForNone(); } - final BeforeEvent event = eventPool.borrowBeforeEvent( + final ClassLoader javaClassLoader = ObjectIDs.instance.getObject(targetClassLoaderObjectID); + final BeforeEvent event = process.getEventFactory().makeBeforeEvent( processId, invokeId, javaClassLoader, @@ -402,144 +341,102 @@ private Spy.Ret handleOnBefore(final int listenerId, try { return handleEvent(listenerId, processId, invokeId, event, wrap); } finally { - eventPool.returnEvent(event); + process.getEventFactory().returnEvent(event); } } /* * 判断堆栈是否错位 */ - private boolean isStackErrorPosition(final int processId, - final int invokeId, - final GaStack stack) { - return (processId == invokeId && !stack.isEmpty()) - || (processId != invokeId && stack.isEmpty()); + private boolean checkProcessStack(final int processId, + final int invokeId, + final boolean isEmptyStack) { + return (processId == invokeId && !isEmptyStack) + || (processId != invokeId && isEmptyStack); } private Spy.Ret handleOnEnd(final int listenerId, final Object object, final boolean isReturn) throws Throwable { - final EventListenerWrap wrap = globalEventListenerMap.get(listenerId); + final EventProcessor wrap = mappingOfEventProcessor.get(listenerId); // 如果尚未注册,则直接返回,不做任何处理 if (null == wrap) { logger.debug("listener={} is not activated, ignore processing return-event|throws-event.", listenerId); - return Spy.Ret.newInstanceForNone(); + return newInstanceForNone(); } - final EventListenerWrap.EventProcess eventProcess = wrap.eventProcessRef.get(); - final GaStack stack = eventProcess.processStack; + final EventProcessor.Process process = wrap.processRef.get(); // 如果当前调用过程信息堆栈是空的,说明 // 1. BEFORE/RETURN错位 // 2. super. // 处理方式是直接返回,不做任何事件的处理和代码流程的改变,放弃对super.的观察,可惜了 - if (stack.isEmpty()) { - return Spy.Ret.newInstanceForNone(); + if (process.isEmptyStack()) { + return newInstanceForNone(); } - final int processId = stack.peekLast(); - final int invokeId = stack.pop(); - wrap.cleanIfLast(); - - if (logger.isDebugEnabled()) { - logger.debug("invoke-stack pop, deep={};listener={};pid={};iid={}", - stack.deep(), - listenerId, - processId, - invokeId - ); - } + final int processId = process.getProcessId(); + final int invokeId = process.popInvokeId(); // 如果PID==IID说明已经到栈顶,此时需要核对堆栈是否为空 // 如果不为空需要输出日志进行告警 - if (isStackErrorPosition(processId, invokeId, stack)) { - logger.warn("stack error position. deep={};listener={};", stack.deep(), listenerId); + if (checkProcessStack(processId, invokeId, process.isEmptyStack())) { + logger.warn("ERROR process-stack. pid={};iid={};listener={};", + processId, + invokeId, + listenerId + ); } // 忽略事件处理 // 放在stack.pop()后边是为了对齐执行栈 - if (eventProcess.isIgnoreProcessEvent(processId)) { - return Spy.Ret.newInstanceForNone(); + if (process.touchIsIgnoreProcess(processId)) { + return newInstanceForNone(); } final Event event = isReturn - ? eventPool.borrowReturnEvent(processId, invokeId, object) - : eventPool.borrowThrowsEvent(processId, invokeId, (Throwable) object); + ? process.getEventFactory().makeReturnEvent(processId, invokeId, object) + : process.getEventFactory().makeThrowsEvent(processId, invokeId, (Throwable) object); try { return handleEvent(listenerId, processId, invokeId, event, wrap); } finally { - eventPool.returnEvent(event); + process.getEventFactory().returnEvent(event); } } - - private Object handleOnBeforeWithTargetClassLoaderSpyRet(final int listenerId, - final ClassLoader javaClassLoader, - final Class spyRetClassInTargetClassLoader, - final String javaClassName, - final String javaMethodName, - final String javaMethodDesc, - final Object target, - final Object[] argumentArray) throws Throwable { - return toSpyRetInTargetClassLoader( - handleOnBefore( - listenerId, - javaClassLoader, - javaClassName, - javaMethodName, - javaMethodDesc, - target, - argumentArray - ), - spyRetClassInTargetClassLoader - ); - } - - private Object handleOnReturnWithTargetClassLoaderSpyRet(final int listenerId, - final Class spyRetClassInTargetClassLoader, - final Object object) throws Throwable { - return toSpyRetInTargetClassLoader(handleOnEnd(listenerId, object, true), spyRetClassInTargetClassLoader); - } - - private Object handleOnThrowsWithTargetClassLoaderSpyRet(final int listenerId, - final Class spyRetClassInTargetClassLoader, - final Throwable throwable) throws Throwable { - return toSpyRetInTargetClassLoader(handleOnEnd(listenerId, throwable, false), spyRetClassInTargetClassLoader); - } - private void handleOnLine(final int listenerId, final int lineNumber) throws Throwable { - final EventListenerWrap wrap = globalEventListenerMap.get(listenerId); + final EventProcessor wrap = mappingOfEventProcessor.get(listenerId); if (null == wrap) { logger.debug("listener={} is not activated, ignore processing line-event.", listenerId); return; } - final EventListenerWrap.EventProcess eventProcess = wrap.eventProcessRef.get(); - final GaStack stack = eventProcess.processStack; + final EventProcessor.Process process = wrap.processRef.get(); // 如果当前调用过程信息堆栈是空的,说明BEFORE/LINE错位 // 处理方式是直接返回,不做任何事件的处理和代码流程的改变 - if (stack.isEmpty()) { + if (process.isEmptyStack()) { return; } - final int processId = stack.peekLast(); - final int invokeId = stack.peek(); + + final int processId = process.getProcessId(); + final int invokeId = process.getInvokeId(); // 如果事件处理流被忽略,则直接返回,不产生后续事件 - if (eventProcess.isIgnoreProcessEvent(processId)) { + if (process.touchIsIgnoreProcess(processId)) { return; } - final Event event = eventPool.borrowLineEvent(processId, invokeId, lineNumber); + final Event event = process.getEventFactory().makeLineEvent(processId, invokeId, lineNumber); try { handleEvent(listenerId, processId, invokeId, event, wrap); } finally { - eventPool.returnEvent(event); + process.getEventFactory().returnEvent(event); } } @@ -549,176 +446,103 @@ private void handleOnCallBefore(final int listenerId, final String owner, final String name, final String desc) throws Throwable { - final EventListenerWrap wrap = globalEventListenerMap.get(listenerId); + final EventProcessor wrap = mappingOfEventProcessor.get(listenerId); if (null == wrap) { logger.debug("listener={} is not activated, ignore processing call-before-event.", listenerId); return; } - final EventListenerWrap.EventProcess eventProcess = wrap.eventProcessRef.get(); - final GaStack stack = eventProcess.processStack; - + final EventProcessor.Process process = wrap.processRef.get(); // 如果当前调用过程信息堆栈是空的,有两种情况 // 1. CALL_BEFORE事件和BEFORE事件错位 // 2. 当前方法是,而CALL_BEFORE事件触发是当前方法在调用父类的 // super.会导致CALL_BEFORE事件优先于BEFORE事件 // 但如果按照现在的架构要兼容这种情况,比较麻烦,所以暂时先放弃了这部分的消息,可惜可惜 - if (stack.isEmpty()) { + if (process.isEmptyStack()) { return; } - final int processId = stack.peekLast(); - final int invokeId = stack.peek(); + final int processId = process.getProcessId(); + final int invokeId = process.getInvokeId(); // 如果事件处理流被忽略,则直接返回,不产生后续事件 - if (eventProcess.isIgnoreProcessEvent(processId)) { + if (process.touchIsIgnoreProcess(processId)) { return; } - final Event event = eventPool.borrowCallBeforeEvent(processId, invokeId, lineNumber, owner, name, desc); + final Event event = process + .getEventFactory() + .makeCallBeforeEvent(processId, invokeId, lineNumber, owner, name, desc); try { handleEvent(listenerId, processId, invokeId, event, wrap); } finally { - eventPool.returnEvent(event); + process.getEventFactory().returnEvent(event); } } private void handleOnCallReturn(final int listenerId) throws Throwable { - final EventListenerWrap wrap = globalEventListenerMap.get(listenerId); + final EventProcessor wrap = mappingOfEventProcessor.get(listenerId); if (null == wrap) { logger.debug("listener={} is not activated, ignore processing call-return-event.", listenerId); return; } - final EventListenerWrap.EventProcess eventProcess = wrap.eventProcessRef.get(); - final GaStack stack = eventProcess.processStack; - if (stack.isEmpty()) { + final EventProcessor.Process process = wrap.processRef.get(); + if (process.isEmptyStack()) { return; } - final int processId = stack.peekLast(); - final int invokeId = stack.peek(); + final int processId = process.getProcessId(); + final int invokeId = process.getInvokeId(); // 如果事件处理流被忽略,则直接返回,不产生后续事件 - if (eventProcess.isIgnoreProcessEvent(processId)) { + if (process.touchIsIgnoreProcess(processId)) { return; } - final Event event = eventPool.borrowCallReturnEvent(processId, invokeId); + final Event event = process + .getEventFactory() + .makeCallReturnEvent(processId, invokeId); try { handleEvent(listenerId, processId, invokeId, event, wrap); } finally { - eventPool.returnEvent(event); + process.getEventFactory().returnEvent(event); } } private void handleOnCallThrows(final int listenerId, final String throwException) throws Throwable { - final EventListenerWrap wrap = globalEventListenerMap.get(listenerId); + final EventProcessor wrap = mappingOfEventProcessor.get(listenerId); if (null == wrap) { logger.debug("listener={} is not activated, ignore processing call-throws-event.", listenerId); return; } - final EventListenerWrap.EventProcess eventProcess = wrap.eventProcessRef.get(); - final GaStack stack = eventProcess.processStack; - if (stack.isEmpty()) { + final EventProcessor.Process process = wrap.processRef.get(); + if (process.isEmptyStack()) { return; } - final int processId = stack.peekLast(); - final int invokeId = stack.peek(); + final int processId = process.getProcessId(); + final int invokeId = process.getInvokeId(); // 如果事件处理流被忽略,则直接返回,不产生后续事件 - if (eventProcess.isIgnoreProcessEvent(processId)) { + if (process.touchIsIgnoreProcess(processId)) { return; } - final Event event = eventPool.borrowCallThrowsEvent(processId, invokeId, throwException); + final Event event = process + .getEventFactory() + .makeCallThrowsEvent(processId, invokeId, throwException); try { handleEvent(listenerId, processId, invokeId, event, wrap); } finally { - eventPool.returnEvent(event); - } - } - - /** - * 事件处理器封装 - */ - private final class EventListenerWrap { - - class EventProcess { - - final GaStack processStack = new ThreadUnsafeGaStack(); - Integer ignoreProcessId = null; - - boolean isIgnoreProcessEvent(int targetProcessId) { - return ignoreProcessId != null - && ignoreProcessId == targetProcessId; - } - - void markIgnoreProcessEvent(int processId) { - this.ignoreProcessId = processId; - } - - void cleanIgnoreProcessEvent() { - this.ignoreProcessId = null; - } - - } - - private final int listenerId; - private final EventListener listener; - private final ThreadLocal eventProcessRef = new ThreadLocal() { - @Override - protected EventProcess initialValue() { - return new EventProcess(); - } - }; - - private EventListenerWrap(final int listenerId, - final EventListener listener, - final Event.Type[] eventTypeArray) { - - this.listenerId = listenerId; - - if (isInterruptEventHandler(listener.getClass())) { - this.listener = new InterruptedEventListenerImpl( - new SeparateImmediatelyEventListener(listener, eventTypeArray, eventPool) - ); - } else { - this.listener = new SeparateImmediatelyEventListener(listener, eventTypeArray, eventPool); - } + process.getEventFactory().returnEvent(event); } - - void cleanIfLast() { - final EventProcess eventProcess = eventProcessRef.get(); - if (eventProcess.processStack.isEmpty()) { - eventProcessRef.remove(); - logger.debug("clean TLS: listener-wrap, listener={};", listenerId); - } - } - - } - - @Interrupted - private class InterruptedEventListenerImpl implements EventListener { - - private final EventListener listener; - - private InterruptedEventListenerImpl(EventListener listener) { - this.listener = listener; - } - - @Override - public void onEvent(Event event) throws Throwable { - listener.onEvent(event); - } - } @@ -730,7 +554,6 @@ public static EventListenerHandlers getSingleton() { return singleton; } - public static Object onBefore(final int listenerId, final int targetClassLoaderObjectID, final Class spyRetClassInTargetClassLoader, @@ -739,10 +562,9 @@ public static Object onBefore(final int listenerId, final String javaMethodDesc, final Object target, final Object[] argumentArray) throws Throwable { - return singleton.handleOnBeforeWithTargetClassLoaderSpyRet( + return singleton.handleOnBefore( listenerId, - (ClassLoader) ObjectIDs.instance.getObject(targetClassLoaderObjectID), - spyRetClassInTargetClassLoader, + targetClassLoaderObjectID, javaClassName, javaMethodName, javaMethodDesc, @@ -754,13 +576,13 @@ public static Object onBefore(final int listenerId, public static Object onReturn(final int listenerId, final Class spyRetClassInTargetClassLoader, final Object object) throws Throwable { - return singleton.handleOnReturnWithTargetClassLoaderSpyRet(listenerId, spyRetClassInTargetClassLoader, object); + return singleton.handleOnEnd(listenerId, object, true); } public static Object onThrows(final int listenerId, final Class spyRetClassInTargetClassLoader, final Throwable throwable) throws Throwable { - return singleton.handleOnThrowsWithTargetClassLoaderSpyRet(listenerId, spyRetClassInTargetClassLoader, throwable); + return singleton.handleOnEnd(listenerId, throwable, false); } public static void onLine(final int listenerId, @@ -773,13 +595,7 @@ public static void onCallBefore(final int listenerId, final String owner, final String name, final String desc) throws Throwable { - singleton.handleOnCallBefore( - listenerId, - lineNumber, - owner, - name, - desc - ); + singleton.handleOnCallBefore(listenerId, lineNumber, owner, name, desc); } public static void onCallReturn(final int listenerId) throws Throwable { @@ -791,5 +607,15 @@ public static void onCallThrows(final int listenerId, singleton.handleOnCallThrows(listenerId, throwException); } + // ---- 自检查 + public void checkEventProcessor(final int... listenerIds) { + for (int listenerId : listenerIds) { + final EventProcessor processor = mappingOfEventProcessor.get(listenerId); + if (null == processor) { + throw new IllegalStateException(String.format("listener=%s not existed.", listenerId)); + } + processor.check(); + } + } } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/EventProcessor.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/EventProcessor.java new file mode 100644 index 00000000..7e0c0160 --- /dev/null +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/EventProcessor.java @@ -0,0 +1,193 @@ +package com.alibaba.jvm.sandbox.core.enhance.weaver; + +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.api.listener.EventListener; +import com.alibaba.jvm.sandbox.core.enhance.annotation.Interrupted; +import com.alibaba.jvm.sandbox.core.util.collection.GaStack; +import com.alibaba.jvm.sandbox.core.util.collection.ThreadUnsafeGaStack; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.alibaba.jvm.sandbox.core.util.SandboxReflectUtils.isInterruptEventHandler; + +/** + * 事件处理器 + */ +class EventProcessor { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + /** + * 处理单元 + */ + class Process { + + // 事件工厂 + private final SingleEventFactory eventFactory + = new SingleEventFactory(); + + // 调用堆栈 + private final GaStack stack + = new ThreadUnsafeGaStack(); + + // 需要忽略的过程ID + private Integer ignoreProcessId = null; + + void pushInvokeId(int invokeId) { + stack.push(invokeId); + logger.debug("push process-stack, invoke-id={};deep={};listener={};", + invokeId, + stack.deep(), + listenerId + ); + } + + int popInvokeId() { + final int invokeId = stack.pop(); + logger.debug("pop process-stack, invoke-id={};deep={};listener={};", + invokeId, + stack.deep(), + listenerId + ); + if (stack.isEmpty()) { + processRef.remove(); + logger.debug("clean TLS: event-processor, listener={};", listenerId); + } + return invokeId; + } + + int getInvokeId() { + return stack.peek(); + } + + int getProcessId() { + return stack.peekLast(); + } + + boolean isEmptyStack() { + return stack.isEmpty(); + } + + boolean touchIsIgnoreProcess(int processId) { + if (null != ignoreProcessId + && ignoreProcessId == processId) { + return true; + } else { + ignoreProcessId = null; + return false; + } + } + + void markIgnoreProcessId(int processId) { + ignoreProcessId = processId; + } + + SingleEventFactory getEventFactory() { + return eventFactory; + } + + } + + @Interrupted + private class InterruptedEventListenerImpl implements EventListener { + + private final EventListener listener; + + private InterruptedEventListenerImpl(EventListener listener) { + this.listener = listener; + } + + @Override + public void onEvent(Event event) throws Throwable { + listener.onEvent(event); + } + + } + + final int listenerId; + final EventListener listener; + final Event.Type[] eventTypes; + final ThreadLocal processRef = new ThreadLocal() { + @Override + protected Process initialValue() { + return new Process(); + } + }; + + EventProcessor(final int listenerId, + final EventListener listener, + final Event.Type[] eventTypes) { + + this.listenerId = listenerId; + this.eventTypes = eventTypes; + this.listener = isInterruptEventHandler(listener.getClass()) + ? new InterruptedEventListenerImpl(listener) + : listener; + } + + + /** + * 校验器,用于校验事件处理器状态是否正确 + *

用于测试用例

+ */ + class Checker { + + void check() { + + final EventProcessor.Process process = processRef.get(); + final ThreadUnsafeGaStack stack = (ThreadUnsafeGaStack) process.stack; + + if (!process.isEmptyStack()) { + throw new IllegalStateException(String.format("process-stack is not empty! listener=%s;\n%s", + listenerId, + toString(stack) + )); + } + + for (int index = 0; index < stack.getElementArray().length; index++) { + if (index <= stack.getCurrent()) { + if (null == stack.getElementArray()[index]) { + throw new IllegalStateException(String.format("process-stack element is null at index=[%d], listener=%s;\n%s", + index, + listenerId, + toString(stack) + )); + } + } else { + if (null != stack.getElementArray()[index]) { + throw new IllegalStateException(String.format("process-stack element is not null at index=[%d], listener=%s;\n%s", + index, + listenerId, + toString(stack) + )); + } + } + } + + if (null != process.ignoreProcessId) { + throw new IllegalStateException(String.format("process ignoreProcessId is not null!, processId=%d", process.ignoreProcessId)); + } + + + } + + String toString(ThreadUnsafeGaStack stack) { + final StringBuilder stackSB = new StringBuilder(String.format("stack[deep=%d;current=%d;]{\n", stack.deep(), stack.getCurrent())); + for (int index = 0; index < stack.getElementArray().length; index++) { + stackSB.append("\t[" + index + "] = " + stack.getElementArray()[index] + "\n"); + } + stackSB.append("}"); + return stackSB.toString(); + } + + } + + /** + * 校验事件处理器 + *

用于测试用例

+ */ + void check() { + new Checker().check(); + } + +} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener.java deleted file mode 100755 index f294be5b..00000000 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.alibaba.jvm.sandbox.core.enhance.weaver; - -import com.alibaba.jvm.sandbox.api.ProcessControlException; -import com.alibaba.jvm.sandbox.api.event.*; -import com.alibaba.jvm.sandbox.api.listener.EventListener; -import com.alibaba.jvm.sandbox.core.util.EventPool; -import org.apache.commons.lang3.ArrayUtils; - -import static com.alibaba.jvm.sandbox.core.enhance.weaver.SeparateImmediatelyEventListener.Step.*; - -/** - * 用于分离"立即返回"/"返回"和"立即异常抛出事件"/"异常抛出事件" - * Created by luanjia@taobao.com on 2017/2/26. - */ -public class SeparateImmediatelyEventListener implements EventListener { - - enum Step { - STEP_IMMEDIATELY_RETURN_EVENT, - STEP_IMMEDIATELY_THROWS_EVENT, - STEP_ORIGINAL_EVENT - } - - private final ThreadLocal stepRef = new ThreadLocal() { - @Override - protected Step initialValue() { - return STEP_ORIGINAL_EVENT; - } - }; - - - private final EventListener listener; - private final EventPool eventPool; - private final Event.Type[] eventTypeArray; - - public SeparateImmediatelyEventListener(final EventListener listener, - final Event.Type[] eventTypeArray, - final EventPool eventPool) { - this.listener = listener; - this.eventPool = eventPool; - this.eventTypeArray = eventTypeArray; - } - - @Override - public void onEvent(final Event event) throws Throwable { - - // 只有BEFORE/RETURN/THROWS事件才需要进行分离 - if (!(event instanceof BeforeEvent) - && !(event instanceof ReturnEvent) - && !(event instanceof ThrowsEvent)) { - if(!ArrayUtils.contains(eventTypeArray, event.type)) { - return; - } - listener.onEvent(event); - return; - } - - // 分离Immediately事件 - final Event replaceEvent; - final Step step = stepRef.get(); - switch (step) { - case STEP_IMMEDIATELY_RETURN_EVENT: { - final ReturnEvent returnEvent = (ReturnEvent) event; - replaceEvent = eventPool.borrowImmediatelyReturnEvent(returnEvent.processId, returnEvent.invokeId, returnEvent.object); - break; - } - case STEP_IMMEDIATELY_THROWS_EVENT: { - final ThrowsEvent throwsEvent = (ThrowsEvent) event; - replaceEvent = eventPool.borrowImmediatelyThrowsEvent(throwsEvent.processId, throwsEvent.invokeId, throwsEvent.throwable); - break; - } - case STEP_ORIGINAL_EVENT: - default: { - replaceEvent = event; - break; - } - } - - // 驱动分离后的事件 - try { - stepRef.set(STEP_ORIGINAL_EVENT); - - // 如果当前事件(分离之后)不在事件监听范围,则直接忽略什么都不用处理 - if (!ArrayUtils.contains(eventTypeArray, replaceEvent.type)) { - return; - } - - // 处理事件 - listener.onEvent(replaceEvent); - - } catch (ProcessControlException pce) { - - switch (pce.getState()) { - case RETURN_IMMEDIATELY: { - stepRef.set(STEP_IMMEDIATELY_RETURN_EVENT); - break; - } - case THROWS_IMMEDIATELY: { - stepRef.set(STEP_IMMEDIATELY_THROWS_EVENT); - break; - } - case NONE_IMMEDIATELY: - default: { - stepRef.set(STEP_ORIGINAL_EVENT); - break; - } - } - - throw pce; - - } finally { - - // 发生了事件分离才需要归还 - if (replaceEvent != event - && (replaceEvent instanceof ImmediatelyReturnEvent || replaceEvent instanceof ImmediatelyThrowsEvent)) { - eventPool.returnEvent(replaceEvent); - } - - } - - } - -} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/SingleEventFactory.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/SingleEventFactory.java new file mode 100644 index 00000000..3911cf55 --- /dev/null +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/SingleEventFactory.java @@ -0,0 +1,216 @@ +package com.alibaba.jvm.sandbox.core.enhance.weaver; + +import com.alibaba.jvm.sandbox.api.event.*; +import com.alibaba.jvm.sandbox.core.util.UnsafeUtils; +import sun.misc.Unsafe; + +import static com.alibaba.jvm.sandbox.core.util.SandboxReflectUtils.unCaughtSetClassDeclaredJavaFieldValue; + +/** + * 单例事件工厂 + */ +class SingleEventFactory { + + private static final int ILLEGAL_PROCESS_ID = -1; + private static final int ILLEGAL_INVOKE_ID = -1; + + private static final Unsafe unsafe; + private static final long processIdFieldInInvokeEventOffset; + private static final long invokeIdFieldInInvokeEventOffset; + private static final long javaClassLoaderFieldInBeforeEventOffset; + private static final long javaClassNameFieldInBeforeEventOffset; + private static final long javaMethodNameFieldInBeforeEventOffset; + private static final long javaMethodDescFieldInBeforeEventOffset; + private static final long targetFieldInBeforeEventOffset; + private static final long argumentArrayFieldInBeforeEventOffset; + private static final long objectFieldInReturnEventOffset; + private static final long throwableFieldInThrowsEventOffset; + private static final long lineNumberFieldInLineEventOffset; + + private static final long lineNumberFieldInCallBeforeEventOffset; + private static final long ownerFieldInCallBeforeEventOffset; + private static final long nameFieldInCallBeforeEventOffset; + private static final long descFieldInCallBeforeEventOffset; + private static final long throwExceptionFieldInCallThrowsEventOffset; + + static { + try { + unsafe = UnsafeUtils.getUnsafe(); + processIdFieldInInvokeEventOffset = unsafe.objectFieldOffset(InvokeEvent.class.getDeclaredField("processId")); + invokeIdFieldInInvokeEventOffset = unsafe.objectFieldOffset(InvokeEvent.class.getDeclaredField("invokeId")); + javaClassLoaderFieldInBeforeEventOffset = unsafe.objectFieldOffset(BeforeEvent.class.getDeclaredField("javaClassLoader")); + javaClassNameFieldInBeforeEventOffset = unsafe.objectFieldOffset(BeforeEvent.class.getDeclaredField("javaClassName")); + javaMethodNameFieldInBeforeEventOffset = unsafe.objectFieldOffset(BeforeEvent.class.getDeclaredField("javaMethodName")); + javaMethodDescFieldInBeforeEventOffset = unsafe.objectFieldOffset(BeforeEvent.class.getDeclaredField("javaMethodDesc")); + targetFieldInBeforeEventOffset = unsafe.objectFieldOffset(BeforeEvent.class.getDeclaredField("target")); + argumentArrayFieldInBeforeEventOffset = unsafe.objectFieldOffset(BeforeEvent.class.getDeclaredField("argumentArray")); + objectFieldInReturnEventOffset = unsafe.objectFieldOffset(ReturnEvent.class.getDeclaredField("object")); + throwableFieldInThrowsEventOffset = unsafe.objectFieldOffset(ThrowsEvent.class.getDeclaredField("throwable")); + lineNumberFieldInLineEventOffset = unsafe.objectFieldOffset(LineEvent.class.getDeclaredField("lineNumber")); + + lineNumberFieldInCallBeforeEventOffset = unsafe.objectFieldOffset(CallBeforeEvent.class.getDeclaredField("lineNumber")); + ownerFieldInCallBeforeEventOffset = unsafe.objectFieldOffset(CallBeforeEvent.class.getDeclaredField("owner")); + nameFieldInCallBeforeEventOffset = unsafe.objectFieldOffset(CallBeforeEvent.class.getDeclaredField("name")); + descFieldInCallBeforeEventOffset = unsafe.objectFieldOffset(CallBeforeEvent.class.getDeclaredField("desc")); + throwExceptionFieldInCallThrowsEventOffset = unsafe.objectFieldOffset(CallThrowsEvent.class.getDeclaredField("throwException")); + } catch (Exception e) { + throw new Error(e); + } + } + + private LineEvent lineEvent = null; + private BeforeEvent beforeEvent = null; + private ReturnEvent returnEvent = null; + private ThrowsEvent throwsEvent = null; + private CallBeforeEvent callBeforeEvent = null; + private CallReturnEvent callReturnEvent = null; + private CallThrowsEvent callThrowsEvent = null; + private ImmediatelyThrowsEvent immediatelyThrowsEvent = null; + private ImmediatelyReturnEvent immediatelyReturnEvent = null; + + + public BeforeEvent makeBeforeEvent(final int processId, + final int invokeId, + final ClassLoader javaClassLoader, + final String javaClassName, + final String javaMethodName, + final String javaMethodDesc, + final Object target, + final Object[] argumentArray) { + if (null == beforeEvent) { + beforeEvent = new BeforeEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, null, null, null, null, null, null); + } + unsafe.putInt(beforeEvent, processIdFieldInInvokeEventOffset, processId); + unsafe.putInt(beforeEvent, invokeIdFieldInInvokeEventOffset, invokeId); + unsafe.putObject(beforeEvent, javaClassLoaderFieldInBeforeEventOffset, javaClassLoader); + unsafe.putObject(beforeEvent, javaClassNameFieldInBeforeEventOffset, javaClassName); + unsafe.putObject(beforeEvent, javaMethodNameFieldInBeforeEventOffset, javaMethodName); + unsafe.putObject(beforeEvent, javaMethodDescFieldInBeforeEventOffset, javaMethodDesc); + unsafe.putObject(beforeEvent, targetFieldInBeforeEventOffset, target); + unsafe.putObject(beforeEvent, argumentArrayFieldInBeforeEventOffset, argumentArray); + return beforeEvent; + } + + public ReturnEvent makeReturnEvent(final int processId, + final int invokeId, + final Object returnObj) { + if (null == returnEvent) { + returnEvent = new ReturnEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, null); + } + unsafe.putInt(returnEvent, processIdFieldInInvokeEventOffset, processId); + unsafe.putInt(returnEvent, invokeIdFieldInInvokeEventOffset, invokeId); + unsafe.putObject(returnEvent, objectFieldInReturnEventOffset, returnObj); + return returnEvent; + } + + public ImmediatelyReturnEvent makeImmediatelyReturnEvent(final int processId, + final int invokeId, + final Object returnObj) { + if (null == immediatelyReturnEvent) { + immediatelyReturnEvent = new ImmediatelyReturnEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, null); + } + unsafe.putInt(immediatelyReturnEvent, processIdFieldInInvokeEventOffset, processId); + unsafe.putInt(immediatelyReturnEvent, invokeIdFieldInInvokeEventOffset, invokeId); + unsafe.putObject(immediatelyReturnEvent, objectFieldInReturnEventOffset, returnObj); + return immediatelyReturnEvent; + } + + public ThrowsEvent makeThrowsEvent(final int processId, + final int invokeId, + final Throwable throwable) { + if (null == throwsEvent) { + throwsEvent = new ThrowsEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, null); + } + unsafe.putInt(throwsEvent, processIdFieldInInvokeEventOffset, processId); + unsafe.putInt(throwsEvent, invokeIdFieldInInvokeEventOffset, invokeId); + unsafe.putObject(throwsEvent, throwableFieldInThrowsEventOffset, throwable); + return throwsEvent; + } + + public ImmediatelyThrowsEvent makeImmediatelyThrowsEvent(final int processId, + final int invokeId, + final Throwable throwable) { + if (null == immediatelyThrowsEvent) { + immediatelyThrowsEvent = new ImmediatelyThrowsEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, null); + } + unsafe.putInt(immediatelyThrowsEvent, processIdFieldInInvokeEventOffset, processId); + unsafe.putInt(immediatelyThrowsEvent, invokeIdFieldInInvokeEventOffset, invokeId); + unsafe.putObject(immediatelyThrowsEvent, throwableFieldInThrowsEventOffset, throwable); + return immediatelyThrowsEvent; + } + + + public LineEvent makeLineEvent(final int processId, + final int invokeId, + final int lineNumber) { + if (null == lineEvent) { + lineEvent = new LineEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, -1); + } + unsafe.putInt(lineEvent, processIdFieldInInvokeEventOffset, processId); + unsafe.putInt(lineEvent, invokeIdFieldInInvokeEventOffset, invokeId); + unsafe.putInt(lineEvent, lineNumberFieldInLineEventOffset, lineNumber); + return lineEvent; + } + + public CallBeforeEvent makeCallBeforeEvent(final int processId, + final int invokeId, + final int lineNumber, + final String owner, + final String name, + final String desc) { + if (null == callBeforeEvent) { + callBeforeEvent = new CallBeforeEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, -1, null, null, null); + } + unsafe.putInt(callBeforeEvent, processIdFieldInInvokeEventOffset, processId); + unsafe.putInt(callBeforeEvent, invokeIdFieldInInvokeEventOffset, invokeId); + unsafe.putInt(callBeforeEvent, lineNumberFieldInCallBeforeEventOffset, lineNumber); + unsafe.putObject(callBeforeEvent, ownerFieldInCallBeforeEventOffset, owner); + unsafe.putObject(callBeforeEvent, nameFieldInCallBeforeEventOffset, name); + unsafe.putObject(callBeforeEvent, descFieldInCallBeforeEventOffset, desc); + return callBeforeEvent; + } + + public CallReturnEvent makeCallReturnEvent(final int processId, + final int invokeId) { + if (null == callReturnEvent) { + callReturnEvent = new CallReturnEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID); + } + unsafe.putInt(callReturnEvent, processIdFieldInInvokeEventOffset, processId); + unsafe.putInt(callReturnEvent, invokeIdFieldInInvokeEventOffset, invokeId); + return callReturnEvent; + } + + public CallThrowsEvent makeCallThrowsEvent(final int processId, + final int invokeId, + final String throwException) { + if (null == callThrowsEvent) { + callThrowsEvent = new CallThrowsEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, null); + } + unsafe.putInt(callThrowsEvent, processIdFieldInInvokeEventOffset, processId); + unsafe.putInt(callThrowsEvent, invokeIdFieldInInvokeEventOffset, invokeId); + unsafe.putObject(callThrowsEvent, throwExceptionFieldInCallThrowsEventOffset, throwException); + return callThrowsEvent; + } + + public void returnEvent(Event event) { + switch (event.type) { + case BEFORE: + unsafe.putObject(event, targetFieldInBeforeEventOffset, null); + unsafe.putObject(event, argumentArrayFieldInBeforeEventOffset, null); + break; + case IMMEDIATELY_THROWS: + case THROWS: + // FIXED #130 + // unsafe.putObject(event, throwableFieldInThrowsEventOffset, null); + unCaughtSetClassDeclaredJavaFieldValue(ThrowsEvent.class, "throwable", event, null); + break; + case IMMEDIATELY_RETURN: + case RETURN: + // FIXED #130 + // unsafe.putObject(event, objectFieldInReturnEventOffset, null); + unCaughtSetClassDeclaredJavaFieldValue(ReturnEvent.class, "object", event, null); + break; + } + } + +} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver.java index e3f11522..27cba37f 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver.java @@ -193,10 +193,6 @@ private void loadClassLoader() { @Override protected void onMethodEnter() { - - isMethodEnter = true; - mark(beginLabel); - codeLockForTracing.lock(new CodeLock.Block() { @Override public void code() { @@ -214,6 +210,8 @@ public void code() { storeArgArray(); pop(); processControl(); + isMethodEnter = true; + mark(beginLabel); } }); } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/CoreModuleManager.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/CoreModuleManager.java index 68b2a09b..6048ce80 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/CoreModuleManager.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/CoreModuleManager.java @@ -1,7 +1,7 @@ package com.alibaba.jvm.sandbox.core.manager; import com.alibaba.jvm.sandbox.api.ModuleException; -import com.alibaba.jvm.sandbox.core.domain.CoreModule; +import com.alibaba.jvm.sandbox.core.CoreModule; import java.util.Collection; @@ -22,9 +22,10 @@ public interface CoreModuleManager { /** * 沙箱重置 * + * @return this * @throws ModuleException 沙箱重置失败 */ - void reset() throws ModuleException; + CoreModuleManager reset() throws ModuleException; /** * 激活模块 @@ -79,5 +80,9 @@ public interface CoreModuleManager { */ CoreModule unload(CoreModule coreModule, boolean isIgnoreModuleException) throws ModuleException; + /** + * 卸载所有模块 + */ + void unloadAll(); } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/LoadedClassLoaderListener.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/LoadedClassLoaderListener.java new file mode 100644 index 00000000..c00ce74c --- /dev/null +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/LoadedClassLoaderListener.java @@ -0,0 +1,7 @@ +package com.alibaba.jvm.sandbox.core.manager; + +public interface LoadedClassLoaderListener { + + void onLoaded(ClassLoader loader); + +} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/ModuleLifeCycleEventBus.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/ModuleLifeCycleEventBus.java deleted file mode 100755 index af3940b0..00000000 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/ModuleLifeCycleEventBus.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.alibaba.jvm.sandbox.core.manager; - -import com.alibaba.jvm.sandbox.core.domain.CoreModule; - -/** - * 模块生命周期事件总线 - * Created by luanjia@taobao.com on 2017/2/3. - */ -public interface ModuleLifeCycleEventBus { - - /** - * 添加模块生命周期监听器 - *

被添加的监听器将按顺序完成生命周期的通知

- * - * @param lifeCycleEventListener 模块生命周期监听 - */ - void append(ModuleLifeCycleEventListener lifeCycleEventListener); - - /** - * 通知事件 - * - * @param coreModule 被通知的沙箱模块 - * @param event 通知事件类型 - */ - void fire(CoreModule coreModule, Event event); - - /** - * 模块事件类型 - */ - enum Event { - - /** - * 模块加载 - */ - LOAD, - - /** - * 模块加载完成 - */ - LOAD_COMPLETED, - - /** - * 模块卸载 - */ - UNLOAD, - - /** - * 模块激活 - */ - ACTIVE, - - /** - * 模块冻结 - */ - FROZE - } - - /** - * 模块生命周期事件监听器 - */ - interface ModuleLifeCycleEventListener { - - /** - * 模块生命周期事件到达 - * - * @param coreModule 被通知的沙箱模块 - * @param event 通知事件类型 - * @return TRUE : 继续保持监听,下次有事件通知时继续接收消息 - * FALSE : 放弃后续的监听 - */ - boolean onFire(CoreModule coreModule, Event event); - - } - -} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/ModuleResourceManager.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/ModuleResourceManager.java deleted file mode 100755 index 60d6002a..00000000 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/ModuleResourceManager.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.alibaba.jvm.sandbox.core.manager; - -import com.alibaba.jvm.sandbox.core.manager.ModuleLifeCycleEventBus.ModuleLifeCycleEventListener; - -import java.lang.ref.WeakReference; - -/** - * 模块可释放资源管理 - * 通常用来管理围绕Module所展开的http/websocket连接 - * Created by luanjia@taobao.com on 2017/2/4. - */ -public interface ModuleResourceManager extends ModuleLifeCycleEventListener { - - /** - * 在模块下追加一个可释放资源 - * - * @param uniqueId 模块ID - * @param resource 可释放资源封装 - * @param 资源实体 - * @return 资源实体本身 - */ - T append(String uniqueId, WeakResource resource); - - /** - * 在当前模块下移除一个可释放资源 - * - * @param uniqueId 模块ID - * @param target 待释放的资源实体 - * @param 资源实体 - */ - void remove(String uniqueId, T target); - - /** - * 弱引用资源 - * - * @param 资源类型 - */ - abstract class WeakResource { - - private final WeakReference weakReference; - - public WeakResource(T resource) { - this.weakReference = new WeakReference(resource); - } - - /** - * 释放资源 - */ - public abstract void release(); - - /** - * 获取资源实体 - * - * @return 资源实体 - */ - public T get() { - return weakReference.get(); - } - - } - -} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultConfigInfo.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultConfigInfo.java index 928ccf33..04f347bf 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultConfigInfo.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultConfigInfo.java @@ -12,9 +12,10 @@ /** * 默认配置信息实现 - * Created by luanjia@taobao.com on 2017/2/9. + * + * @author luanjia@taobao.com */ -public class DefaultConfigInfo implements ConfigInfo { +class DefaultConfigInfo implements ConfigInfo { private final CoreConfigure cfg; @@ -69,45 +70,45 @@ public String[] getUserModuleLibPaths() { @Override public boolean isEnableEventPool() { - return cfg.isEventPoolEnable(); + return false; } @Deprecated @Override public int getEventPoolKeyMin() { - return getEventPoolMaxIdlePerEvent(); + return 0; } @Deprecated @Override public int getEventPoolKeyMax() { - return getEventPoolMaxTotal(); + return 0; } @Deprecated @Override public int getEventPoolTotal() { - return getEventPoolMaxTotal(); + return 0; } @Override public int getEventPoolMaxTotal() { - return cfg.getEventPoolMaxTotal(); + return 0; } @Override public int getEventPoolMinIdlePerEvent() { - return cfg.getEventPoolMinIdlePerEvent(); + return 0; } @Override public int getEventPoolMaxIdlePerEvent() { - return cfg.getEventPoolMaxIdlePerEvent(); + return 0; } @Override public int getEventPoolMaxTotalPerEvent() { - return cfg.getEventPoolMaxTotalPerEvent(); + return 0; } @Override diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager.java index 7fd8dfeb..be6efc81 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager.java @@ -1,15 +1,17 @@ package com.alibaba.jvm.sandbox.core.manager.impl; import com.alibaba.jvm.sandbox.api.*; +import com.alibaba.jvm.sandbox.api.event.Event; import com.alibaba.jvm.sandbox.api.resource.*; import com.alibaba.jvm.sandbox.core.CoreConfigure; -import com.alibaba.jvm.sandbox.core.classloader.ModuleClassLoader; -import com.alibaba.jvm.sandbox.core.domain.CoreModule; +import com.alibaba.jvm.sandbox.core.CoreModule; +import com.alibaba.jvm.sandbox.core.CoreModule.ReleaseResource; +import com.alibaba.jvm.sandbox.core.classloader.ModuleJarClassLoader; import com.alibaba.jvm.sandbox.core.enhance.weaver.EventListenerHandlers; import com.alibaba.jvm.sandbox.core.manager.CoreLoadedClassDataSource; import com.alibaba.jvm.sandbox.core.manager.CoreModuleManager; -import com.alibaba.jvm.sandbox.core.manager.ModuleLifeCycleEventBus; import com.alibaba.jvm.sandbox.core.manager.ProviderManager; +import com.alibaba.jvm.sandbox.core.manager.impl.ModuleLibLoader.ModuleJarLoadCallback; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.reflect.FieldUtils; import org.slf4j.Logger; @@ -24,7 +26,7 @@ import java.util.concurrent.ConcurrentHashMap; import static com.alibaba.jvm.sandbox.api.ModuleException.ErrorCode.*; -import static com.alibaba.jvm.sandbox.core.manager.ModuleLifeCycleEventBus.Event.LOAD_COMPLETED; +import static com.alibaba.jvm.sandbox.core.manager.impl.DefaultCoreModuleManager.ModuleLifeCycleType.*; import static org.apache.commons.lang3.reflect.FieldUtils.writeField; /** @@ -37,9 +39,7 @@ public class DefaultCoreModuleManager implements CoreModuleManager { private final CoreConfigure cfg; private final Instrumentation inst; - private final ClassLoader sandboxClassLoader; private final CoreLoadedClassDataSource classDataSource; - private final ModuleLifeCycleEventBus moduleLifeCycleEventBus; private final ProviderManager providerManager; // 模块目录&文件集合 @@ -51,24 +51,18 @@ public class DefaultCoreModuleManager implements CoreModuleManager { /** * 模块模块管理 * - * @param cfg 模块核心配置 - * @param inst inst - * @param sandboxClassLoader 沙箱加载ClassLoader - * @param classDataSource 已加载类数据源 - * @param moduleLifeCycleEventBus 模块生命周期通知总线 - * @param providerManager 服务提供者管理器 + * @param cfg 模块核心配置 + * @param inst inst + * @param classDataSource 已加载类数据源 + * @param providerManager 服务提供者管理器 */ public DefaultCoreModuleManager(final CoreConfigure cfg, final Instrumentation inst, - final ClassLoader sandboxClassLoader, final CoreLoadedClassDataSource classDataSource, - final ModuleLifeCycleEventBus moduleLifeCycleEventBus, final ProviderManager providerManager) { this.cfg = cfg; this.inst = inst; - this.sandboxClassLoader = sandboxClassLoader; this.classDataSource = classDataSource; - this.moduleLifeCycleEventBus = moduleLifeCycleEventBus; this.providerManager = providerManager; // 初始化模块目录 @@ -76,13 +70,6 @@ public DefaultCoreModuleManager(final CoreConfigure cfg, new File[]{new File(cfg.getSystemModuleLibPath())}, cfg.getUserModuleLibFilesWithCache() ); - - // 初始化加载所有的模块 - try { - reset(); - } catch (Throwable cause) { - logger.warn("reset occur error when initializing.", cause); - } } private File[] mergeFileArray(File[] aFileArray, File[] bFileArray) { @@ -95,13 +82,13 @@ private File[] mergeFileArray(File[] aFileArray, File[] bFileArray) { /* * 通知模块生命周期 */ - private void callAndFireModuleLifeCycle(final CoreModule coreModule, final ModuleLifeCycleEventBus.Event e) throws ModuleException { + private void callAndFireModuleLifeCycle(final CoreModule coreModule, final ModuleLifeCycleType type) throws ModuleException { if (coreModule.getModule() instanceof ModuleLifecycle) { final ModuleLifecycle moduleLifecycle = (ModuleLifecycle) coreModule.getModule(); final String uniqueId = coreModule.getUniqueId(); - switch (e) { + switch (type) { - case LOAD: { + case MODULE_LOAD: { try { moduleLifecycle.onLoad(); } catch (Throwable throwable) { @@ -110,7 +97,7 @@ private void callAndFireModuleLifeCycle(final CoreModule coreModule, final Modul break; } - case UNLOAD: { + case MODULE_UNLOAD: { try { moduleLifecycle.onUnload(); } catch (Throwable throwable) { @@ -119,7 +106,7 @@ private void callAndFireModuleLifeCycle(final CoreModule coreModule, final Modul break; } - case ACTIVE: { + case MODULE_ACTIVE: { try { moduleLifecycle.onActive(); } catch (Throwable throwable) { @@ -128,7 +115,7 @@ private void callAndFireModuleLifeCycle(final CoreModule coreModule, final Modul break; } - case FROZE: { + case MODULE_FROZEN: { try { moduleLifecycle.onFrozen(); } catch (Throwable throwable) { @@ -142,7 +129,7 @@ private void callAndFireModuleLifeCycle(final CoreModule coreModule, final Modul // 这里要对LOAD_COMPLETED事件做特殊处理 // 因为这个事件处理失败不会影响模块变更行为,只做简单的日志处理 - if (e == LOAD_COMPLETED + if (type == MODULE_LOAD_COMPLETED && coreModule.getModule() instanceof LoadCompleted) { try { ((LoadCompleted) coreModule.getModule()).loadCompleted(); @@ -151,8 +138,6 @@ private void callAndFireModuleLifeCycle(final CoreModule coreModule, final Modul } } - // fire the bus - moduleLifeCycleEventBus.fire(coreModule, e); } /** @@ -170,7 +155,7 @@ private void callAndFireModuleLifeCycle(final CoreModule coreModule, final Modul private synchronized void load(final String uniqueId, final Module module, final File moduleJarFile, - final ModuleClassLoader moduleClassLoader) throws ModuleException { + final ModuleJarClassLoader moduleClassLoader) throws ModuleException { if (loadedModuleBOMap.containsKey(uniqueId)) { logger.debug("module already loaded. module={};", uniqueId); @@ -189,11 +174,10 @@ private synchronized void load(final String uniqueId, // 注入@Resource资源 injectResourceOnLoadIfNecessary(coreModule); - // 通知生命周期:模块加载开始 - callAndFireModuleLifeCycle(coreModule, ModuleLifeCycleEventBus.Event.LOAD); + callAndFireModuleLifeCycle(coreModule, MODULE_LOAD); // 设置为已经加载 - coreModule.setLoaded(true); + coreModule.markLoaded(true); // 如果模块标记了加载时自动激活,则需要在加载完成之后激活模块 markActiveOnLoadIfNecessary(coreModule); @@ -202,7 +186,7 @@ private synchronized void load(final String uniqueId, loadedModuleBOMap.put(uniqueId, coreModule); // 通知生命周期,模块加载完成 - callAndFireModuleLifeCycle(coreModule, LOAD_COMPLETED); + callAndFireModuleLifeCycle(coreModule, MODULE_LOAD_COMPLETED); } @@ -224,14 +208,26 @@ private void injectResourceOnLoadIfNecessary(final CoreModule coreModule) throws // ModuleEventWatcher对象注入 else if (ModuleEventWatcher.class.isAssignableFrom(fieldType)) { - final ModuleEventWatcher moduleEventWatcher = new DefaultModuleEventWatcher( + final ModuleEventWatcher moduleEventWatcher = coreModule.append(new ReleaseResource(new DefaultModuleEventWatcher( inst, classDataSource, coreModule, cfg.isEnableUnsafe(), cfg.getNamespace() - ); - moduleLifeCycleEventBus.append((DefaultModuleEventWatcher) moduleEventWatcher); + )) { + @Override + public void release() { + logger.info("release all SandboxClassFileTransformer for module={}", coreModule.getUniqueId()); + final ModuleEventWatcher moduleEventWatcher = get(); + if (null != moduleEventWatcher) { + for (final SandboxClassFileTransformer sandboxClassFileTransformer + : new ArrayList(coreModule.getSandboxClassFileTransformers())) { + moduleEventWatcher.delete(sandboxClassFileTransformer.getWatchId()); + } + } + } + }); + writeField( resourceField, module, @@ -275,7 +271,32 @@ else if (EventMonitor.class.isAssignableFrom(fieldType)) { writeField( resourceField, module, - new DefaultEventMonitor(), + new EventMonitor() { + @Override + public EventPoolInfo getEventPoolInfo() { + return new EventPoolInfo() { + @Override + public int getNumActive() { + return 0; + } + + @Override + public int getNumActive(Event.Type type) { + return 0; + } + + @Override + public int getNumIdle() { + return 0; + } + + @Override + public int getNumIdle(Event.Type type) { + return 0; + } + }; + } + }, true ); } @@ -284,9 +305,9 @@ else if (EventMonitor.class.isAssignableFrom(fieldType)) { else { logger.warn("module inject @Resource ignored: field not found. module={};class={};type={};field={};", coreModule.getUniqueId(), - resourceField.getName(), coreModule.getModule().getClass().getName(), - fieldType.getName() + fieldType.getName(), + resourceField.getName() ); } @@ -333,7 +354,7 @@ public synchronized CoreModule unload(final CoreModule coreModule, // 通知生命周期 try { - callAndFireModuleLifeCycle(coreModule, ModuleLifeCycleEventBus.Event.UNLOAD); + callAndFireModuleLifeCycle(coreModule, MODULE_UNLOAD); } catch (ModuleException meCause) { if (isIgnoreModuleException) { logger.warn("unload module occur error, ignored. module={};class={};code={};", @@ -351,14 +372,34 @@ public synchronized CoreModule unload(final CoreModule coreModule, loadedModuleBOMap.remove(coreModule.getUniqueId()); // 标记模块为:已卸载 - coreModule.setLoaded(false); + coreModule.markLoaded(false); + + // 释放所有可释放资源 + coreModule.releaseAll(); // 尝试关闭ClassLoader - closeModuleClassLoaderIfNecessary(coreModule.getLoader()); + closeModuleJarClassLoaderIfNecessary(coreModule.getLoader()); return coreModule; } + @Override + public void unloadAll() { + + logger.info("force unloading all loaded modules:{}", loadedModuleBOMap.keySet()); + + // 强制卸载所有模块 + for (final CoreModule coreModule : new ArrayList(loadedModuleBOMap.values())) { + try { + unload(coreModule, true); + } catch (ModuleException cause) { + // 强制卸载不可能出错,这里不对外继续抛出任何异常 + logger.warn("force unloading module occur error! module={};", coreModule.getUniqueId(), cause); + } + } + + } + @Override public synchronized void active(final CoreModule coreModule) throws ModuleException { @@ -375,7 +416,7 @@ public synchronized void active(final CoreModule coreModule) throws ModuleExcept ); // 通知生命周期 - callAndFireModuleLifeCycle(coreModule, ModuleLifeCycleEventBus.Event.ACTIVE); + callAndFireModuleLifeCycle(coreModule, MODULE_ACTIVE); // 激活所有监听器 for (final SandboxClassFileTransformer sandboxClassFileTransformer : coreModule.getSandboxClassFileTransformers()) { @@ -387,7 +428,7 @@ public synchronized void active(final CoreModule coreModule) throws ModuleExcept } // 标记模块为:已激活 - coreModule.setActivated(true); + coreModule.markActivated(true); } @Override @@ -408,7 +449,7 @@ public synchronized void frozen(final CoreModule coreModule, // 通知生命周期 try { - callAndFireModuleLifeCycle(coreModule, ModuleLifeCycleEventBus.Event.FROZE); + callAndFireModuleLifeCycle(coreModule, MODULE_FROZEN); } catch (ModuleException meCause) { if (isIgnoreModuleException) { logger.warn("frozen module occur error, ignored. module={};class={};code={};", @@ -429,7 +470,7 @@ public synchronized void frozen(final CoreModule coreModule, } // 标记模块为:已冻结 - coreModule.setActivated(false); + coreModule.markActivated(false); } @Override @@ -472,7 +513,7 @@ private boolean isSystemModule(final File child) { /** * 用户模块文件加载回调 */ - final private class InnerModuleJarLoadCallback implements ModuleJarLoader.ModuleJarLoadCallback { + final private class InnerModuleJarLoadCallback implements ModuleJarLoadCallback { @Override public void onLoad(File moduleJarFile) throws Throwable { providerManager.loading(moduleJarFile); @@ -488,7 +529,7 @@ public void onLoad(final String uniqueId, final Class moduleClass, final Module module, final File moduleJarFile, - final ModuleClassLoader moduleClassLoader) throws Throwable { + final ModuleJarClassLoader moduleClassLoader) throws Throwable { // 如果之前已经加载过了相同ID的模块,则放弃当前模块的加载 if (loadedModuleBOMap.containsKey(uniqueId)) { @@ -517,6 +558,8 @@ public void onLoad(final String uniqueId, moduleClass, moduleClassLoader ); + + // 这里进行真正的模块加载 load(uniqueId, module, moduleJarFile, moduleClassLoader); } } @@ -531,43 +574,44 @@ public synchronized void flush(final boolean isForce) throws ModuleException { } @Override - public synchronized void reset() throws ModuleException { - + public synchronized CoreModuleManager reset() throws ModuleException { + logger.info("resetting all loaded modules:{}", loadedModuleBOMap.keySet()); // 1. 强制卸载所有模块 - for (final CoreModule coreModule : new ArrayList(loadedModuleBOMap.values())) { - unload(coreModule, true); - } + unloadAll(); // 2. 加载所有模块 for (final File moduleLibDir : moduleLibDirArray) { // 用户模块加载目录,加载用户模块目录下的所有模块 // 对模块访问权限进行校验 - if (moduleLibDir.exists() - && moduleLibDir.canRead()) { - new ModuleJarLoader(moduleLibDir, cfg.getLaunchMode(), sandboxClassLoader) - .load(new InnerModuleJarLoadCallback(), new InnerModuleLoadCallback()); + if (moduleLibDir.exists() && moduleLibDir.canRead()) { + new ModuleLibLoader(moduleLibDir, cfg.getLaunchMode()) + .load( + new InnerModuleJarLoadCallback(), + new InnerModuleLoadCallback() + ); } else { logger.warn("module-lib not access, ignore flush load this lib. path={}", moduleLibDir); } } + return this; } /** - * 关闭Module的ClassLoader - * 如ModuleClassLoader所加载上来的所有模块都已经被卸载,则该ClassLoader需要主动进行关闭 + * 关闭ModuleJarClassLoader + * 如ModuleJarClassLoader所加载上来的所有模块都已经被卸载,则该ClassLoader需要主动进行关闭 * * @param loader 需要被关闭的ClassLoader */ - private void closeModuleClassLoaderIfNecessary(final ClassLoader loader) { + private void closeModuleJarClassLoaderIfNecessary(final ClassLoader loader) { - if (!(loader instanceof ModuleClassLoader)) { + if (!(loader instanceof ModuleJarClassLoader)) { return; } - // 查找已经注册的模块中是否仍然还包含有ModuleClassLoader的引用 + // 查找已经注册的模块中是否仍然还包含有ModuleJarClassLoader的引用 boolean hasRef = false; for (final CoreModule coreModule : loadedModuleBOMap.values()) { if (loader == coreModule.getLoader()) { @@ -577,8 +621,8 @@ private void closeModuleClassLoaderIfNecessary(final ClassLoader loader) { } if (!hasRef) { - logger.info("module-classloader will be close: all module unloaded.", loader); - ((ModuleClassLoader) loader).closeIfPossible(); + logger.info("ModuleJarClassLoader will be close: all module unloaded.", loader); + ((ModuleJarClassLoader) loader).closeIfPossible(); } } @@ -629,7 +673,7 @@ private void softFlush() { // 2. 找出所有待卸载的已加载用户模块 for (final CoreModule coreModule : loadedModuleBOMap.values()) { - final ModuleClassLoader moduleClassLoader = coreModule.getLoader(); + final ModuleJarClassLoader moduleJarClassLoader = coreModule.getLoader(); // 如果是系统模块目录则跳过 if (isOptimisticDirectoryContainsFile(systemModuleLibDir, coreModule.getJarFile())) { @@ -641,10 +685,10 @@ private void softFlush() { } // 如果CRC32已经在这次待加载的集合中,则说明这个文件没有变动,忽略 - if (checksumCRC32s.contains(moduleClassLoader.getChecksumCRC32())) { + if (checksumCRC32s.contains(moduleJarClassLoader.getChecksumCRC32())) { logger.info("soft-flushing module: module-jar already loaded, ignored. module-jar={};CRC32={};", coreModule.getJarFile(), - moduleClassLoader.getChecksumCRC32() + moduleJarClassLoader.getChecksumCRC32() ); continue; } @@ -662,7 +706,7 @@ private void softFlush() { // 4. 加载add for (final File jarFile : appendJarFiles) { - new ModuleJarLoader(jarFile, cfg.getLaunchMode(), sandboxClassLoader) + new ModuleLibLoader(jarFile, cfg.getLaunchMode()) .load(new InnerModuleJarLoadCallback(), new InnerModuleLoadCallback()); } } catch (Throwable cause) { @@ -716,7 +760,7 @@ private void forceFlush() throws ModuleException { if (userModuleLibDir.exists() && userModuleLibDir.canRead()) { logger.info("force-flush modules: module-lib={}", userModuleLibDir); - new ModuleJarLoader(userModuleLibDir, cfg.getLaunchMode(), sandboxClassLoader) + new ModuleLibLoader(userModuleLibDir, cfg.getLaunchMode()) .load(new InnerModuleJarLoadCallback(), new InnerModuleLoadCallback()); } else { logger.warn("force-flush modules: module-lib can not access, will be ignored. module-lib={}", userModuleLibDir); @@ -725,4 +769,35 @@ private void forceFlush() throws ModuleException { } + /** + * 模块生命周期类型 + */ + enum ModuleLifeCycleType { + + /** + * 模块加载 + */ + MODULE_LOAD, + + /** + * 模块卸载 + */ + MODULE_UNLOAD, + + /** + * 模块激活 + */ + MODULE_ACTIVE, + + /** + * 模块冻结 + */ + MODULE_FROZEN, + + /** + * 模块加载完成 + */ + MODULE_LOAD_COMPLETED + } + } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultEventMonitor.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultEventMonitor.java deleted file mode 100644 index cf938031..00000000 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultEventMonitor.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.alibaba.jvm.sandbox.core.manager.impl; - -import com.alibaba.jvm.sandbox.api.event.Event; -import com.alibaba.jvm.sandbox.api.resource.EventMonitor; -import com.alibaba.jvm.sandbox.core.enhance.weaver.EventListenerHandlers; -import com.alibaba.jvm.sandbox.core.util.EventPool; - -/** - * 事件监控器实现 - */ -class DefaultEventMonitor implements EventMonitor { - - @Override - public EventPoolInfo getEventPoolInfo() { - - final EventPool pool = EventListenerHandlers.getSingleton().getEventPool(); - - return new EventPoolInfo() { - @Override - public int getNumActive() { - return pool.getNumActive(); - } - - @Override - public int getNumActive(Event.Type type) { - return pool.getNumActive(type); - } - - @Override - public int getNumIdle() { - return pool.getNumIdle(); - } - - @Override - public int getNumIdle(Event.Type type) { - return pool.getNumIdle(type); - } - }; - } - -} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultLoadedClassDataSource.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultLoadedClassDataSource.java index b9b542dc..571c47db 100644 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultLoadedClassDataSource.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultLoadedClassDataSource.java @@ -1,8 +1,8 @@ package com.alibaba.jvm.sandbox.core.manager.impl; import com.alibaba.jvm.sandbox.api.filter.Filter; -import com.alibaba.jvm.sandbox.core.CoreConfigure; import com.alibaba.jvm.sandbox.core.manager.CoreLoadedClassDataSource; +import com.alibaba.jvm.sandbox.core.manager.LoadedClassLoaderListener; import com.alibaba.jvm.sandbox.core.util.matcher.ExtFilterMatcher; import com.alibaba.jvm.sandbox.core.util.matcher.Matcher; import com.alibaba.jvm.sandbox.core.util.matcher.UnsupportedMatcher; @@ -24,12 +24,14 @@ public class DefaultLoadedClassDataSource implements CoreLoadedClassDataSource { private final Logger logger = LoggerFactory.getLogger(getClass()); private final Instrumentation inst; - private final CoreConfigure cfg; + private final boolean isEnableUnsafe; + private final List loadedClassLoaderListeners + = new ArrayList(); public DefaultLoadedClassDataSource(final Instrumentation inst, - final CoreConfigure cfg) { + final boolean isEnableUnsafe) { this.inst = inst; - this.cfg = cfg; + this.isEnableUnsafe = isEnableUnsafe; } @Override @@ -84,12 +86,12 @@ private List> find(final Matcher matcher, // 过滤掉对于JVM认为不可修改的类 if (isRemoveUnsupported && !inst.isModifiableClass(clazz)) { - logger.debug("remove from findForReTransform, because class:{} is unModifiable", clazz.getName()); + // logger.debug("remove from findForReTransform, because class:{} is unModifiable", clazz.getName()); continue; } try { if (isRemoveUnsupported) { - if (new UnsupportedMatcher(clazz.getClassLoader(), cfg.isEnableUnsafe()) + if (new UnsupportedMatcher(clazz.getClassLoader(), isEnableUnsafe) .and(matcher) .matching(ClassStructureFactory.createClassStructure(clazz)) .isMatched()) { diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleController.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleController.java index bd6c26b0..725f0148 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleController.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleController.java @@ -2,7 +2,7 @@ import com.alibaba.jvm.sandbox.api.ModuleException; import com.alibaba.jvm.sandbox.api.resource.ModuleController; -import com.alibaba.jvm.sandbox.core.domain.CoreModule; +import com.alibaba.jvm.sandbox.core.CoreModule; import com.alibaba.jvm.sandbox.core.manager.CoreModuleManager; /** diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleEventWatcher.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleEventWatcher.java index cedc58a3..9ea0d795 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleEventWatcher.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleEventWatcher.java @@ -5,10 +5,9 @@ import com.alibaba.jvm.sandbox.api.listener.EventListener; import com.alibaba.jvm.sandbox.api.listener.ext.EventWatchCondition; import com.alibaba.jvm.sandbox.api.resource.ModuleEventWatcher; -import com.alibaba.jvm.sandbox.core.domain.CoreModule; +import com.alibaba.jvm.sandbox.core.CoreModule; import com.alibaba.jvm.sandbox.core.enhance.weaver.EventListenerHandlers; import com.alibaba.jvm.sandbox.core.manager.CoreLoadedClassDataSource; -import com.alibaba.jvm.sandbox.core.manager.ModuleLifeCycleEventBus; import com.alibaba.jvm.sandbox.core.util.Sequencer; import com.alibaba.jvm.sandbox.core.util.matcher.ExtFilterMatcher; import com.alibaba.jvm.sandbox.core.util.matcher.GroupMatcher; @@ -18,16 +17,20 @@ import org.slf4j.LoggerFactory; import java.lang.instrument.Instrumentation; -import java.util.*; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; import static com.alibaba.jvm.sandbox.api.filter.ExtFilter.ExtFilterFactory.make; import static com.alibaba.jvm.sandbox.core.util.matcher.ExtFilterMatcher.toOrGroupMatcher; /** * 默认事件观察者实现 - * Created by luanjia@taobao.com on 2017/2/23. + * + * @author luanjia@taobao.com */ -public class DefaultModuleEventWatcher implements ModuleEventWatcher, ModuleLifeCycleEventBus.ModuleLifeCycleEventListener { +public class DefaultModuleEventWatcher implements ModuleEventWatcher { private final Logger logger = LoggerFactory.getLogger(getClass()); @@ -38,7 +41,7 @@ public class DefaultModuleEventWatcher implements ModuleEventWatcher, ModuleLife private final String namespace; // 观察ID序列生成器 - private final Sequencer watchIdSequencer = new Sequencer(1000); + private final Sequencer watchIdSequencer = new Sequencer(); DefaultModuleEventWatcher(final Instrumentation inst, final CoreLoadedClassDataSource classDataSource, @@ -92,72 +95,51 @@ private void reTransformClasses(final int watchId, } if (logger.isDebugEnabled()) { - logger.debug("reTransformClasses:{};module[id:{}];watch[Id:{}];", + logger.debug("reTransformClasses={};module={};watch={};", waitingReTransformClasses, coreModule.getUniqueId(), watchId); } - - // 如果不需要进行进度汇报,则可以进行批量形变 - boolean batchReTransformSuccess = true; - if (null == progress) { + int index = 0; + for (final Class waitingReTransformClass : waitingReTransformClasses) { + index++; try { - inst.retransformClasses(waitingReTransformClasses.toArray(new Class[waitingReTransformClasses.size()])); - logger.info("module[id:{}] watch[id:{}] batch reTransform classes[count:{}] success.", - coreModule.getUniqueId(), watchId, waitingReTransformClasses.size()); - } catch (Throwable e) { - logger.warn("module[id:{}] watch[id:{}] batch reTransform classes[count:{}] failed.", - coreModule.getUniqueId(), watchId, waitingReTransformClasses.size(), e); - batchReTransformSuccess = false; - } - } - - // 只有两种情况需要进行逐个形变 - // 1. 需要进行形变进度报告,则只能一个个进行形变 - // 2. 批量形变失败,需要转换为单个形变,以观察具体是哪个形变失败 - if (!batchReTransformSuccess - || null != progress) { - int index = 0; - for (final Class waitingReTransformClass : waitingReTransformClasses) { - index++; - try { - if (null != progress) { - try { - progress.progressOnSuccess(waitingReTransformClass, index); - } catch (Throwable cause) { - // 在进行进度汇报的过程中抛出异常,直接进行忽略,因为不影响形变的主体流程 - // 仅仅只是一个汇报作用而已 - logger.warn("module[id:{}] watch[id:{}] on class:{} report progressOnSuccess occur exception at index:{},total:{},class:{};", - coreModule.getUniqueId(), watchId, waitingReTransformClass, - index - 1, total, - cause - ); - } + if (null != progress) { + try { + progress.progressOnSuccess(waitingReTransformClass, index); + } catch (Throwable cause) { + // 在进行进度汇报的过程中抛出异常,直接进行忽略,因为不影响形变的主体流程 + // 仅仅只是一个汇报作用而已 + logger.warn("watch={} in module={} on {} report progressOnSuccess occur exception at index={};total={};", + watchId, coreModule.getUniqueId(), waitingReTransformClass, + index - 1, total, + cause + ); } - inst.retransformClasses(waitingReTransformClass); - logger.info("module[id:{}] watch[id:{}] single reTransform class:{} success, at index:{},total:{};", - coreModule.getUniqueId(), watchId, waitingReTransformClass, - index - 1, total - ); - } catch (Throwable causeOfReTransform) { - logger.warn("module[id:{}] watch[id:{}] single reTransform class:{} failed, at index:{},total:{}. ignore this class.", - coreModule.getUniqueId(), watchId, waitingReTransformClass, - index - 1, total, - causeOfReTransform - ); - if (null != progress) { - try { - progress.progressOnFailed(waitingReTransformClass, index, causeOfReTransform); - } catch (Throwable cause) { - logger.warn("module[id:{}] watch[id:{}] on class:{} report progressOnFailed occur exception, at index:{},total:{};", - coreModule.getUniqueId(), watchId, waitingReTransformClass, - index - 1, total, - cause - ); - } + } + inst.retransformClasses(waitingReTransformClass); + logger.info("watch={} in module={} single reTransform {} success, at index={};total={};", + watchId, coreModule.getUniqueId(), waitingReTransformClass, + index - 1, total + ); + } catch (Throwable causeOfReTransform) { + logger.warn("watch={} in module={} single reTransform {} failed, at index={};total={}. ignore this class.", + watchId, coreModule.getUniqueId(), waitingReTransformClass, + index - 1, total, + causeOfReTransform + ); + if (null != progress) { + try { + progress.progressOnFailed(waitingReTransformClass, index, causeOfReTransform); + } catch (Throwable cause) { + logger.warn("watch={} in module={} on {} report progressOnFailed occur exception, at index={};total={};", + watchId, coreModule.getUniqueId(), waitingReTransformClass, + index - 1, total, + cause + ); } } - }//for - } + } + }//for } @@ -202,8 +184,11 @@ private int watch(final Matcher matcher, // 查找需要渲染的类集合 final List> waitingReTransformClasses = classDataSource.findForReTransform(matcher); - logger.info("{} watch[id:{}] found classes:{} in loaded for watch(ing).", - coreModule, watchId, waitingReTransformClasses.size()); + logger.info("watch={} in module={} found {} classes for watch(ing).", + watchId, + coreModule.getUniqueId(), + waitingReTransformClasses.size() + ); int cCnt = 0, mCnt = 0; @@ -270,8 +255,11 @@ public void delete(final int watcherId, final List> waitingReTransformClasses = classDataSource.findForReTransform( new GroupMatcher.Or(waitingRemoveMatcherSet.toArray(new Matcher[0])) ); - logger.info("{} found classes:{} in loaded for delete.", - coreModule, waitingReTransformClasses.size()); + logger.info("watch={} in module={} found {} classes for delete.", + watcherId, + coreModule.getUniqueId(), + waitingReTransformClasses.size() + ); beginProgress(progress, waitingReTransformClasses.size()); try { @@ -299,7 +287,7 @@ public void watching(final Filter filter, final WatchCallback watchCb, final Progress dProgress, final Event.Type... eventType) throws Throwable { - final int watchId = watch(filter, listener, wProgress, eventType); + final int watchId = watch(new ExtFilterMatcher(make(filter)), listener, wProgress, eventType); try { watchCb.watchCompleted(); } finally { @@ -307,23 +295,4 @@ public void watching(final Filter filter, } } - @Override - public boolean onFire(final CoreModule coreModule, - final ModuleLifeCycleEventBus.Event event) { - - if (this.coreModule == coreModule - && event == ModuleLifeCycleEventBus.Event.UNLOAD) { - // 是当前模块的卸载事件,需要主动清理掉之前的埋点 - for (final SandboxClassFileTransformer transformer : new ArrayList(coreModule.getSandboxClassFileTransformers())) { - logger.info("delete watch[id={}] by module[id={};] unload.", - transformer.getWatchId(), coreModule.getUniqueId()); - delete(transformer.getWatchId()); - } - // 当前模块都卸载了,我还留着做啥... - return false; - } - - // 不是当前模块的卸载事件,继续保持监听 - return true; - } } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleLifeCycleEventBus.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleLifeCycleEventBus.java deleted file mode 100755 index bc17b6c0..00000000 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleLifeCycleEventBus.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.alibaba.jvm.sandbox.core.manager.impl; - -import com.alibaba.jvm.sandbox.core.domain.CoreModule; -import com.alibaba.jvm.sandbox.core.manager.ModuleLifeCycleEventBus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Iterator; -import java.util.LinkedList; - -/** - * 默认模块生命周期实现 - * Created by luanjia@taobao.com on 2017/2/3. - */ -public class DefaultModuleLifeCycleEventBus implements ModuleLifeCycleEventBus { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final LinkedList moduleLifeCycleEventListeners - = new LinkedList(); - - @Override - public void append(ModuleLifeCycleEventListener lifeCycleEventListener) { - moduleLifeCycleEventListeners.add(lifeCycleEventListener); - } - - @Override - public void fire(CoreModule coreModule, Event event) { - - logger.info("firing module-event: event={};module={};", event, coreModule.getUniqueId()); - final Iterator listenerIt = moduleLifeCycleEventListeners.iterator(); - while (listenerIt.hasNext()) { - - final ModuleLifeCycleEventListener moduleLifeCycleEventListener = listenerIt.next(); - try { - if (!moduleLifeCycleEventListener.onFire(coreModule, event)) { - // 监听器返回FALSE,说明监听器主动放弃后续的消息监听 - listenerIt.remove(); - logger.debug("fired module-event by once. event={};module={};listener={};", - event, - coreModule.getUniqueId(), - moduleLifeCycleEventListener - ); - } - } catch (Throwable cause) { - logger.warn("fire module-event failed, event={};module={};listener={};", - event, - coreModule.getUniqueId(), - moduleLifeCycleEventListener, - cause - ); - } - - } - - } - -} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleManager.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleManager.java index b953e153..f37eaf29 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleManager.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleManager.java @@ -3,7 +3,7 @@ import com.alibaba.jvm.sandbox.api.Module; import com.alibaba.jvm.sandbox.api.ModuleException; import com.alibaba.jvm.sandbox.api.resource.ModuleManager; -import com.alibaba.jvm.sandbox.core.domain.CoreModule; +import com.alibaba.jvm.sandbox.core.CoreModule; import com.alibaba.jvm.sandbox.core.manager.CoreModuleManager; import java.io.File; diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleResourceManager.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleResourceManager.java deleted file mode 100755 index 73dfd915..00000000 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleResourceManager.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.alibaba.jvm.sandbox.core.manager.impl; - -import com.alibaba.jvm.sandbox.core.domain.CoreModule; -import com.alibaba.jvm.sandbox.core.manager.ModuleLifeCycleEventBus; -import com.alibaba.jvm.sandbox.core.manager.ModuleLifeCycleEventBus.ModuleLifeCycleEventListener; -import com.alibaba.jvm.sandbox.core.manager.ModuleResourceManager; -import org.apache.commons.collections.CollectionUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -/** - * 默认实现自动释放连接释放管理 - * Created by luanjia@taobao.com on 2017/2/4. - */ -public class DefaultModuleResourceManager implements ModuleResourceManager, ModuleLifeCycleEventListener { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final Map>> moduleResourceListMapping - = new HashMap>>(); - - @Override - public synchronized T append(String uniqueId, WeakResource resource) { - if (null == resource - || null == resource.get()) { - return null; - } - final List> moduleResourceList; - if (moduleResourceListMapping.containsKey(uniqueId)) { - moduleResourceList = moduleResourceListMapping.get(uniqueId); - } else { - moduleResourceListMapping.put(uniqueId, moduleResourceList - = new ArrayList>()); - } - moduleResourceList.add(resource); - logger.debug("append resource={} in module[id={};]", resource.get(), uniqueId); - return resource.get(); - } - - @Override - public void remove(String uniqueId, T target) { - if (null == target) { - return; - } - synchronized (this) { - final List> moduleResourceList = moduleResourceListMapping.get(uniqueId); - if (null == moduleResourceList) { - return; - } - final Iterator> resourceRefIt = moduleResourceList.iterator(); - while (resourceRefIt.hasNext()) { - final WeakResource resourceRef = resourceRefIt.next(); - - // 删除掉无效的资源 - if (null == resourceRef) { - resourceRefIt.remove(); - logger.debug("remove illegal resource in module[id={};]", uniqueId); - continue; - } - - // 删除掉已经被GC掉的资源 - if (null == resourceRef.get()) { - resourceRefIt.remove(); - logger.debug("remove empty resource in module[id={};]", uniqueId); - continue; - } - - if (target.equals(resourceRef.get())) { - resourceRefIt.remove(); - logger.debug("remove resource={} in module[id={};]", resourceRef.get(), uniqueId); - } - }//while - }//sync - } - - @Override - public boolean onFire(CoreModule coreModule, ModuleLifeCycleEventBus.Event event) { - - // 只有模块卸载的时候才需要关注处理 - if (event != ModuleLifeCycleEventBus.Event.UNLOAD) { - return true; - } - - final String uniqueId = coreModule.getUniqueId(); - final List> moduleResourceList; - synchronized (this) { - moduleResourceList = moduleResourceListMapping.remove(uniqueId); - } - if (CollectionUtils.isEmpty(moduleResourceList)) { - logger.debug("module[id={};] mapping resources was empty.", uniqueId); - return true; - } else { - logger.info("module[id={};] is unloading, will release {} resources.", uniqueId, moduleResourceList.size()); - } - - for (final WeakResource resource : moduleResourceList) { - if (null == resource - || null == resource.get()) { - continue; - } - try { - resource.release(); - logger.info("module[id={};] is unloading, resource={} was closed.", uniqueId, resource); - } catch (Throwable cause) { - logger.warn("module[id={};] is unloading, resource={} closing failed.", - uniqueId, resource, cause); - } - } - return true; - - } - -} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultProviderManager.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultProviderManager.java index 98d57f80..645bf616 100644 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultProviderManager.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/DefaultProviderManager.java @@ -33,18 +33,16 @@ public class DefaultProviderManager implements ProviderManager { private final Collection moduleLoadingChains = new ArrayList(); private final CoreConfigure cfg; - public DefaultProviderManager(final CoreConfigure cfg, - final ClassLoader sandboxClassLoader) { + public DefaultProviderManager(final CoreConfigure cfg) { this.cfg = cfg; try { - init(cfg, sandboxClassLoader); + init(cfg); } catch (Throwable cause) { logger.warn("loading sandbox's provider-lib[{}] failed.", cfg.getProviderLibPath(), cause); } } - private void init(final CoreConfigure cfg, - final ClassLoader sandboxClassLoader) { + private void init(final CoreConfigure cfg) { final File providerLibDir = new File(cfg.getProviderLibPath()); if (!providerLibDir.exists() || !providerLibDir.canRead()) { @@ -55,7 +53,7 @@ private void init(final CoreConfigure cfg, for (final File providerJarFile : FileUtils.listFiles(providerLibDir, new String[]{"jar"}, false)) { try { - final ProviderClassLoader providerClassLoader = new ProviderClassLoader(providerJarFile, sandboxClassLoader); + final ProviderClassLoader providerClassLoader = new ProviderClassLoader(providerJarFile, getClass().getClassLoader()); // load ModuleJarLoadingChain inject(moduleJarLoadingChains, ModuleJarLoadingChain.class, providerClassLoader, providerJarFile); diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader.java old mode 100755 new mode 100644 index 20dacfa2..c84a10a8 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader.java @@ -2,225 +2,139 @@ import com.alibaba.jvm.sandbox.api.Information; import com.alibaba.jvm.sandbox.api.Module; -import com.alibaba.jvm.sandbox.core.classloader.ModuleClassLoader; +import com.alibaba.jvm.sandbox.core.classloader.ModuleJarClassLoader; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; -import java.util.*; +import java.io.IOException; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.ServiceLoader; +import java.util.Set; -import static org.apache.commons.io.FileUtils.convertFileCollectionToFileArray; -import static org.apache.commons.io.FileUtils.listFiles; - -/** - * 模块加载器 - * 用于从${module.lib}中加载所有的沙箱模块 - * Created by luanjia@taobao.com on 2016/11/17. - */ class ModuleJarLoader { private final Logger logger = LoggerFactory.getLogger(getClass()); - // 模块加载目录 - private final File moduleLibDir; + // 等待加载的模块jar文件 + private final File moduleJarFile; // 沙箱加载模式 private final Information.Mode mode; - // 沙箱加载ClassLoader - private final ClassLoader sandboxClassLoader; - - ModuleJarLoader(final File moduleLibDir, - final Information.Mode mode, - final ClassLoader sandboxClassLoader) { - this.moduleLibDir = moduleLibDir; + ModuleJarLoader(final File moduleJarFile, + final Information.Mode mode) { + this.moduleJarFile = moduleJarFile; this.mode = mode; - this.sandboxClassLoader = sandboxClassLoader; } - private File[] toModuleJarFileArray() { - if (moduleLibDir.exists() - && moduleLibDir.isFile() - && moduleLibDir.canRead() - && StringUtils.endsWith(moduleLibDir.getName(), ".jar")) { - return new File[]{ - moduleLibDir - }; - } else { - return convertFileCollectionToFileArray( - listFiles(moduleLibDir, new String[]{"jar"}, false) - ); - } - } - /** - * 加载Module - * - * @param mjCb 模块文件加载回调 - * @param mCb 模块加载回掉 - */ - void load(final ModuleJarLoadCallback mjCb, - final ModuleLoadCallback mCb) { - - // 查找所有可加载的Jar文件 - final File[] moduleJarFileArray = toModuleJarFileArray(); - Arrays.sort(moduleJarFileArray); - - // 记录下都有那些模块文件被找到即将被加载 - if (logger.isInfoEnabled()) { - final Set moduleJarFileNameSet = new LinkedHashSet(); - for (final File moduleJarFile : moduleJarFileArray) { - moduleJarFileNameSet.add(moduleJarFile.getName()); + private boolean loadingModules(final ModuleJarClassLoader moduleClassLoader, + final ModuleLoadCallback mCb) { + + final Set loadedModuleUniqueIds = new LinkedHashSet(); + final ServiceLoader moduleServiceLoader = ServiceLoader.load(Module.class, moduleClassLoader); + final Iterator moduleIt = moduleServiceLoader.iterator(); + while (moduleIt.hasNext()) { + + final Module module; + try { + module = moduleIt.next(); + } catch (Throwable cause) { + logger.warn("loading module instance failed: instance occur error, will be ignored. module-jar={}", moduleJarFile, cause); + continue; } - logger.info("loading module-lib={}, found {} module-jar files : {}", - moduleLibDir, - moduleJarFileArray.length, - moduleJarFileNameSet - ); - } - // 开始逐条加载 - for (final File moduleJarFile : moduleJarFileArray) { + final Class classOfModule = module.getClass(); - logger.info("loading module-jar={} from module-lib={};", moduleJarFile, moduleLibDir); + // 判断模块是否实现了@Information标记 + if (!classOfModule.isAnnotationPresent(Information.class)) { + logger.warn("loading module instance failed: not implements @Information, will be ignored. class={};module-jar={};", + classOfModule, + moduleJarFile + ); + continue; + } - // 是否有模块加载成功 - boolean hasModuleLoadedSuccessFlag = false; + final Information info = classOfModule.getAnnotation(Information.class); + final String uniqueId = info.id(); - // 已加载的模块ID集合 - final Set loadedModuleUniqueIds = new LinkedHashSet(); + // 判断模块ID是否合法 + if (StringUtils.isBlank(uniqueId)) { + logger.warn("loading module instance failed: @Information.id is missing, will be ignored. class={};module-jar={};", + classOfModule, + moduleJarFile + ); + continue; + } - // MODULE-JAR-CLASSLOADER - ModuleClassLoader moduleClassLoader = null; + // 判断模块要求的启动模式和容器的启动模式是否匹配 + if (!ArrayUtils.contains(info.mode(), mode)) { + logger.warn("loading module instance failed: launch-mode is not match module required, will be ignored. module={};launch-mode={};required-mode={};class={};module-jar={};", + uniqueId, + mode, + StringUtils.join(info.mode(), ","), + classOfModule, + moduleJarFile + ); + continue; + } try { - - if (null != mjCb) { - try { - mjCb.onLoad(moduleJarFile); - } catch (Throwable cause) { - logger.warn("loading module-jar failed: JAR-LOADER-PROVIDER denied, will be ignore. module-jar={};", moduleJarFile, cause); - continue; - } + if (null != mCb) { + mCb.onLoad(uniqueId, classOfModule, module, moduleJarFile, moduleClassLoader); } - - // 模块ClassLoader - moduleClassLoader = new ModuleClassLoader(moduleJarFile, sandboxClassLoader); - - final ClassLoader preTCL = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(moduleClassLoader); - - try { - - final ServiceLoader moduleServiceLoader = ServiceLoader.load(Module.class, moduleClassLoader); - final Iterator moduleIt = moduleServiceLoader.iterator(); - while (moduleIt.hasNext()) { - - final Module module; - try { - module = moduleIt.next(); - } catch (Throwable cause) { - logger.warn("loading module instance failed: instance occur error, will be ignored. module-jar={}", moduleJarFile, cause); - continue; - } - - final Class classOfModule = module.getClass(); - - // 判断模块是否实现了@Information标记 - if (!classOfModule.isAnnotationPresent(Information.class)) { - logger.warn("loading module instance failed: not implements @Information, will be ignored. class={};module-jar={};", - classOfModule, - moduleJarFile - ); - continue; - } - - final Information info = classOfModule.getAnnotation(Information.class); - final String uniqueId = info.id(); - - // 判断模块ID是否合法 - if (StringUtils.isBlank(uniqueId)) { - logger.warn("loading module instance failed: @Information.id is missing, will be ignored. class={};module-jar={};", - classOfModule, - moduleJarFile - ); - continue; - } - - // 判断模块要求的启动模式和容器的启动模式是否匹配 - if (!ArrayUtils.contains(info.mode(), mode)) { - logger.warn("loading module instance failed: launch-mode is not match module required, will be ignored. module={};launch-mode={};required-mode={};class={};module-jar={};", - uniqueId, - mode, - StringUtils.join(info.mode(), ","), - classOfModule, - moduleJarFile - ); - continue; - } - - try { - if (null != mCb) { - mCb.onLoad(uniqueId, classOfModule, module, moduleJarFile, moduleClassLoader); - } - } catch (Throwable cause) { - logger.warn("loading module instance failed: MODULE-LOADER-PROVIDER denied, will be ignored. module={};class={};module-jar={};", - uniqueId, - classOfModule, - moduleJarFile, - cause - ); - continue; - } - - loadedModuleUniqueIds.add(uniqueId); - hasModuleLoadedSuccessFlag = true; - - }//while - - } finally { - Thread.currentThread().setContextClassLoader(preTCL); - }// try-catch for load module from Jar - } catch (Throwable cause) { - logger.info("load module-jar occur error, will be ignored. module-jar={};", + logger.warn("loading module instance failed: MODULE-LOADER-PROVIDER denied, will be ignored. module={};class={};module-jar={};", + uniqueId, + classOfModule, moduleJarFile, cause ); - } finally { - if (hasModuleLoadedSuccessFlag) { - logger.info("loaded module-jar completed, loaded {} module in module-jar={}, modules={}", - loadedModuleUniqueIds.size(), - moduleJarFile, - loadedModuleUniqueIds - ); - } else { - logger.warn("loaded module-jar completed, NONE module loaded, will be close ModuleClassLoader. module-jar={};", moduleJarFile, moduleClassLoader); - if (null != moduleClassLoader) { - moduleClassLoader.closeIfPossible(); - } - } - }// try-catch for load jar from lib + continue; + } + + loadedModuleUniqueIds.add(uniqueId); } + + logger.info("loaded module-jar completed, loaded {} module in module-jar={}, modules={}", + loadedModuleUniqueIds.size(), + moduleJarFile, + loadedModuleUniqueIds + ); + return !loadedModuleUniqueIds.isEmpty(); } - /** - * 模块文件加载回调 - */ - public interface ModuleJarLoadCallback { + void load(final ModuleLoadCallback mCb) throws IOException { - /** - * 模块文件加载回调 - * - * @param moduleJarFile 模块文件 - * @throws Throwable 加载回调异常 - */ - void onLoad(File moduleJarFile) throws Throwable; + boolean hasModuleLoadedSuccessFlag = false; + ModuleJarClassLoader moduleJarClassLoader = null; + logger.info("prepare loading module-jar={};", moduleJarFile); + try { + moduleJarClassLoader = new ModuleJarClassLoader(moduleJarFile); + + final ClassLoader preTCL = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(moduleJarClassLoader); + + try { + hasModuleLoadedSuccessFlag = loadingModules(moduleJarClassLoader, mCb); + } finally { + Thread.currentThread().setContextClassLoader(preTCL); + } + + } finally { + if (!hasModuleLoadedSuccessFlag + && null != moduleJarClassLoader) { + logger.warn("loading module-jar completed, but NONE module loaded, will be close ModuleJarClassLoader. module-jar={};", moduleJarFile); + moduleJarClassLoader.closeIfPossible(); + } + } } @@ -243,7 +157,7 @@ void onLoad(String uniqueId, Class moduleClass, Module module, File moduleJarFile, - ModuleClassLoader moduleClassLoader) throws Throwable; + ModuleJarClassLoader moduleClassLoader) throws Throwable; } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/ModuleLibLoader.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/ModuleLibLoader.java new file mode 100755 index 00000000..6d6ce580 --- /dev/null +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/ModuleLibLoader.java @@ -0,0 +1,99 @@ +package com.alibaba.jvm.sandbox.core.manager.impl; + +import com.alibaba.jvm.sandbox.api.Information; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.Arrays; + +import static org.apache.commons.io.FileUtils.convertFileCollectionToFileArray; +import static org.apache.commons.io.FileUtils.listFiles; +import static org.apache.commons.lang3.StringUtils.join; + +/** + * 模块目录加载器 + * 用于从${module.lib}中加载所有的沙箱模块 + * Created by luanjia@taobao.com on 2016/11/17. + */ +class ModuleLibLoader { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + // 模块加载目录 + private final File moduleLibDir; + + // 沙箱加载模式 + private final Information.Mode mode; + + ModuleLibLoader(final File moduleLibDir, + final Information.Mode mode) { + this.moduleLibDir = moduleLibDir; + this.mode = mode; + } + + private File[] toModuleJarFileArray() { + if (moduleLibDir.exists() + && moduleLibDir.isFile() + && moduleLibDir.canRead() + && StringUtils.endsWith(moduleLibDir.getName(), ".jar")) { + return new File[]{ + moduleLibDir + }; + } else { + return convertFileCollectionToFileArray( + listFiles(moduleLibDir, new String[]{"jar"}, false) + ); + } + } + + + private File[] listModuleJarFileInLib() { + final File[] moduleJarFileArray = toModuleJarFileArray(); + Arrays.sort(moduleJarFileArray); + logger.info("loading module-lib={}, found {} module-jar files : {}", + moduleLibDir, + moduleJarFileArray.length, + join(moduleJarFileArray, ",") + ); + return moduleJarFileArray; + } + + /** + * 加载Module + * + * @param mjCb 模块文件加载回调 + * @param mCb 模块加载回掉 + */ + void load(final ModuleJarLoadCallback mjCb, + final ModuleJarLoader.ModuleLoadCallback mCb) { + + // 开始逐条加载 + for (final File moduleJarFile : listModuleJarFileInLib()) { + try { + mjCb.onLoad(moduleJarFile); + new ModuleJarLoader(moduleJarFile, mode).load(mCb); + } catch (Throwable cause) { + logger.warn("loading module-jar occur error! module-jar={};", moduleJarFile, cause); + } + } + + } + + /** + * 模块文件加载回调 + */ + public interface ModuleJarLoadCallback { + + /** + * 模块文件加载回调 + * + * @param moduleJarFile 模块文件 + * @throws Throwable 加载回调异常 + */ + void onLoad(File moduleJarFile) throws Throwable; + + } + +} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/SandboxClassFileTransformer.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/SandboxClassFileTransformer.java index 043e3702..de21c8de 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/SandboxClassFileTransformer.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/manager/impl/SandboxClassFileTransformer.java @@ -2,7 +2,7 @@ import com.alibaba.jvm.sandbox.api.event.Event; import com.alibaba.jvm.sandbox.api.listener.EventListener; -import com.alibaba.jvm.sandbox.core.classloader.ModuleClassLoader; +import com.alibaba.jvm.sandbox.core.classloader.ModuleJarClassLoader; import com.alibaba.jvm.sandbox.core.enhance.EventEnhancer; import com.alibaba.jvm.sandbox.core.util.ObjectIDs; import com.alibaba.jvm.sandbox.core.util.matcher.Matcher; @@ -20,11 +20,13 @@ /** * 沙箱类形变器 - * Created by luanjia@taobao.com on 2016/11/14. + * + * @author luanjia@taobao.com */ public class SandboxClassFileTransformer implements ClassFileTransformer { private final Logger logger = LoggerFactory.getLogger(getClass()); + private final int watchId; private final String uniqueId; private final Matcher matcher; @@ -82,8 +84,8 @@ public byte[] transform(final ClassLoader loader, return null; } - // 过滤掉来自ModuleClassLoader加载的类 - if (loader instanceof ModuleClassLoader) { + // 过滤掉来自ModuleJarClassLoader加载的类 + if (loader instanceof ModuleJarClassLoader) { return null; } @@ -96,9 +98,11 @@ public byte[] transform(final ClassLoader loader, } catch (Throwable cause) { - logger.warn("sandbox transform class:{} in loader:{};namespace:{} failed, module[id:{}] at watch[id:{}] will ignore this transform.", - internalClassName, loader, namespace, - uniqueId, watchId, + logger.warn("sandbox transform {} in loader={}; failed, module={} at watch={}, will ignore this transform.", + internalClassName, + loader, + uniqueId, + watchId, cause ); return null; @@ -112,7 +116,7 @@ private byte[] _transform(final ClassLoader loader, // 如果未开启unsafe开关,是不允许增强来自BootStrapClassLoader的类 if (!isEnableUnsafe && null == loader) { - logger.debug("transform ignore class:{}, class from bootstrap but unsafe.enable:false.", internalClassName); + logger.debug("transform ignore {}, class from bootstrap but unsafe.enable=false.", internalClassName); return null; } @@ -122,7 +126,7 @@ private byte[] _transform(final ClassLoader loader, // 如果一个行为都没匹配上也不用继续了 if (!matchingResult.isMatched()) { - logger.debug("transform ignore class:{}, no behaviors matched in loader:{};namespace:{}", internalClassName, loader, namespace); + logger.debug("transform ignore {}, no behaviors matched in loader={}", internalClassName, loader); return null; } @@ -137,17 +141,17 @@ private byte[] _transform(final ClassLoader loader, eventTypeArray ); if (srcByteCodeArray == toByteCodeArray) { - logger.debug("transform ignore class:{}, nothing changed in loader:{}. namespace:{}", internalClassName, loader, namespace); + logger.debug("transform ignore {}, nothing changed in loader={}", internalClassName, loader); return null; } // statistic affect affectStatistic.statisticAffect(loader, internalClassName, behaviorSignCodes); - logger.info("transform class:{} finished, by module[id:{}] in loader:{};namespace:{}", internalClassName, uniqueId, loader, namespace); + logger.info("transform {} finished, by module={} in loader={}", internalClassName, uniqueId, loader); return toByteCodeArray; } catch (Throwable cause) { - logger.warn("transform class:{} failed, by module[id={}] in loader:{}namespace:{};", internalClassName, uniqueId, loader, namespace, cause); + logger.warn("transform {} failed, by module={} in loader={}", internalClassName, uniqueId, loader, cause); return null; } } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer.java index e30e1c32..92689810 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer.java @@ -1,20 +1,12 @@ package com.alibaba.jvm.sandbox.core.server.jetty; -import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.joran.JoranConfigurator; import com.alibaba.jvm.sandbox.core.CoreConfigure; -import com.alibaba.jvm.sandbox.core.enhance.weaver.EventListenerHandlers; -import com.alibaba.jvm.sandbox.core.manager.CoreModuleManager; -import com.alibaba.jvm.sandbox.core.manager.ModuleLifeCycleEventBus; -import com.alibaba.jvm.sandbox.core.manager.ModuleResourceManager; -import com.alibaba.jvm.sandbox.core.manager.ProviderManager; -import com.alibaba.jvm.sandbox.core.manager.impl.*; +import com.alibaba.jvm.sandbox.core.JvmSandbox; import com.alibaba.jvm.sandbox.core.server.CoreServer; import com.alibaba.jvm.sandbox.core.server.jetty.servlet.ModuleHttpServlet; import com.alibaba.jvm.sandbox.core.server.jetty.servlet.WebSocketAcceptorServlet; import com.alibaba.jvm.sandbox.core.util.Initializer; -import com.alibaba.jvm.sandbox.core.util.SandboxStringUtils; -import org.apache.commons.io.IOUtils; +import com.alibaba.jvm.sandbox.core.util.LogbackUtils; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.nio.SelectChannelConnector; @@ -25,13 +17,10 @@ import org.slf4j.LoggerFactory; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; import java.lang.instrument.Instrumentation; import java.net.InetSocketAddress; -import static com.alibaba.jvm.sandbox.core.util.NamespaceConvert.initNamespaceConvert; import static com.alibaba.jvm.sandbox.core.util.NetworkUtils.isPortInUsing; import static java.lang.String.format; import static org.eclipse.jetty.servlet.ServletContextHandler.NO_SESSIONS; @@ -49,8 +38,7 @@ public class JettyCoreServer implements CoreServer { private Server httpServer; private CoreConfigure cfg; - private ModuleResourceManager moduleResourceManager; - private CoreModuleManager coreModuleManager; + private JvmSandbox jvmSandbox; /** * 单例 @@ -79,6 +67,7 @@ public void unbind() throws IOException { initializer.destroyProcess(new Initializer.Processor() { @Override public void process() throws Throwable { + if (null != httpServer) { // stop http server @@ -86,17 +75,15 @@ public void process() throws Throwable { httpServer.stop(); } + } }); // destroy http server logger.info("{} is destroying", this); + while (!httpServer.isStopped()); httpServer.destroy(); - // 关闭对象池 - logger.info("{} is closing event-pool", this); - EventListenerHandlers.getSingleton().getEventPool().close(); - } catch (Throwable cause) { logger.warn("{} unBind failed.", this, cause); throw new IOException("unBind failed.", cause); @@ -134,135 +121,95 @@ public InetSocketAddress getLocal() throws IOException { /* * 初始化Jetty's ContextHandler */ - private void initJettyContextHandler(final CoreConfigure cfg) { + private void initJettyContextHandler() { + final String namespace = cfg.getNamespace(); final ServletContextHandler context = new ServletContextHandler(NO_SESSIONS); - final String contextPath = "/sandbox/" + cfg.getNamespace(); + final String contextPath = "/sandbox/" + namespace; context.setContextPath(contextPath); context.setClassLoader(getClass().getClassLoader()); // web-socket-servlet final String wsPathSpec = "/module/websocket/*"; logger.info("initializing ws-http-handler. path={}", contextPath + wsPathSpec); - context.addServlet(new ServletHolder(new WebSocketAcceptorServlet(coreModuleManager, moduleResourceManager)), wsPathSpec); + //noinspection deprecation + context.addServlet( + new ServletHolder(new WebSocketAcceptorServlet(jvmSandbox.getCoreModuleManager())), + wsPathSpec + ); // module-http-servlet final String pathSpec = "/module/http/*"; logger.info("initializing http-handler. path={}", contextPath + pathSpec); - context.addServlet(new ServletHolder(new ModuleHttpServlet(coreModuleManager, moduleResourceManager)), pathSpec); + context.addServlet( + new ServletHolder(new ModuleHttpServlet(jvmSandbox.getCoreModuleManager())), + pathSpec + ); httpServer.setHandler(context); } - // 初始化Logback日志配置 - private void initLogback(final CoreConfigure cfg) { - final LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); - final JoranConfigurator configurator = new JoranConfigurator(); - final File configureFile = new File(cfg.getCfgLibPath() + File.separator + "sandbox-logback.xml"); - configurator.setContext(loggerContext); - loggerContext.reset(); - InputStream is = null; - try { - is = new FileInputStream(configureFile); - initNamespaceConvert(cfg.getNamespace()); - configurator.doConfigure(is); - logger.info(SandboxStringUtils.getLogo()); - logger.info("initializing logback success. file={};", configureFile); - } catch (Throwable cause) { - logger.warn("initialize logback failed. file={};", configureFile, cause); - } finally { - IOUtils.closeQuietly(is); - } - } - - // 关闭Logback日志框架 - private void closeLogback() { - try { - ((LoggerContext) LoggerFactory.getILoggerFactory()).stop(); - } catch (Throwable cause) { - // - } - } + private void initHttpServer() { - private void initHttpServer(final CoreConfigure cfg) { + final String serverIp = cfg.getServerIp(); + final int serverPort = cfg.getServerPort(); // 如果IP:PORT已经被占用,则无法继续被绑定 // 这里说明下为什么要这么无聊加个这个判断,让Jetty的Server.bind()抛出异常不是更好么? // 比较郁闷的是,如果这个端口的绑定是"SO_REUSEADDR"端口可重用的模式,那么这个server是能正常启动,但无法正常工作的 // 所以这里必须先主动检查一次端口占用情况,当然了,这里也会存在一定的并发问题,BUT,我认为这种概率事件我可以选择暂时忽略 - if (isPortInUsing(cfg.getServerIp(), cfg.getServerPort())) { + if (isPortInUsing(serverIp, serverPort)) { throw new IllegalStateException(format("address[%s:%s] already in using, server bind failed.", - cfg.getServerIp(), - cfg.getServerPort()) - ); + serverIp, + serverPort + )); } - httpServer = new Server(new InetSocketAddress(cfg.getServerIp(), cfg.getServerPort())); + httpServer = new Server(new InetSocketAddress(serverIp, serverPort)); if (httpServer.getThreadPool() instanceof QueuedThreadPool) { final QueuedThreadPool qtp = (QueuedThreadPool) httpServer.getThreadPool(); qtp.setName("sandbox-jetty-qtp-" + qtp.hashCode()); } } - // 关闭HTTP服务器 - private void closeHttpServer() { - if (null != httpServer) { - httpServer.destroy(); - } - } - - // 初始化各种manager - private void initManager(final Instrumentation inst, - final CoreConfigure cfg) { - - final ClassLoader sandboxClassLoader = getClass().getClassLoader(); - - // 初始化事件处理总线 - logger.info("initializing manager : EventListenerHandlers"); - EventListenerHandlers.getSingleton(); - - // 初始化模块生命周期事件总线 - logger.info("initializing manager : ModuleLifeCycleEventBus"); - final ModuleLifeCycleEventBus moduleLifeCycleEventBus = new DefaultModuleLifeCycleEventBus(); - - // 初始化模块资源管理器 - logger.info("initializing manager : ModuleResourceManager"); - moduleLifeCycleEventBus.append(moduleResourceManager = new DefaultModuleResourceManager()); - - // 初始化服务管理器 - logger.info("initializing manager : ProviderManager"); - final ProviderManager providerManager = new DefaultProviderManager(cfg, sandboxClassLoader); - - // 初始化模块管理器 - logger.info("initializing manager : CoreModuleManager"); - coreModuleManager = new DefaultCoreModuleManager( - cfg, inst, - sandboxClassLoader, new DefaultLoadedClassDataSource(inst, cfg), - moduleLifeCycleEventBus, - providerManager - ); - - } - @Override public synchronized void bind(final CoreConfigure cfg, final Instrumentation inst) throws IOException { + this.cfg = cfg; try { initializer.initProcess(new Initializer.Processor() { @Override public void process() throws Throwable { - JettyCoreServer.this.cfg = cfg; - initLogback(cfg); + LogbackUtils.init( + cfg.getNamespace(), + cfg.getCfgLibPath() + File.separator + "sandbox-logback.xml" + ); logger.info("initializing server. cfg={}", cfg); - initManager(inst, cfg); - initHttpServer(cfg); - initJettyContextHandler(cfg); + jvmSandbox = new JvmSandbox(cfg, inst); + initHttpServer(); + initJettyContextHandler(); httpServer.start(); } }); + + // 初始化加载所有的模块 + try { + jvmSandbox.getCoreModuleManager().reset(); + } catch (Throwable cause) { + logger.warn("reset occur error when initializing.", cause); + } + final InetSocketAddress local = getLocal(); - logger.info("initialized server. actual bind to {}:{}", local.getHostName(), local.getPort()); + logger.info("initialized server. actual bind to {}:{}", + local.getHostName(), + local.getPort() + ); + } catch (Throwable cause) { + + // 这里会抛出到目标应用层,所以在这里留下错误信息 logger.warn("initialize server failed.", cause); + + // 对外抛出到目标应用中 throw new IOException("server bind failed.", cause); } @@ -271,6 +218,11 @@ public void process() throws Throwable { @Override public void destroy() { + + // 关闭JVM-SANDBOX + jvmSandbox.destroy(); + + // 关闭HTTP服务器 if (isBind()) { try { unbind(); @@ -279,11 +231,8 @@ public void destroy() { } } - // STOP HTTP-SERVER - closeHttpServer(); - - // STOP LOGBACK - closeLogback(); + // 关闭LOGBACK + LogbackUtils.destroy(); } @Override diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/server/jetty/servlet/ModuleHttpServlet.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/server/jetty/servlet/ModuleHttpServlet.java index 1cf8ef57..b78af491 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/server/jetty/servlet/ModuleHttpServlet.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/server/jetty/servlet/ModuleHttpServlet.java @@ -1,9 +1,10 @@ package com.alibaba.jvm.sandbox.core.server.jetty.servlet; +import com.alibaba.jvm.sandbox.api.annotation.Command; import com.alibaba.jvm.sandbox.api.http.Http; -import com.alibaba.jvm.sandbox.core.domain.CoreModule; +import com.alibaba.jvm.sandbox.core.CoreModule; +import com.alibaba.jvm.sandbox.core.CoreModule.ReleaseResource; import com.alibaba.jvm.sandbox.core.manager.CoreModuleManager; -import com.alibaba.jvm.sandbox.core.manager.ModuleResourceManager; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; @@ -19,6 +20,10 @@ import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; import static com.alibaba.jvm.sandbox.api.util.GaStringUtils.matching; @@ -31,12 +36,9 @@ public class ModuleHttpServlet extends HttpServlet { private final Logger logger = LoggerFactory.getLogger(getClass()); private final CoreModuleManager coreModuleManager; - private final ModuleResourceManager moduleResourceManager; - public ModuleHttpServlet(final CoreModuleManager coreModuleManager, - final ModuleResourceManager moduleResourceManager) { + public ModuleHttpServlet(final CoreModuleManager coreModuleManager) { this.coreModuleManager = coreModuleManager; - this.moduleResourceManager = moduleResourceManager; } @Override @@ -51,7 +53,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S private void doMethod(final HttpServletRequest req, final HttpServletResponse resp, - final Http.Method httpMethod) throws ServletException, IOException { + final Http.Method expectHttpMethod) throws ServletException, IOException { // 获取请求路径 final String path = req.getPathInfo(); @@ -75,7 +77,7 @@ private void doMethod(final HttpServletRequest req, // 匹配对应的方法 final Method method = matchingModuleMethod( path, - httpMethod, + expectHttpMethod, uniqueId, coreModule.getModule().getClass() ); @@ -99,18 +101,16 @@ private void doMethod(final HttpServletRequest req, // 生成方法调用参数 final Object[] parameterObjectArray = generateParameterObjectArray(method, req, resp); - final PrintWriter writer = resp.getWriter(); + final PrintWriter writer = coreModule.append(new ReleaseResource(resp.getWriter()) { - // 调用方法 - moduleResourceManager.append(uniqueId, - new ModuleResourceManager.WeakResource(writer) { + @Override + public void release() { + IOUtils.closeQuietly(get()); + } + + }); - @Override - public void release() { - IOUtils.closeQuietly(get()); - } - }); final boolean isAccessible = method.isAccessible(); final ClassLoader oriThreadContextClassLoader = Thread.currentThread().getContextClassLoader(); try { @@ -137,7 +137,7 @@ public void release() { } finally { Thread.currentThread().setContextClassLoader(oriThreadContextClassLoader); method.setAccessible(isAccessible); - moduleResourceManager.remove(uniqueId, writer); + coreModule.release(writer); } } @@ -173,12 +173,25 @@ private Method matchingModuleMethod(final String path, final String uniqueId, final Class classOfModule) { + // 查找@Command注解的方法 + for (final Method method : MethodUtils.getMethodsListWithAnnotation(classOfModule, Command.class)) { + final Command commandAnnotation = method.getAnnotation(Command.class); + if (null == commandAnnotation) { + continue; + } + final String pathOfCmd = "/" + uniqueId + "/" + commandAnnotation.value(); + if (StringUtils.equals(path, pathOfCmd)) { + return method; + } + } + + // 查找@Http注解的方法 for (final Method method : MethodUtils.getMethodsListWithAnnotation(classOfModule, Http.class)) { final Http httpAnnotation = method.getAnnotation(Http.class); - if(null == httpAnnotation) { + if (null == httpAnnotation) { continue; } - final String pathPattern = "/"+uniqueId+httpAnnotation.value(); + final String pathPattern = "/" + uniqueId + httpAnnotation.value(); if (ArrayUtils.contains(httpAnnotation.method(), httpMethod) && matching(path, pathPattern)) { return method; @@ -189,6 +202,20 @@ && matching(path, pathPattern)) { return null; } + private boolean isMapWithGenericParameterTypes(final Method method, + final int parameterIndex, + final Class keyClass, + final Class valueClass) { + final Type[] genericParameterTypes = method.getGenericParameterTypes(); + if (genericParameterTypes.length < parameterIndex + || !(genericParameterTypes[parameterIndex] instanceof ParameterizedType)) { + return false; + } + final Type[] actualTypeArguments = ((ParameterizedType) genericParameterTypes[parameterIndex]).getActualTypeArguments(); + return actualTypeArguments.length == 2 + && keyClass.equals(actualTypeArguments[0]) + && valueClass.equals(actualTypeArguments[1]); + } /** * 生成方法请求参数数组 @@ -201,7 +228,7 @@ && matching(path, pathPattern)) { */ private Object[] generateParameterObjectArray(final Method method, final HttpServletRequest req, - final HttpServletResponse resp) { + final HttpServletResponse resp) throws IOException { final Class[] parameterTypeArray = method.getParameterTypes(); if (ArrayUtils.isEmpty(parameterTypeArray)) { @@ -223,6 +250,34 @@ private Object[] generateParameterObjectArray(final Method method, continue; } + // ParameterMap + if (Map.class.isAssignableFrom(parameterType) + && isMapWithGenericParameterTypes(method, index, String.class, String[].class)) { + parameterObjectArray[index] = req.getParameterMap(); + } + + // ParameterMap + else if (Map.class.isAssignableFrom(parameterType) + && isMapWithGenericParameterTypes(method, index, String.class, String.class)) { + final Map param = new HashMap(); + for (final Map.Entry entry : req.getParameterMap().entrySet()) { + param.put(entry.getKey(), StringUtils.join(entry.getValue(), ",")); + } + parameterObjectArray[index] = param; + } + + // QueryString + else if (String.class.isAssignableFrom(parameterType)) { + parameterObjectArray[index] = req.getQueryString(); + } + + + // PrintWriter + else if (PrintWriter.class.isAssignableFrom(parameterType)) { + parameterObjectArray[index] = resp.getWriter(); + } + + } return parameterObjectArray; diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet.java index 2b2c3e68..23b1d2c0 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet.java @@ -4,9 +4,8 @@ import com.alibaba.jvm.sandbox.api.http.websocket.WebSocketAcceptor; import com.alibaba.jvm.sandbox.api.http.websocket.WebSocketConnection; import com.alibaba.jvm.sandbox.api.http.websocket.WebSocketConnectionListener; -import com.alibaba.jvm.sandbox.core.domain.CoreModule; +import com.alibaba.jvm.sandbox.core.CoreModule; import com.alibaba.jvm.sandbox.core.manager.CoreModuleManager; -import com.alibaba.jvm.sandbox.core.manager.ModuleResourceManager; import org.apache.commons.lang3.StringUtils; import org.eclipse.jetty.websocket.WebSocket; import org.eclipse.jetty.websocket.WebSocket.OnTextMessage; @@ -19,21 +18,19 @@ /** * 构建WebSocket通讯 - * Created by luanjia@taobao.com on 2017/2/2. + * + * @author luanjia@taobao.com + * @deprecated 考虑废弃掉WebSocket的支持,不再维护 */ +@Deprecated public class WebSocketAcceptorServlet extends WebSocketServlet { private final Logger logger = LoggerFactory.getLogger(getClass()); - // WebSocket Connection auto release Map - private final ModuleResourceManager moduleResourceManager; - private final CoreModuleManager coreModuleManager; - public WebSocketAcceptorServlet(final CoreModuleManager coreModuleManager, - final ModuleResourceManager moduleResourceManager) { + public WebSocketAcceptorServlet(final CoreModuleManager coreModuleManager) { this.coreModuleManager = coreModuleManager; - this.moduleResourceManager = moduleResourceManager; } @@ -74,9 +71,9 @@ public WebSocket doWebSocketConnect(final HttpServletRequest req, uniqueId, coreModule.getModule().getClass().getName(), req.getPathInfo()); if (listener instanceof TextMessageListener) { - return new InnerOnTextMessage(uniqueId, (TextMessageListener) listener); + return new InnerOnTextMessage(coreModule, (TextMessageListener) listener); } else { - return new InnerWebSocket(uniqueId, listener); + return new InnerWebSocket(coreModule, listener); } } @@ -93,42 +90,31 @@ private String parseUniqueId(final String pathInfo) { return null; } - private class WebSocketConnectionResource extends ModuleResourceManager.WeakResource { - - final WebSocketConnection conn; - - WebSocketConnectionResource(WebSocketConnection conn) { - super(conn); - this.conn = conn; - } - - @Override - public void release() { - if (null != conn) { - conn.disconnect(); - } - } - - } - private class InnerWebSocket implements WebSocket { - final String uniqueId; + final CoreModule coreModule; final WebSocketConnectionListener listener; private WebSocketConnection conn = null; - InnerWebSocket(String uniqueId, WebSocketConnectionListener listener) { - this.uniqueId = uniqueId; + InnerWebSocket(final CoreModule coreModule, + final WebSocketConnectionListener listener) { + this.coreModule = coreModule; this.listener = listener; } @Override public void onOpen(Connection connection) { - conn = moduleResourceManager.append( - uniqueId, - new WebSocketConnectionResource(toWebSocketConnection(connection)) - ); + conn = coreModule.append(new CoreModule.ReleaseResource(toWebSocketConnection(connection)) { + @Override + public void release() { + final WebSocketConnection resource = get(); + if(null != resource) { + resource.disconnect(); + } + + } + }); listener.onOpen(conn); } @@ -161,7 +147,7 @@ public void onClose(int closeCode, String message) { try { listener.onClose(closeCode, message); } finally { - moduleResourceManager.remove(uniqueId, conn); + coreModule.release(conn); } } @@ -171,8 +157,9 @@ private class InnerOnTextMessage extends InnerWebSocket implements OnTextMessage private final TextMessageListener textMessageListener; - InnerOnTextMessage(String uniqueId, TextMessageListener listener) { - super(uniqueId, listener); + InnerOnTextMessage(final CoreModule coreModule, + final TextMessageListener listener) { + super(coreModule, listener); this.textMessageListener = listener; } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/AsmUtils.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/AsmUtils.java new file mode 100644 index 00000000..365d5602 --- /dev/null +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/AsmUtils.java @@ -0,0 +1,63 @@ +package com.alibaba.jvm.sandbox.core.util; + +import com.alibaba.jvm.sandbox.core.util.matcher.structure.ClassStructure; +import com.alibaba.jvm.sandbox.core.util.matcher.structure.ClassStructureFactory; +import org.apache.commons.io.IOUtils; + +import java.io.InputStream; + +import static com.alibaba.jvm.sandbox.core.util.SandboxStringUtils.toInternalClassName; + +/** + * ASM工具集 + * + * @author luanjia@taobao.com + */ +public class AsmUtils { + + /** + * {@see org.objectweb.asm.ClassWriter#getCommonSuperClass(String, String)} + */ + public static String getCommonSuperClass(String type1, String type2, ClassLoader loader) { + return getCommonSuperClassImplByAsm(type1, type2, loader); + } + + // implements by ASM + private static String getCommonSuperClassImplByAsm(String type1, String type2, ClassLoader targetClassLoader) { + InputStream inputStreamOfType1 = null, inputStreamOfType2 = null; + try { + inputStreamOfType1 = targetClassLoader.getResourceAsStream(type1 + ".class"); + if (null == inputStreamOfType1) { + return "java/lang/Object"; + } + inputStreamOfType2 = targetClassLoader.getResourceAsStream(type2 + ".class"); + if (null == inputStreamOfType2) { + return "java/lang/Object"; + } + final ClassStructure classStructureOfType1 = ClassStructureFactory.createClassStructure(inputStreamOfType1, targetClassLoader); + final ClassStructure classStructureOfType2 = ClassStructureFactory.createClassStructure(inputStreamOfType2, targetClassLoader); + if (classStructureOfType2.getFamilyTypeClassStructures().contains(classStructureOfType1)) { + return type1; + } + if (classStructureOfType1.getFamilyTypeClassStructures().contains(classStructureOfType2)) { + return type2; + } + if (classStructureOfType1.getAccess().isInterface() + || classStructureOfType2.getAccess().isInterface()) { + return "java/lang/Object"; + } + ClassStructure classStructure = classStructureOfType1; + do { + classStructure = classStructure.getSuperClassStructure(); + if (null == classStructure) { + return "java/lang/Object"; + } + } while (!classStructureOfType2.getFamilyTypeClassStructures().contains(classStructure)); + return toInternalClassName(classStructure.getJavaClassName()); + } finally { + IOUtils.closeQuietly(inputStreamOfType1); + IOUtils.closeQuietly(inputStreamOfType2); + } + } + +} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/EventPool.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/EventPool.java deleted file mode 100755 index 9fc39551..00000000 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/EventPool.java +++ /dev/null @@ -1,446 +0,0 @@ -package com.alibaba.jvm.sandbox.core.util; - -import com.alibaba.jvm.sandbox.api.event.*; -import com.alibaba.jvm.sandbox.core.CoreConfigure; -import org.apache.commons.pool2.BaseKeyedPooledObjectFactory; -import org.apache.commons.pool2.KeyedObjectPool; -import org.apache.commons.pool2.PooledObject; -import org.apache.commons.pool2.impl.DefaultPooledObject; -import org.apache.commons.pool2.impl.GenericKeyedObjectPool; -import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import sun.misc.Unsafe; - -/** - * 事件对象池 - * - * @author luanjia@taobao.com - */ -public class EventPool { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final KeyedObjectPool pool; - private final boolean isEnable; - - public EventPool() { - this.pool = createEventPool(); - this.isEnable = this.pool != null; - } - - /** - * 关闭并清理对象池 - *

- * 修复问题:#108 - *

- */ - public void close() { - if (null != pool) { - pool.close(); - } - } - - private KeyedObjectPool createEventPool() { - final CoreConfigure cfg = CoreConfigure.getInstance(); - if (cfg.isEventPoolEnable()) { - final GenericKeyedObjectPoolConfig poolConfig = new GenericKeyedObjectPoolConfig(); - poolConfig.setMaxTotalPerKey(cfg.getEventPoolMaxTotalPerEvent()); - poolConfig.setMinIdlePerKey(cfg.getEventPoolMinIdlePerEvent()); - poolConfig.setMaxIdlePerKey(cfg.getEventPoolMaxIdlePerEvent()); - poolConfig.setMaxTotal(cfg.getEventPoolMaxTotal()); - logger.info("enable event-pool[per-key-idle-min={};per-key-idle-max={};per-key-max={};total={};]", - cfg.getEventPoolMinIdlePerEvent(), - cfg.getEventPoolMaxIdlePerEvent(), - cfg.getEventPoolMaxTotalPerEvent(), - cfg.getEventPoolMaxTotal() - ); - return new GenericKeyedObjectPool(new EventFactory(), poolConfig); - } else { - logger.info("disable event-pool."); - return null; - } - } - - public int getNumActive() { - return isEnable - ? pool.getNumActive() - : -1; - } - - public int getNumActive(Event.Type type) { - return isEnable - ? pool.getNumActive(type) - : -1; - } - - public int getNumIdle() { - return isEnable - ? pool.getNumIdle() - : -1; - } - - public int getNumIdle(Event.Type type) { - return isEnable - ? pool.getNumIdle(type) - : -1; - } - - public BeforeEvent borrowBeforeEvent(final int processId, - final int invokeId, - final ClassLoader javaClassLoader, - final String javaClassName, - final String javaMethodName, - final String javaMethodDesc, - final Object target, - final Object[] argumentArray) { - if (isEnable) { - try { - final BeforeEvent event = (BeforeEvent) pool.borrowObject(Event.Type.BEFORE); - initBeforeEvent( - event, - processId, invokeId, - javaClassLoader, javaClassName, javaMethodName, javaMethodDesc, - target, argumentArray - ); - return event; - } catch (Exception cause) { - logger.warn("EventPool borrow BeforeEvent[processId={};invokeId={};class={};method={};] failed.", - processId, invokeId, javaClassName, javaMethodName, cause); - } - } - return new BeforeEvent( - processId, invokeId, - javaClassLoader, javaClassName, javaMethodName, javaMethodDesc, - target, argumentArray - ); - } - - public ReturnEvent borrowReturnEvent(final int processId, - final int invokeId, - final Object object) { - if (isEnable) { - try { - final ReturnEvent event = (ReturnEvent) pool.borrowObject(Event.Type.RETURN); - initReturnEvent(event, processId, invokeId, object); - return event; - } catch (Exception cause) { - logger.warn("EventPool borrow ReturnEvent[processId={};invokeId={};] failed.", - processId, invokeId, cause); - } - } - return new ReturnEvent(processId, invokeId, object); - } - - public ThrowsEvent borrowThrowsEvent(final int processId, - final int invokeId, - final Throwable throwable) { - if (isEnable) { - try { - final ThrowsEvent event = (ThrowsEvent) pool.borrowObject(Event.Type.THROWS); - initThrowsEvent(event, processId, invokeId, throwable); - return event; - } catch (Exception cause) { - logger.warn("EventPool borrow ThrowsEvent[processId={};invokeId={};] failed.", - processId, invokeId, cause); - } - } - return new ThrowsEvent(processId, invokeId, throwable); - } - - public LineEvent borrowLineEvent(final int processId, - final int invokeId, - final int lineNumber) { - if (isEnable) { - try { - final LineEvent event = (LineEvent) pool.borrowObject(Event.Type.LINE); - initLineEvent(event, processId, invokeId, lineNumber); - return event; - } catch (Exception cause) { - logger.warn("EventPool borrow LineEvent[processId={};invokeId={};] failed.", - processId, invokeId, cause); - } - } - return new LineEvent(processId, invokeId, lineNumber); - } - - public ImmediatelyReturnEvent borrowImmediatelyReturnEvent(final int processId, - final int invokeId, - final Object object) { - if (isEnable) { - try { - final ImmediatelyReturnEvent event = (ImmediatelyReturnEvent) pool.borrowObject(Event.Type.IMMEDIATELY_RETURN); - initReturnEvent(event, processId, invokeId, object); - return event; - } catch (Exception cause) { - logger.warn("EventPool borrow ImmediatelyReturnEvent[processId={};invokeId={};] failed.", - processId, invokeId, cause); - } - } - return new ImmediatelyReturnEvent(processId, invokeId, object); - } - - public ImmediatelyThrowsEvent borrowImmediatelyThrowsEvent(final int processId, - final int invokeId, - final Throwable throwable) { - if (isEnable) { - try { - final ImmediatelyThrowsEvent event = (ImmediatelyThrowsEvent) pool.borrowObject(Event.Type.IMMEDIATELY_THROWS); - initThrowsEvent(event, processId, invokeId, throwable); - return event; - } catch (Exception cause) { - logger.warn("EventPool borrow ImmediatelyThrowsEvent[processId={};invokeId={};] failed.", - processId, invokeId, cause); - } - } - return new ImmediatelyThrowsEvent(processId, invokeId, throwable); - } - - public CallBeforeEvent borrowCallBeforeEvent(final int processId, - final int invokeId, - final int lineNumber, - final String owner, - final String name, - final String desc) { - if (isEnable) { - try { - final CallBeforeEvent event = (CallBeforeEvent) pool.borrowObject(Event.Type.CALL_BEFORE); - initCallBeforeEvent(event, processId, invokeId, lineNumber, owner, name, desc); - return event; - } catch (Exception cause) { - logger.warn("EventPool borrow CallBeforeEvent[processId={};invokeId={};] failed.", - processId, invokeId, cause); - } - } - return new CallBeforeEvent(processId, invokeId, lineNumber, owner, name, desc); - } - - public CallReturnEvent borrowCallReturnEvent(final int processId, - final int invokeId) { - if (isEnable) { - try { - final CallReturnEvent event = (CallReturnEvent) pool.borrowObject(Event.Type.CALL_RETURN); - initCallReturnEvent(event, processId, invokeId); - return event; - } catch (Exception cause) { - logger.warn("EventPool borrow CallReturnEvent[processId={};invokeId={};] failed.", - processId, invokeId, cause); - } - } - return new CallReturnEvent(processId, invokeId); - } - - public CallThrowsEvent borrowCallThrowsEvent(final int processId, - final int invokeId, - final String throwException) { - if (isEnable) { - try { - final CallThrowsEvent event = (CallThrowsEvent) pool.borrowObject(Event.Type.CALL_THROWS); - initCallThrowsEvent(event, processId, invokeId, throwException); - return event; - } catch (Exception cause) { - logger.warn("EventPool borrow CallThrowsEvent[processId={};invokeId={};] failed.", - processId, invokeId, cause); - } - } - return new CallThrowsEvent(processId, invokeId, throwException); - } - - - /** - * 归还事件对象 - * - * @param event 事件对象 - */ - public void returnEvent(Event event) { - if (isEnable) { - try { - pool.returnObject(event.type, event); - } catch (Exception cause) { - logger.warn("EventPool return event={} failed.", event, cause); - } - } - } - - - private static final int ILLEGAL_PROCESS_ID = -1; - private static final int ILLEGAL_INVOKE_ID = -1; - - private static final Unsafe unsafe; - private static final long processIdFieldInInvokeEventOffset; - private static final long invokeIdFieldInInvokeEventOffset; - private static final long javaClassLoaderFieldInBeforeEventOffset; - private static final long javaClassNameFieldInBeforeEventOffset; - private static final long javaMethodNameFieldInBeforeEventOffset; - private static final long javaMethodDescFieldInBeforeEventOffset; - private static final long targetFieldInBeforeEventOffset; - private static final long argumentArrayFieldInBeforeEventOffset; - private static final long objectFieldInReturnEventOffset; - private static final long throwableFieldInThrowsEventOffset; - private static final long lineNumberFieldInLineEventOffset; - - private static final long lineNumberFieldInCallBeforeEventOffset; - private static final long ownerFieldInCallBeforeEventOffset; - private static final long nameFieldInCallBeforeEventOffset; - private static final long descFieldInCallBeforeEventOffset; - private static final long throwExceptionFieldInCallThrowsEventOffset; - - static { - try { - unsafe = UnsafeUtils.getUnsafe(); - processIdFieldInInvokeEventOffset = unsafe.objectFieldOffset(InvokeEvent.class.getDeclaredField("processId")); - invokeIdFieldInInvokeEventOffset = unsafe.objectFieldOffset(InvokeEvent.class.getDeclaredField("invokeId")); - javaClassLoaderFieldInBeforeEventOffset = unsafe.objectFieldOffset(BeforeEvent.class.getDeclaredField("javaClassLoader")); - javaClassNameFieldInBeforeEventOffset = unsafe.objectFieldOffset(BeforeEvent.class.getDeclaredField("javaClassName")); - javaMethodNameFieldInBeforeEventOffset = unsafe.objectFieldOffset(BeforeEvent.class.getDeclaredField("javaMethodName")); - javaMethodDescFieldInBeforeEventOffset = unsafe.objectFieldOffset(BeforeEvent.class.getDeclaredField("javaMethodDesc")); - targetFieldInBeforeEventOffset = unsafe.objectFieldOffset(BeforeEvent.class.getDeclaredField("target")); - argumentArrayFieldInBeforeEventOffset = unsafe.objectFieldOffset(BeforeEvent.class.getDeclaredField("argumentArray")); - objectFieldInReturnEventOffset = unsafe.objectFieldOffset(ReturnEvent.class.getDeclaredField("object")); - throwableFieldInThrowsEventOffset = unsafe.objectFieldOffset(ThrowsEvent.class.getDeclaredField("throwable")); - lineNumberFieldInLineEventOffset = unsafe.objectFieldOffset(LineEvent.class.getDeclaredField("lineNumber")); - - lineNumberFieldInCallBeforeEventOffset = unsafe.objectFieldOffset(CallBeforeEvent.class.getDeclaredField("lineNumber")); - ownerFieldInCallBeforeEventOffset = unsafe.objectFieldOffset(CallBeforeEvent.class.getDeclaredField("owner")); - nameFieldInCallBeforeEventOffset = unsafe.objectFieldOffset(CallBeforeEvent.class.getDeclaredField("name")); - descFieldInCallBeforeEventOffset = unsafe.objectFieldOffset(CallBeforeEvent.class.getDeclaredField("desc")); - throwExceptionFieldInCallThrowsEventOffset = unsafe.objectFieldOffset(CallThrowsEvent.class.getDeclaredField("throwException")); - } catch (Exception e) { - throw new Error(e); - } - } - - - private static void initBeforeEvent(final BeforeEvent event, - final int processId, - final int invokeId, - final ClassLoader javaClassLoader, - final String javaClassName, - final String javaMethodName, - final String javaMethodDesc, - final Object target, - final Object[] argumentArray) { - unsafe.putInt(event, processIdFieldInInvokeEventOffset, processId); - unsafe.putInt(event, invokeIdFieldInInvokeEventOffset, invokeId); - unsafe.putObject(event, javaClassLoaderFieldInBeforeEventOffset, javaClassLoader); - unsafe.putObject(event, javaClassNameFieldInBeforeEventOffset, javaClassName); - unsafe.putObject(event, javaMethodNameFieldInBeforeEventOffset, javaMethodName); - unsafe.putObject(event, javaMethodDescFieldInBeforeEventOffset, javaMethodDesc); - unsafe.putObject(event, targetFieldInBeforeEventOffset, target); - unsafe.putObject(event, argumentArrayFieldInBeforeEventOffset, argumentArray); - } - - private static void initReturnEvent(final ReturnEvent event, - final int processId, - final int invokeId, - final Object returnObj) { - unsafe.putInt(event, processIdFieldInInvokeEventOffset, processId); - unsafe.putInt(event, invokeIdFieldInInvokeEventOffset, invokeId); - unsafe.putObject(event, objectFieldInReturnEventOffset, returnObj); - } - - private static void initThrowsEvent(final ThrowsEvent event, - final int processId, - final int invokeId, - final Throwable throwable) { - unsafe.putInt(event, processIdFieldInInvokeEventOffset, processId); - unsafe.putInt(event, invokeIdFieldInInvokeEventOffset, invokeId); - unsafe.putObject(event, throwableFieldInThrowsEventOffset, throwable); - } - - private static void initLineEvent(final LineEvent event, - final int processId, - final int invokeId, - final int lineNumber) { - unsafe.putInt(event, processIdFieldInInvokeEventOffset, processId); - unsafe.putInt(event, invokeIdFieldInInvokeEventOffset, invokeId); - unsafe.putInt(event, lineNumberFieldInLineEventOffset, lineNumber); - } - - private static void initCallBeforeEvent(final CallBeforeEvent event, - final int processId, - final int invokeId, - final int lineNumber, - final String owner, - final String name, - final String desc) { - unsafe.putInt(event, processIdFieldInInvokeEventOffset, processId); - unsafe.putInt(event, invokeIdFieldInInvokeEventOffset, invokeId); - unsafe.putInt(event, lineNumberFieldInCallBeforeEventOffset, lineNumber); - unsafe.putObject(event, ownerFieldInCallBeforeEventOffset, owner); - unsafe.putObject(event, nameFieldInCallBeforeEventOffset, name); - unsafe.putObject(event, descFieldInCallBeforeEventOffset, desc); - } - - private static void initCallReturnEvent(final CallReturnEvent event, - final int processId, - final int invokeId) { - unsafe.putInt(event, processIdFieldInInvokeEventOffset, processId); - unsafe.putInt(event, invokeIdFieldInInvokeEventOffset, invokeId); - } - - private static void initCallThrowsEvent(final CallThrowsEvent event, - final int processId, - final int invokeId, - final String throwException) { - unsafe.putInt(event, processIdFieldInInvokeEventOffset, processId); - unsafe.putInt(event, invokeIdFieldInInvokeEventOffset, invokeId); - unsafe.putObject(event, throwExceptionFieldInCallThrowsEventOffset, throwException); - } - - private static class EventFactory extends BaseKeyedPooledObjectFactory { - - @Override - public Event create(Event.Type type) throws Exception { - switch (type) { - case BEFORE: - return new BeforeEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, null, null, null, null, null, null); - case THROWS: - return new ThrowsEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, null); - case RETURN: - return new ReturnEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, null); - case LINE: - return new LineEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, -1); - case IMMEDIATELY_RETURN: - return new ImmediatelyReturnEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, null); - case IMMEDIATELY_THROWS: - return new ImmediatelyThrowsEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, null); - case CALL_BEFORE: - return new CallBeforeEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, -1, null, null, null); - case CALL_RETURN: - return new CallReturnEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID); - case CALL_THROWS: - return new CallThrowsEvent(ILLEGAL_PROCESS_ID, ILLEGAL_INVOKE_ID, null); - } - throw new IllegalStateException("illegal type=" + type); - } - - @Override - public PooledObject wrap(Event event) { - return new DefaultPooledObject(event); - } - - /* - * 这里主要是释放掉引用的大资源,比如入参、返回值、抛异常等 - * 一些不大的资源其实可以保持引用,不会轻易触发GC - */ - @Override - public void passivateObject(Event.Type key, PooledObject pooledObject) throws Exception { - final Event event = pooledObject.getObject(); - switch (event.type) { - case BEFORE: - unsafe.putObject(event, targetFieldInBeforeEventOffset, null); - unsafe.putObject(event, argumentArrayFieldInBeforeEventOffset, null); - break; - case IMMEDIATELY_THROWS: - case THROWS: - unsafe.putObject(event, throwableFieldInThrowsEventOffset, null); - break; - case IMMEDIATELY_RETURN: - case RETURN: - unsafe.putObject(event, objectFieldInReturnEventOffset, null); - } - } - - } - -} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/LogbackUtils.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/LogbackUtils.java new file mode 100644 index 00000000..6493ca8a --- /dev/null +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/LogbackUtils.java @@ -0,0 +1,60 @@ +package com.alibaba.jvm.sandbox.core.util; + +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.joran.JoranConfigurator; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +import static com.alibaba.jvm.sandbox.core.util.NamespaceConvert.initNamespaceConvert; + +/** + * Logback日志框架工具类 + */ +public class LogbackUtils { + + + /** + * 初始化Logback日志框架 + * + * @param namespace 命名空间 + * @param logbackCfgFilePath logback配置文件路径 + */ + public static void init(final String namespace, + final String logbackCfgFilePath) { + final LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); + final JoranConfigurator configurator = new JoranConfigurator(); + final File configureFile = new File(logbackCfgFilePath); + configurator.setContext(loggerContext); + loggerContext.reset(); + InputStream is = null; + final Logger logger = LoggerFactory.getLogger(LoggerFactory.class); + try { + is = new FileInputStream(configureFile); + initNamespaceConvert(namespace); + configurator.doConfigure(is); + logger.info(SandboxStringUtils.getLogo()); + logger.info("initializing logback success. file={};", configureFile); + } catch (Throwable cause) { + logger.warn("initialize logback failed. file={};", configureFile, cause); + } finally { + IOUtils.closeQuietly(is); + } + } + + /** + * 销毁Logback日志框架 + */ + public static void destroy() { + try { + ((LoggerContext) LoggerFactory.getILoggerFactory()).stop(); + } catch (Throwable cause) { + cause.printStackTrace(); + } + } + +} diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/ObjectIDs.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/ObjectIDs.java index a9730d27..00a2f78c 100644 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/ObjectIDs.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/ObjectIDs.java @@ -28,7 +28,7 @@ public class ObjectIDs { /** * 对象ID序列生成器,生成范围[1,{@link Integer#MAX_VALUE}]之间的整数 */ - private final Sequencer objectIDSequencer = new Sequencer(1); + private final Sequencer objectIDSequencer = new Sequencer(); /** * 全局读写锁:用于维护世界的和平 diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SandboxReflectUtils.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SandboxReflectUtils.java index d1617804..b96d5919 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SandboxReflectUtils.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SandboxReflectUtils.java @@ -1,12 +1,16 @@ package com.alibaba.jvm.sandbox.core.util; +import com.alibaba.jvm.sandbox.api.listener.EventListener; +import com.alibaba.jvm.sandbox.core.enhance.annotation.Interrupted; + import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 反射工具类 - * Created by luanjia@taobao.com on 16/5/21. + * + * @author luanjia@taobao.com */ public class SandboxReflectUtils { @@ -118,4 +122,14 @@ public static Class defineClass(final ClassLoader loader, } + /** + * 判断是否是中断式事件处理器 + * + * @param listenerClass 事件监听器类型 + * @return TRUE:中断式;FALSE:非中断式 + */ + public static boolean isInterruptEventHandler(final Class listenerClass) { + return listenerClass.isAnnotationPresent(Interrupted.class); + } + } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SandboxStringUtils.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SandboxStringUtils.java index 5eb06502..a28a27eb 100644 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SandboxStringUtils.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SandboxStringUtils.java @@ -2,6 +2,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; +import org.objectweb.asm.Type; import java.io.IOException; import java.io.InputStream; @@ -35,7 +36,7 @@ public static String toJavaClassName(String internalClassName) { public static String[] toJavaClassNameArray(String[] internalClassNameArray) { if (null == internalClassNameArray) { - return null; + return new String[]{}; } final String[] javaClassNameArray = new String[internalClassNameArray.length]; for (int index = 0; index < internalClassNameArray.length; index++) { @@ -44,6 +45,17 @@ public static String[] toJavaClassNameArray(String[] internalClassNameArray) { return javaClassNameArray; } + public static String[] toJavaClassNameArray(Type[] asmTypeArray) { + if (null == asmTypeArray) { + return new String[]{}; + } + final String[] javaClassNameArray = new String[asmTypeArray.length]; + for (int index = 0; index < asmTypeArray.length; index++) { + javaClassNameArray[index] = asmTypeArray[index].getClassName(); + } + return javaClassNameArray; + } + /** * 获取异常的原因描述 * diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/Sequencer.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/Sequencer.java index c1ea19be..dbd591b8 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/Sequencer.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/Sequencer.java @@ -1,28 +1,23 @@ package com.alibaba.jvm.sandbox.core.util; -import java.util.concurrent.atomic.AtomicInteger; +import java.com.alibaba.jvm.sandbox.spy.Spy; /** * 序列发生器 * 序列发生器用途非常广泛,主要用于圈定全局唯一性标识 - * Created by luanjia@taobao.com on 16/5/20. + * + * @author luanjia@taobao.com */ public class Sequencer { - // 序列生成器 - private final AtomicInteger generator; - - public Sequencer(int initialValue) { - generator = new AtomicInteger(initialValue); - } - /** * 生成下一条序列 * * @return 下一条序列 */ public int next() { - return generator.getAndIncrement(); + // 这里直接修改为引用Spy的全局唯一序列,修复 #125 + return Spy.nextSequence(); } } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SpyUtils.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SpyUtils.java index cdb0d407..9d6a32db 100644 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SpyUtils.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/SpyUtils.java @@ -13,14 +13,13 @@ */ public class SpyUtils { - private static final Initializer isSpyInit = new Initializer(); /** * 初始化Spy类 * - * @throws Throwable 初始化失败 + * @param namespace 命名空间 */ - public synchronized static void init(final String namespace) throws Throwable { + public synchronized static void init(final String namespace) { if (Spy.isInit(namespace)) { return; @@ -70,4 +69,13 @@ public synchronized static void init(final String namespace) throws Throwable { } + /** + * 清理Spy中的命名空间 + * + * @param namespace 命名空间 + */ + public synchronized static void clean(final String namespace) { + Spy.clean(namespace); + } + } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/collection/ThreadUnsafeGaStack.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/collection/ThreadUnsafeGaStack.java index 9fc5fa78..31029813 100755 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/collection/ThreadUnsafeGaStack.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/collection/ThreadUnsafeGaStack.java @@ -54,7 +54,10 @@ private void checkForPopOrPeek() { public E pop() { checkForPopOrPeek(); //noinspection unchecked - return (E) elementArray[current--]; + final E e = (E) elementArray[current]; + elementArray[current] = null; + current--; + return e; } @Override @@ -91,4 +94,11 @@ public int deep() { return current + 1; } + public Object[] getElementArray() { + return elementArray; + } + + public int getCurrent() { + return current; + } } diff --git a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/matcher/ExtFilterMatcher.java b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/matcher/ExtFilterMatcher.java index 15fc99fc..4a657daf 100644 --- a/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/matcher/ExtFilterMatcher.java +++ b/sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/util/matcher/ExtFilterMatcher.java @@ -126,7 +126,7 @@ private static int toFilterAccess(final Access access) { * 兼容{@code sandbox-api:1.0.10}时 * 在{@link EventWatchCondition#getOrFilterArray()}中将{@link Filter}直接暴露出来的问题, * 所以这里做一个兼容性的强制转换 - *

+ * *

    *
  • 如果filterArray[index]是一个{@link ExtFilter},则不需要再次转换
  • *
  • 如果filterArray[index]是一个{@link Filter},则需要进行{@link ExtFilterFactory#make(Filter)}的转换
  • diff --git a/sandbox-core/src/main/resources/com/alibaba/jvm/sandbox/logo b/sandbox-core/src/main/resources/com/alibaba/jvm/sandbox/logo index b4a26f05..0983a78a 100644 --- a/sandbox-core/src/main/resources/com/alibaba/jvm/sandbox/logo +++ b/sandbox-core/src/main/resources/com/alibaba/jvm/sandbox/logo @@ -1,3 +1,4 @@ + ___ ____ __ ____ _ _ _ ____ ____ _____ __ | \ \ / / \/ | / ___| / \ | \ | | _ \| __ ) / _ \ \/ / _ | |\ \ / /| |\/| |____\___ \ / _ \ | \| | | | | _ \| | | \ / diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase.java deleted file mode 100644 index 77a6402a..00000000 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase.java +++ /dev/null @@ -1,176 +0,0 @@ -package com.alibaba.jvm.sandbox.qatest.core.enhance; - -import com.alibaba.jvm.sandbox.api.ProcessController; -import com.alibaba.jvm.sandbox.api.listener.ext.Advice; -import com.alibaba.jvm.sandbox.api.listener.ext.AdviceAdapterListener; -import com.alibaba.jvm.sandbox.api.listener.ext.AdviceListener; -import com.alibaba.jvm.sandbox.qatest.core.enhance.listener.InterruptedAdviceAdapterListener; -import com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator; -import org.junit.Test; - -import static com.alibaba.jvm.sandbox.api.event.Event.Type.*; -import static org.junit.Assert.*; - -public class AdviceTestCase extends CalculatorTestCase { - - @Test - public void test$$advice$$aroundWithError() throws Throwable { - final StringBuilder traceSB = new StringBuilder(); - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - new AdviceAdapterListener(new AdviceListener() { - - @Override - protected void before(Advice advice) throws Throwable { - traceSB.append("before;"); - throw new RuntimeException("TEST"); - } - - @Override - protected void afterReturning(Advice advice) throws Throwable { - traceSB.append("return;"); - throw new RuntimeException("TEST"); - } - }), - BEFORE, RETURN, THROWS - ); - assertEquals(30, calculatorSum(computerClass.newInstance(), 10, 20)); - assertEquals("before;return;", traceSB.toString()); - } - - @Test - public void test$$advice$$around() throws Throwable { - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - new InterruptedAdviceAdapterListener(new AdviceListener() { - - @Override - protected void before(Advice advice) throws Throwable { - assertEquals(10, ((int[])advice.getParameterArray()[0])[0]); - assertEquals(20, ((int[])advice.getParameterArray()[0])[1]); - assertTrue(advice.isProcessTop()); - assertFalse(advice.isReturn()); - assertFalse(advice.isThrows()); - } - - @Override - protected void afterReturning(Advice advice) throws Throwable { - assertEquals(30, advice.getReturnObj()); - assertTrue(advice.isProcessTop()); - assertTrue(advice.isReturn()); - assertFalse(advice.isThrows()); - } - }), - BEFORE, RETURN, THROWS - ); - assertEquals(30, calculatorSum(computerClass.newInstance(), 10, 20)); - assertEquals(30, calculatorSum(computerClass.newInstance(), 10, 20)); - } - - - @Test - public void test$$advice$$changeParameters() throws Throwable { - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - new InterruptedAdviceAdapterListener(new AdviceListener() { - - @Override - protected void before(Advice advice) throws Throwable { - assertEquals(10, ((int[])advice.getParameterArray()[0])[0]); - assertEquals(20, ((int[])advice.getParameterArray()[0])[1]); - advice.changeParameter(0, new int[]{40,60}); - } - - @Override - protected void afterReturning(Advice advice) throws Throwable { - assertEquals(40, ((int[])advice.getParameterArray()[0])[0]); - assertEquals(60, ((int[])advice.getParameterArray()[0])[1]); - assertEquals(100, advice.getReturnObj());; - } - }), - BEFORE, RETURN, THROWS - ); - assertEquals(100, calculatorSum(computerClass.newInstance(), 10, 20)); - assertEquals(100, calculatorSum(computerClass.newInstance(), 10, 20)); - } - - @Test - public void test$$advice$$changeReturnOnBefore() throws Throwable { - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - new InterruptedAdviceAdapterListener(new AdviceListener() { - - @Override - protected void before(Advice advice) throws Throwable { - assertTrue(advice.isProcessTop()); - assertEquals(10, ((int[])advice.getParameterArray()[0])[0]); - assertEquals(20, ((int[])advice.getParameterArray()[0])[1]); - ProcessController.returnImmediately(100); - } - - }), - BEFORE, RETURN, THROWS, IMMEDIATELY_RETURN, IMMEDIATELY_THROWS - ); - assertEquals(100, calculatorSum(computerClass.newInstance(), 10, 20)); - assertEquals(100, calculatorSum(computerClass.newInstance(), 10, 20)); - } - - @Test - public void test$$advice$$changeReturnOnReturn() throws Throwable { - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - new InterruptedAdviceAdapterListener(new AdviceListener() { - - @Override - protected void before(Advice advice) throws Throwable { - assertTrue(advice.isProcessTop()); - } - - @Override - protected void afterReturning(Advice advice) throws Throwable { - assertTrue(advice.isProcessTop()); - assertEquals(10, ((int[])advice.getParameterArray()[0])[0]); - assertEquals(20, ((int[])advice.getParameterArray()[0])[1]); - ProcessController.returnImmediately(100); - } - - }), - BEFORE, RETURN, THROWS, IMMEDIATELY_RETURN, IMMEDIATELY_THROWS - ); - assertEquals(100, calculatorSum(computerClass.newInstance(), 10, 20)); - assertEquals(100, calculatorSum(computerClass.newInstance(), 10, 20)); - } - - @Test - public void test$$advice$$changeReturnOnThrows() throws Throwable { - final Class computerClass = watching( - Calculator.class, - CALCULATOR_ERROR_SUM_FILTER, - new InterruptedAdviceAdapterListener(new AdviceListener() { - - @Override - protected void before(Advice advice) throws Throwable { - assertTrue(advice.isProcessTop()); - } - - @Override - protected void afterThrowing(Advice advice) throws Throwable { - assertTrue(advice.isProcessTop()); - assertEquals(10, ((int[])advice.getParameterArray()[0])[0]); - assertEquals(20, ((int[])advice.getParameterArray()[0])[1]); - ProcessController.returnImmediately(100); - } - - }), - BEFORE, RETURN, THROWS, IMMEDIATELY_RETURN, IMMEDIATELY_THROWS - ); - assertEquals(100, calculatorErrorSum(computerClass.newInstance(), 10, 20)); - assertEquals(100, calculatorErrorSum(computerClass.newInstance(), 10, 20)); - } - -} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/CalculatorTestCase.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/CalculatorTestCase.java deleted file mode 100644 index 69a577c5..00000000 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/CalculatorTestCase.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.alibaba.jvm.sandbox.qatest.core.enhance; - -import com.alibaba.jvm.sandbox.api.filter.Filter; -import com.alibaba.jvm.sandbox.api.filter.NameRegexFilter; -import com.alibaba.jvm.sandbox.core.util.UnCaughtException; - -import java.lang.reflect.InvocationTargetException; - -import static com.alibaba.jvm.sandbox.core.util.SandboxReflectUtils.unCaughtGetClassDeclaredJavaMethod; -import static com.alibaba.jvm.sandbox.core.util.SandboxReflectUtils.unCaughtInvokeMethod; - -public class CalculatorTestCase extends CoreEnhanceBaseTestCase { - - public static final Filter CALCULATOR_SUM_FILTER - = new NameRegexFilter( - "^com\\.alibaba\\.jvm.sandbox\\.qatest\\.core\\.enhance\\.target\\.Calculator$", - "^sum$" - ); - - public static final Filter CALCULATOR_SUM_and_ADD_FILTER - = new NameRegexFilter( - "^com\\.alibaba\\.jvm.sandbox\\.qatest\\.core\\.enhance\\.target\\.Calculator$", - "^(sum|add)$" - ); - - public static final Filter CALCULATOR_ERROR_SUM_FILTER - = new NameRegexFilter( - "^com\\.alibaba\\.jvm.sandbox\\.qatest\\.core\\.enhance\\.target\\.Calculator$", - "^errorSum$" - ); - - protected int calculatorSum(final Object calculatorObject, int... numArray) { - return unCaughtInvokeMethod( - unCaughtGetClassDeclaredJavaMethod(calculatorObject.getClass(), "sum", int[].class), - calculatorObject, - numArray - ); - } - - protected int calculatorErrorSum(final Object calculatorObject, int... numArray) throws Throwable { - try { - return unCaughtInvokeMethod( - unCaughtGetClassDeclaredJavaMethod(calculatorObject.getClass(), "errorSum", int[].class), - calculatorObject, - numArray - ); - } catch (Throwable cause) { - if (cause instanceof UnCaughtException - && (cause.getCause() instanceof InvocationTargetException)) { - throw ((InvocationTargetException) cause.getCause()).getTargetException(); - } - throw cause; - } - } - -} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/CalculatorTestCaseImplByAdviceListener.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/CalculatorTestCaseImplByAdviceListener.java new file mode 100644 index 00000000..a10dc9f0 --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/CalculatorTestCaseImplByAdviceListener.java @@ -0,0 +1,821 @@ +package com.alibaba.jvm.sandbox.qatest.core.enhance; + +import com.alibaba.jvm.sandbox.api.listener.ext.Advice; +import com.alibaba.jvm.sandbox.qatest.core.enhance.listener.TracingAdviceListener; +import com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator; +import com.alibaba.jvm.sandbox.qatest.core.util.JvmHelper; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.com.alibaba.jvm.sandbox.spy.Spy; + +import static com.alibaba.jvm.sandbox.api.ProcessController.returnImmediately; +import static com.alibaba.jvm.sandbox.api.ProcessController.throwsImmediately; +import static com.alibaba.jvm.sandbox.api.event.Event.Type.*; +import static com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.ERROR_EXCEPTION_MESSAGE; +import static com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.TestCase.ADD$EXCEPTION; +import static com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.TestCase.SUM$EXCEPTION; +import static com.alibaba.jvm.sandbox.qatest.core.util.CalculatorHelper.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * AdviceListener相关测试用例 + */ +public class CalculatorTestCaseImplByAdviceListener implements ICalculatorTestCase { + + @BeforeClass + public static void initSpy() { + Spy.isSpyThrowException = true; + } + + @Test + @Override + public void cal$sum$around() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_FILTER, + listener = new TracingAdviceListener() + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Override + public void cal$sum$line() throws Throwable { + + } + + @Test + @Override + public void cal$sum$call() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_FILTER, + listener = new TracingAdviceListener(), + CALL_BEFORE, CALL_RETURN,CALL_THROWS + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "CALL-BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE|96|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)", + "CALL-RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE|96|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)", + "CALL-BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE|96|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)", + "CALL-RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE|96|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum$before$changeParameters() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void before(Advice advice) throws Throwable { + super.before(advice); + advice.changeParameter(0, new int[]{40, 60}); + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum$before$returnImmediately() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_FILTER, + listener = new TracingAdviceListener() { + @Override + protected void before(Advice advice) throws Throwable { + super.before(advice); + returnImmediately(100); + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum$before$throwsImmediately() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void before(Advice advice) throws Throwable { + super.before(advice); + throwsImmediately(new Throwable(ERROR_EXCEPTION_MESSAGE)); + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + try { + sum(newInstance(calculatorClass), 10,20); + assertTrue(false); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum$return$changeParameters() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void afterReturning(Advice advice) throws Throwable{ + super.afterReturning(advice); + advice.changeParameter(0, new int[]{40, 60}); + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum$return$returnImmediately() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void afterReturning(Advice advice) throws Throwable{ + super.afterReturning(advice); + returnImmediately(100); + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum$return$throwsImmediately() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void afterReturning(Advice advice) throws Throwable { + super.afterReturning(advice); + throwsImmediately(new Throwable(ERROR_EXCEPTION_MESSAGE)); + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + try { + sum(newInstance(calculatorClass), 10,20); + assertTrue(false); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum$throws$changeParameters() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void afterThrowing(Advice advice) throws Throwable{ + super.afterThrowing(advice); + advice.changeParameter(0, new int[]{40, 60}); + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + try { + sum(newInstance(calculatorClass, SUM$EXCEPTION), 10,20); + assertTrue(false); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "THROWING|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum$throws$returnImmediately() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void afterThrowing(Advice advice) throws Throwable{ + super.afterThrowing(advice); + returnImmediately(100); + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(100, sum(newInstance(calculatorClass, SUM$EXCEPTION), 10, 20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "THROWING|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum$throws$throwsImmediately() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void afterThrowing(Advice advice) throws Throwable{ + super.afterThrowing(advice); + throwsImmediately(new Throwable(ERROR_EXCEPTION_MESSAGE)); + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + try { + sum(newInstance(calculatorClass, SUM$EXCEPTION), 10,20); + assertTrue(false); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "THROWING|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum_add$around() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingAdviceListener() + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Override + public void cal$sum_add$line() throws Throwable { + + } + + @Test + @Override + public void cal$sum_add$call() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingAdviceListener(), + CALL_BEFORE, CALL_RETURN,CALL_THROWS + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "CALL-BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE|96|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "CALL-RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE|96|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)", + "CALL-BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE|96|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "CALL-RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE|96|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum_add$before$changeParameters_at_add() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void before(Advice advice) throws Throwable { + super.before(advice); + if (advice.getBehavior().getName().equalsIgnoreCase("add")){ + advice.changeParameter(0, 40); + advice.changeParameter(1, 60); + } + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum_add$before$returnImmediately_at_add() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void before(Advice advice) throws Throwable { + super.before(advice); + if (advice.getBehavior().getName().equalsIgnoreCase("add")){ + returnImmediately(100); + } + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Override + public void cal$sum_add$before$throwsImmediately_at_add() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void before(Advice advice) throws Throwable { + super.before(advice); + if (advice.getBehavior().getName().equalsIgnoreCase("add")){ + throwsImmediately(new Throwable(ERROR_EXCEPTION_MESSAGE)); + } + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + try { + sum(newInstance(calculatorClass), 10,20); + assertTrue(false); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "THROWING|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Override + public void cal$sum_add$return$changeParameters_at_add() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void afterReturning(Advice advice) throws Throwable { + super.afterReturning(advice); + if (advice.getBehavior().getName().equalsIgnoreCase("add")){ + advice.changeParameter(0, 40); + advice.changeParameter(0, 60); + } + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum_add$return$returnImmediately_at_add() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void afterReturning(Advice advice) throws Throwable { + super.afterReturning(advice); + if (advice.getBehavior().getName().equalsIgnoreCase("add")){ + returnImmediately(100); + } + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum_add$return$throwsImmediately_at_add() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void afterReturning(Advice advice) throws Throwable { + super.afterReturning(advice); + if (advice.getBehavior().getName().equalsIgnoreCase("add")){ + throwsImmediately(new Throwable(ERROR_EXCEPTION_MESSAGE)); + } + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + try { + sum(newInstance(calculatorClass), 10,20); + assertTrue(false); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "THROWING|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$sum_add$throws$changeParameters_at_add() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void afterThrowing(Advice advice) throws Throwable { + super.afterThrowing(advice); + if (advice.getBehavior().getName().equalsIgnoreCase("add")){ + advice.changeParameter(0, 40); + advice.changeParameter(1, 60); + } + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + try { + sum(newInstance(calculatorClass, ADD$EXCEPTION), 10,20); + assertTrue(false); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "THROWING|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "THROWING|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Override + public void cal$sum_add$throws$returnImmediately_at_add() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void afterThrowing(Advice advice) throws Throwable { + super.afterThrowing(advice); + if (advice.getBehavior().getName().equalsIgnoreCase("add")){ + returnImmediately(100); + } + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "THROWING|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "THROWING|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Override + public void cal$sum_add$throws$throwsImmediately_at_add() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingAdviceListener(){ + @Override + protected void afterThrowing(Advice advice) throws Throwable { + super.afterThrowing(advice); + if (advice.getBehavior().getName().equalsIgnoreCase("add")){ + throwsImmediately(new Throwable(ERROR_EXCEPTION_MESSAGE)); + } + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + try { + sum(newInstance(calculatorClass, ADD$EXCEPTION), 10,20); + assertTrue(false); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "THROWING|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.add(int,int)|FALSE", + "THROWING|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.sum(int[])|TRUE" + ); + } + + @Test + @Override + public void cal$pow$around() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_POW_FILTER, + listener = new TracingAdviceListener() + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(25, pow(newInstance(calculatorClass), 5,2)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|TRUE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|FALSE", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|TRUE" + ); + } + + @Override + public void cal$pow$line() throws Throwable { + + } + + @Test + @Override + public void cal$pow$call() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_POW_FILTER, + listener = new TracingAdviceListener(), + CALL_BEFORE, CALL_RETURN, CALL_THROWS + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(25, pow(newInstance(calculatorClass), 5,2)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|TRUE", + "CALL-BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|TRUE|115|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|FALSE", + "CALL-BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|FALSE|115|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)", + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|FALSE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|FALSE", + "CALL-RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|FALSE|115|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|FALSE", + "CALL-RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|TRUE|115|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.pow(int,int)|TRUE" + ); + } + + @Test + @Override + public void cal$init_with_TestCase$around() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_INIT_FILTER_WITH_TEST_CASE, + listener = new TracingAdviceListener() + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.(com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator$TestCase)|TRUE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.(com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator$TestCase)|TRUE" + ); + } + + @Override + public void cal$init_with_TestCase$line() throws Throwable { + + } + + @Test + @Override + public void cal$init_with_TestCase$call() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_INIT_FILTER_WITH_TEST_CASE, + listener = new TracingAdviceListener(), + CALL_BEFORE, CALL_RETURN, CALL_THROWS + ) + ).loadClass(CALCULATOR_CLASS_NAME); + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.(com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator$TestCase)|TRUE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.(com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator$TestCase)|TRUE" + ); + } + + @Test + @Override + public void cal$init_with_TestCase$before$changeParameters() throws Throwable { + final TracingAdviceListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + new JvmHelper.Transformer( + CALCULATOR_INIT_FILTER_WITH_TEST_CASE, + listener = new TracingAdviceListener(){ + @Override + protected void before(Advice advice) throws Throwable { + super.before(advice); + advice.changeParameter(0, Calculator.TestCase.SUM$EXCEPTION); + } + } + ) + ).loadClass(CALCULATOR_CLASS_NAME); + try { + sum(newInstance(calculatorClass), 10,20); + }catch (RuntimeException e){ + assertEquals(ERROR_EXCEPTION_MESSAGE, e.getMessage()); + } + listener.assertTracing( + "BEFORE|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.(com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator$TestCase)|TRUE", + "RETURN|com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.(com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator$TestCase)|TRUE" + ); + } +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/CalculatorTestCaseImplByEventListener.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/CalculatorTestCaseImplByEventListener.java new file mode 100644 index 00000000..b56a1086 --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/CalculatorTestCaseImplByEventListener.java @@ -0,0 +1,898 @@ +package com.alibaba.jvm.sandbox.qatest.core.enhance; + +import com.alibaba.jvm.sandbox.api.event.BeforeEvent; +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.qatest.core.enhance.listener.LineNumTracingEventListener; +import com.alibaba.jvm.sandbox.qatest.core.enhance.listener.TracingEventListener; +import com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator; +import com.alibaba.jvm.sandbox.qatest.core.util.JvmHelper; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import java.com.alibaba.jvm.sandbox.spy.Spy; + +import static com.alibaba.jvm.sandbox.api.ProcessController.returnImmediately; +import static com.alibaba.jvm.sandbox.api.ProcessController.throwsImmediately; +import static com.alibaba.jvm.sandbox.api.event.Event.Type.*; +import static com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.ERROR_EXCEPTION_MESSAGE; +import static com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.TestCase.ADD$EXCEPTION; +import static com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.TestCase.SUM$EXCEPTION; +import static com.alibaba.jvm.sandbox.qatest.core.util.CalculatorHelper.*; +import static org.junit.Assert.assertEquals; + +public class CalculatorTestCaseImplByEventListener implements ICalculatorTestCase { + + @BeforeClass + public static void initSpy() { + Spy.isSpyThrowException = true; + } + + @Test + @Override + public void cal$sum$around() throws Throwable { + + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_FILTER, + listener = new TracingEventListener(), + BEFORE, RETURN, THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertEventTracing( + BEFORE, + RETURN + ); + + } + + @Test + @Override + public void cal$sum$line() throws Throwable { + + final LineNumTracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_FILTER, + listener = new LineNumTracingEventListener(), + LINE + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertLIneTracing( + 91, + 94, + 95, + 96, + 95, + 96, + 95, + 98 + ); + } + + @Test + @Override + public void cal$sum$call() throws Throwable { + + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_FILTER, + listener = new TracingEventListener(), + CALL_BEFORE, CALL_RETURN, CALL_THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertEventTracing( + CALL_BEFORE, + CALL_RETURN, + CALL_BEFORE, + CALL_RETURN + ); + + } + + @Test + @Override + public void cal$sum$before$changeParameters() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + ((int[]) ((BeforeEvent) event).argumentArray[0])[0]=40; + ((int[]) ((BeforeEvent) event).argumentArray[0])[1]=60; + } + }, + BEFORE + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + listener.assertEventTracing( + BEFORE + ); + } + + @Test + @Override + public void cal$sum$before$returnImmediately() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + returnImmediately(100); + } + }, + BEFORE + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + listener.assertEventTracing( + BEFORE + ); + } + + @Test + @Override + public void cal$sum$before$throwsImmediately() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + throwsImmediately(new Throwable(ERROR_EXCEPTION_MESSAGE)); + } + }, + THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + try { + sum(newInstance(calculatorClass, SUM$EXCEPTION), 10,20); + }catch (Throwable e){ + assertEquals(ERROR_EXCEPTION_MESSAGE, e.getMessage()); + } + listener.assertEventTracing( + THROWS + ); + } + + @Test + @Override + public void cal$sum$return$changeParameters() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + returnImmediately(100); + } + }, + RETURN + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + listener.assertEventTracing( + RETURN + ); + } + + @Test + @Override + public void cal$sum$return$returnImmediately() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + returnImmediately(100); + } + }, + RETURN + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + listener.assertEventTracing( + RETURN + ); + } + + @Test + @Override + public void cal$sum$return$throwsImmediately() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + throwsImmediately(new Throwable(ERROR_EXCEPTION_MESSAGE)); + } + }, + RETURN + ) + .loadClass(CALCULATOR_CLASS_NAME); + + try { + sum(newInstance(calculatorClass), 10,20); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + listener.assertEventTracing( + RETURN + ); + } + + @Test + @Override + public void cal$sum$throws$changeParameters() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + returnImmediately(100); + } + }, + THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(100, sum(newInstance(calculatorClass, SUM$EXCEPTION), 10,20)); + listener.assertEventTracing( + THROWS + ); + } + + @Override + public void cal$sum$throws$returnImmediately() throws Throwable { + + } + + @Test + @Override + public void cal$sum$throws$throwsImmediately() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + throwsImmediately(new Throwable(ERROR_EXCEPTION_MESSAGE)); + } + }, + THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + try { + sum(newInstance(calculatorClass, SUM$EXCEPTION), 10,20); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + listener.assertEventTracing( + THROWS + ); + } + + @Test + @Override + public void cal$sum_add$around() throws Throwable { + + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingEventListener(), + BEFORE, RETURN, THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertEventTracing( + BEFORE, + BEFORE, + RETURN, + BEFORE, + RETURN, + RETURN + ); + + } + + @Test + @Override + public void cal$sum_add$line() throws Throwable { + final LineNumTracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + listener = new LineNumTracingEventListener(), + LINE + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertLIneTracing( + 91, + 94, + 95, + 96, + 78, + 81, + 95, + 96, + 78, + 81, + 95, + 98 + ); + } + + @Test + @Override + public void cal$sum_add$call() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingEventListener(), + CALL_BEFORE, CALL_RETURN, CALL_THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertEventTracing( + CALL_BEFORE, + CALL_RETURN, + CALL_BEFORE, + CALL_RETURN + ); + } + + @Test + @Override + public void cal$sum_add$before$changeParameters_at_add() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + BeforeEvent beforeEvent = (BeforeEvent) event; + if (beforeEvent.javaMethodName.equalsIgnoreCase("add")){ + beforeEvent.argumentArray[0]=20; + } + } + }, + BEFORE + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(40, sum(newInstance(calculatorClass), 10,20)); + listener.assertEventTracing( + BEFORE, + BEFORE, + BEFORE + ); + } + + @Test + @Override + public void cal$sum_add$before$returnImmediately_at_add() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + BeforeEvent beforeEvent = (BeforeEvent) event; + if (beforeEvent.javaMethodName.equalsIgnoreCase("add")){ + returnImmediately(100); + } + } + }, + BEFORE + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + listener.assertEventTracing( + BEFORE, + BEFORE, + BEFORE + ); + } + + @Test + @Override + public void cal$sum_add$before$throwsImmediately_at_add() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + BeforeEvent beforeEvent = (BeforeEvent) event; + if (beforeEvent.javaMethodName.equalsIgnoreCase("add")){ + throwsImmediately(new Throwable(ERROR_EXCEPTION_MESSAGE)); + } + } + }, + BEFORE + ) + .loadClass(CALCULATOR_CLASS_NAME); + + try{ + sum(newInstance(calculatorClass), 10,20); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + listener.assertEventTracing( + BEFORE, + BEFORE + ); + } + + @Test + @Override + public void cal$sum_add$return$changeParameters_at_add() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + if (IsSpecalMethodEnvet(event, "add")){ + returnImmediately(100); + } + } + }, + BEFORE,RETURN + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + assertEquals(true, stack.isEmpty()); + listener.assertEventTracing( + BEFORE, + BEFORE, + RETURN, + BEFORE, + RETURN, + RETURN + ); + } + + @Test + @Override + public void cal$sum_add$return$returnImmediately_at_add() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + if (IsSpecalMethodEnvet(event, "add")){ + returnImmediately(100); + } + } + }, + BEFORE,RETURN + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(100, sum(newInstance(calculatorClass), 10,20)); + assertEquals(true, stack.isEmpty()); + listener.assertEventTracing( + BEFORE, + BEFORE, + RETURN, + BEFORE, + RETURN, + RETURN + ); + } + + @Test + @Override + public void cal$sum_add$return$throwsImmediately_at_add() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + if (IsSpecalMethodEnvet(event, "add")){ + throwsImmediately(new Throwable(ERROR_EXCEPTION_MESSAGE)); + } + } + }, + BEFORE,RETURN,THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + try { + sum(newInstance(calculatorClass), 10,20); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + + assertEquals(true, stack.isEmpty()); + listener.assertEventTracing( + BEFORE, + BEFORE, + RETURN, + THROWS + ); + } + + @Test + @Override + public void cal$sum_add$throws$changeParameters_at_add() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + if (IsSpecalMethodEnvet(event, "add")){ + ((BeforeEvent)stack.peek()).argumentArray[0] = 100; + } + } + }, + BEFORE,RETURN,THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + try { + sum(newInstance(calculatorClass, ADD$EXCEPTION), 10,20); + }catch (RuntimeException throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + + assertEquals(true, stack.isEmpty()); + listener.assertEventTracing( + BEFORE, + BEFORE, + THROWS, + THROWS + ); + } + + @Test + @Override + public void cal$sum_add$throws$returnImmediately_at_add() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + if (IsSpecalMethodEnvet(event, "add")){ + returnImmediately(100); + } + } + }, + BEFORE,RETURN,THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(100, sum(newInstance(calculatorClass, ADD$EXCEPTION), 10,20)); + assertEquals(true, stack.isEmpty()); + listener.assertEventTracing( + BEFORE, + BEFORE, + THROWS, + BEFORE, + THROWS, + RETURN + ); + } + + @Test + @Override + public void cal$sum_add$throws$throwsImmediately_at_add() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + if (IsSpecalMethodEnvet(event, "add")){ + throwsImmediately(new Throwable(ERROR_EXCEPTION_MESSAGE)); + } + } + }, + BEFORE,RETURN,THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + try { + sum(newInstance(calculatorClass, ADD$EXCEPTION), 10,20); + }catch (Throwable throwable){ + assertEquals(ERROR_EXCEPTION_MESSAGE, throwable.getMessage()); + } + + assertEquals(true, stack.isEmpty()); + listener.assertEventTracing( + BEFORE, + BEFORE, + THROWS, + THROWS + ); + } + + @Test + @Override + public void cal$pow$around() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_POW_FILTER, + listener = new TracingEventListener(), + BEFORE, RETURN, THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(25, pow(newInstance(calculatorClass), 5,2)); + listener.assertEventTracing( + BEFORE, + BEFORE, + BEFORE, + RETURN, + RETURN, + RETURN + ); + } + + @Test + @Override + public void cal$pow$line() throws Throwable { + final LineNumTracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_POW_FILTER, + listener = new LineNumTracingEventListener(), + LINE + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(25, pow(newInstance(calculatorClass), 5,2)); + listener.assertLIneTracing( + 109, + 115, + 109, + 115, + 109, + 110, + 113 + ); + } + + @Test + @Override + public void cal$pow$call() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_POW_FILTER, + listener = new TracingEventListener(), + CALL_BEFORE, CALL_RETURN, CALL_THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(25, pow(newInstance(calculatorClass), 5,2)); + listener.assertEventTracing( + CALL_BEFORE, + CALL_BEFORE, + CALL_RETURN, + CALL_RETURN + ); + } + + @Test + @Override + public void cal$init_with_TestCase$around() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_INIT_FILTER, + listener = new TracingEventListener(), + BEFORE, RETURN, THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertEventTracing( + BEFORE, + RETURN, + BEFORE, + RETURN + ); + } + + @Test + @Override + public void cal$init_with_TestCase$line() throws Throwable { + final LineNumTracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_INIT_FILTER, + listener = new LineNumTracingEventListener(), + LINE + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(30, sum(newInstance(calculatorClass), 10,20)); + listener.assertLIneTracing( + 64, + 65, + 68, + 57 + ); + } + + @Ignore + @Override + public void cal$init_with_TestCase$call() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_INIT_FILTER, + listener = new TracingEventListener(), + CALL_BEFORE, CALL_RETURN, CALL_THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + assertEquals(25, pow(newInstance(calculatorClass), 5,2)); + listener.assertEventTracing( + CALL_BEFORE, + CALL_RETURN + ); + } + + @Test + @Override + public void cal$init_with_TestCase$before$changeParameters() throws Throwable { + final TracingEventListener listener; + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_INIT_FILTER_WITH_TEST_CASE, + listener = new TracingEventListener(){ + @Override + public void onEvent(Event event) throws Throwable { + super.onEvent(event); + if (event instanceof BeforeEvent){ + ((BeforeEvent) event).argumentArray[0] = Calculator.TestCase.ADD$EXCEPTION; + } + + } + }, + BEFORE, RETURN, THROWS + ) + .loadClass(CALCULATOR_CLASS_NAME); + + try { + assertEquals(-1, sum(newInstance(calculatorClass), 10,20)); + }catch (RuntimeException e){ + assertEquals(ERROR_EXCEPTION_MESSAGE, e.getMessage()); + } + + listener.assertEventTracing( + BEFORE, + RETURN + ); + } +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/CoreEnhanceBaseTestCase.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/CoreEnhanceBaseTestCase.java deleted file mode 100644 index 94f6870f..00000000 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/CoreEnhanceBaseTestCase.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.alibaba.jvm.sandbox.qatest.core.enhance; - -import com.alibaba.jvm.sandbox.api.event.Event; -import com.alibaba.jvm.sandbox.api.filter.ExtFilter; -import com.alibaba.jvm.sandbox.api.filter.Filter; -import com.alibaba.jvm.sandbox.api.listener.EventListener; -import com.alibaba.jvm.sandbox.core.CoreConfigure; -import com.alibaba.jvm.sandbox.core.enhance.EventEnhancer; -import com.alibaba.jvm.sandbox.core.enhance.weaver.EventListenerHandlers; -import com.alibaba.jvm.sandbox.core.util.SandboxReflectUtils; -import com.alibaba.jvm.sandbox.core.util.matcher.ExtFilterMatcher; -import com.alibaba.jvm.sandbox.core.util.matcher.structure.ClassStructureImplByJDK; -import org.apache.commons.lang3.StringUtils; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -import static com.alibaba.jvm.sandbox.qatest.core.util.QaClassUtils.toByteArray; -import static com.alibaba.jvm.sandbox.qatest.core.util.QaClassUtils.toResourceName; - -public class CoreEnhanceBaseTestCase { - - private static final AtomicInteger LISTENER_ID_SEQ = new AtomicInteger(1000); - - private class TestClassLoader extends ClassLoader { - - private final Map javaClassByteArrayMap - = new HashMap(); - - @Override - protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - final Class loadedClass = findLoadedClass(name); - if (loadedClass == null) { - try { - final Class aClass = findClass(name); - if (resolve) { - resolveClass(aClass); - } - return aClass; - } catch (Exception e) { - return super.loadClass(name, resolve); - } - } else { - return loadedClass; - } - } - - public Class defineClass(final String javaClassName, - final byte[] classByteArray) throws InvocationTargetException, IllegalAccessException { - javaClassByteArrayMap.put(toResourceName(javaClassName), classByteArray); - return SandboxReflectUtils.defineClass(this, javaClassName, classByteArray); - } - - @Override - public InputStream getResourceAsStream(String name) { - if(javaClassByteArrayMap.containsKey(name)) { - return new ByteArrayInputStream(javaClassByteArrayMap.get(name)); - } - return super.getResourceAsStream(name); - } - - } - - /** - * 构造TestClassLoader,用于完成隔离测试 - * - * @return TestClassLoader - */ - protected TestClassLoader newTestClassLoader() { - return new TestClassLoader(); - } - - protected Class watchingWithNamespace(final String namespace, - final Class targetClass, - final Filter filter, - final EventListener listener, - final Event.Type... eventType) throws IOException, InvocationTargetException, IllegalAccessException { - final int listenerId = LISTENER_ID_SEQ.getAndIncrement(); - final TestClassLoader loader = newTestClassLoader(); - final CoreConfigure coreCfg = CoreConfigure.toConfigure( - StringUtils.isBlank(namespace) - ? "" - : String.format(";namespace=%s;", namespace), - "" - ); - EventListenerHandlers.getSingleton().active(listenerId, listener, eventType); - return loader.defineClass( - targetClass.getName(), - new EventEnhancer().toByteCodeArray( - loader, - toByteArray(targetClass), - new ExtFilterMatcher(ExtFilter.ExtFilterFactory.make(filter)) - .matching(new ClassStructureImplByJDK(targetClass)) - .getBehaviorSignCodes(), - coreCfg.getNamespace(), - listenerId, - eventType - )//new - );//return - } - - protected Class watching(final Class targetClass, - final Filter filter, - final EventListener listener, - final Event.Type... eventType) throws IOException, InvocationTargetException, IllegalAccessException { - return watchingWithNamespace( - null, - targetClass, - filter, - listener, - eventType - ); - } - -} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase.java deleted file mode 100644 index 7f8deee8..00000000 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.alibaba.jvm.sandbox.qatest.core.enhance; - -import com.alibaba.jvm.sandbox.api.ProcessController; -import com.alibaba.jvm.sandbox.api.event.BeforeEvent; -import com.alibaba.jvm.sandbox.api.event.Event; -import com.alibaba.jvm.sandbox.api.event.InvokeEvent; -import com.alibaba.jvm.sandbox.qatest.core.enhance.listener.InterruptedEventListener; -import com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator; -import org.junit.Test; - -import java.util.Stack; - -import static com.alibaba.jvm.sandbox.api.event.Event.Type.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class EventStackTestCase extends CalculatorTestCase { - - @Test - public void test$$stack$$around() throws Throwable { - final Stack processStack = new Stack(); - final Stack invokeStack = new Stack(); - - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_and_ADD_FILTER, - new InterruptedEventListener() { - @Override - public void onEvent(Event event) throws Throwable { - switch (event.type) { - case BEFORE: - final BeforeEvent beforeEvent = (BeforeEvent) event; - processStack.push(beforeEvent.processId); - invokeStack.push(beforeEvent.invokeId); - break; - default: - InvokeEvent invokeEvent = (InvokeEvent) event; - assertEquals(processStack.pop().intValue(), invokeEvent.processId); - assertEquals(invokeStack.pop().intValue(), invokeEvent.invokeId); - } - - } - - }, - BEFORE, RETURN, THROWS - ); - assertEquals(30, calculatorSum(computerClass.newInstance(), 10, 20)); - assertTrue(processStack.isEmpty()); - assertTrue(invokeStack.isEmpty()); - assertEquals(30, calculatorSum(computerClass.newInstance(), 10, 20)); - assertTrue(processStack.isEmpty()); - assertTrue(invokeStack.isEmpty()); - } - - @Test - public void test$$stack$$returnImmediatelyOnBefore() throws Throwable { - final Stack processStack = new Stack(); - final Stack invokeStack = new Stack(); - - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_and_ADD_FILTER, - new InterruptedEventListener() { - @Override - public void onEvent(Event event) throws Throwable { - switch (event.type) { - case BEFORE: - final BeforeEvent beforeEvent = (BeforeEvent) event; - processStack.push(beforeEvent.processId); - invokeStack.push(beforeEvent.invokeId); - if (beforeEvent.javaMethodName.equals("add")) { - ProcessController.returnImmediately(30); - } - break; - default: - InvokeEvent invokeEvent = (InvokeEvent) event; - assertEquals(processStack.pop().intValue(), invokeEvent.processId); - assertEquals(invokeStack.pop().intValue(), invokeEvent.invokeId); - } - - } - - }, - BEFORE, RETURN, THROWS, IMMEDIATELY_THROWS, IMMEDIATELY_RETURN - ); - assertEquals(30, calculatorSum(computerClass.newInstance(), 10, 20)); - assertTrue(processStack.isEmpty()); - assertTrue(invokeStack.isEmpty()); - assertEquals(30, calculatorSum(computerClass.newInstance(), 10, 20)); - assertTrue(processStack.isEmpty()); - assertTrue(invokeStack.isEmpty()); - } - - @Test - public void test$$stack$$returnImmediatelyOnReturn() throws Throwable { - final Stack processStack = new Stack(); - final Stack invokeStack = new Stack(); - - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_and_ADD_FILTER, - new InterruptedEventListener() { - boolean isIReturn = false; - - @Override - public void onEvent(Event event) throws Throwable { - switch (event.type) { - case BEFORE: - final BeforeEvent beforeEvent = (BeforeEvent) event; - processStack.push(beforeEvent.processId); - invokeStack.push(beforeEvent.invokeId); - if (beforeEvent.javaMethodName.equals("add")) { - isIReturn = true; - } - break; - default: - InvokeEvent invokeEvent = (InvokeEvent) event; - assertEquals(processStack.pop().intValue(), invokeEvent.processId); - assertEquals(invokeStack.pop().intValue(), invokeEvent.invokeId); - if (isIReturn) { - ProcessController.returnImmediately(100); - } - } - - } - - }, - BEFORE, RETURN, THROWS - ); - assertEquals(100, calculatorSum(computerClass.newInstance(), 10, 20)); - assertTrue(processStack.isEmpty()); - assertTrue(invokeStack.isEmpty()); -// assertEquals(100, calculatorSum(computerClass.newInstance(), 10, 20)); -// assertTrue(processStack.isEmpty()); -// assertTrue(invokeStack.isEmpty()); - } - -} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStreamTestCase.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStreamTestCase.java deleted file mode 100644 index 42d21f1f..00000000 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStreamTestCase.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.alibaba.jvm.sandbox.qatest.core.enhance; - -import com.alibaba.jvm.sandbox.api.event.Event; -import com.alibaba.jvm.sandbox.qatest.core.enhance.listener.EventStreamCheckerListener; -import com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator; -import org.junit.Assert; -import org.junit.Test; - -import static com.alibaba.jvm.sandbox.api.event.Event.Type.*; -import static com.alibaba.jvm.sandbox.qatest.core.enhance.listener.EventStreamCheckerListener.EventTypeChecker.*; - -/** - * 测试方法调用事件流是否正确 - */ -public class EventStreamTestCase extends CalculatorTestCase { - - @Test - public void test$$event_stream$$normal() throws Throwable { - final EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - listener = new EventStreamCheckerListener() - .nextEventCheck(BEFORE_CHECKER) - .nextEventCheck(RETURN_CHECKER), - BEFORE, RETURN, THROWS - ); - - Assert.assertEquals(2, calculatorSum(computerClass.newInstance(), 1, 1)); - listener.assertIsEmpty(); - } - - - @Test - public void test$$event_stream$$call() throws Throwable { - final EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - listener = new EventStreamCheckerListener() - .nextEventCheck(BEFORE_CHECKER) - .nextEventCheck(CALL_BEFORE_CHECKER) - .nextEventCheck(CALL_RETURN_CHECKER) - .nextEventCheck(CALL_BEFORE_CHECKER) - .nextEventCheck(CALL_RETURN_CHECKER) - .nextEventCheck(RETURN_CHECKER), - BEFORE, RETURN, THROWS, CALL_BEFORE, CALL_RETURN, CALL_THROWS - ); - - Assert.assertEquals(2, calculatorSum(computerClass.newInstance(), 1, 1)); - listener.assertIsEmpty(); - } - - @Test - public void test$$event_stream$$line() throws Throwable { - final EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - listener = new EventStreamCheckerListener() - .nextEventCheck(BEFORE_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(RETURN_CHECKER), - BEFORE, RETURN, THROWS, LINE - ); - - Assert.assertEquals(2, calculatorSum(computerClass.newInstance(), 1, 1)); - listener.assertIsEmpty(); - } - - @Test - public void test$$event_stream$$all() throws Throwable { - final EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - listener = new EventStreamCheckerListener() - .nextEventCheck(BEFORE_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(CALL_BEFORE_CHECKER) - .nextEventCheck(CALL_RETURN_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(CALL_BEFORE_CHECKER) - .nextEventCheck(CALL_RETURN_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(LINE_CHECKER) - .nextEventCheck(RETURN_CHECKER), - Event.Type.values() - ); - - Assert.assertEquals(2, calculatorSum(computerClass.newInstance(), 1, 1)); - listener.assertIsEmpty(); - } - -} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase.java deleted file mode 100644 index 7c1aea30..00000000 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.alibaba.jvm.sandbox.qatest.core.enhance; - -import com.alibaba.jvm.sandbox.api.event.*; -import com.alibaba.jvm.sandbox.qatest.core.enhance.listener.EventStreamCheckerListener; -import com.alibaba.jvm.sandbox.qatest.core.enhance.listener.EventStreamCheckerListener.EventChecker; -import com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator; -import org.junit.Test; - -import static com.alibaba.jvm.sandbox.api.event.Event.Type.*; -import static com.alibaba.jvm.sandbox.qatest.core.enhance.listener.EventStreamCheckerListener.EventTypeChecker.CALL_RETURN_CHECKER; -import static org.junit.Assert.*; - -/** - * 测试事件内容是否正确 - */ -public class EventTestCase extends CalculatorTestCase { - - @Test - public void test$$event$$before() throws Throwable { - EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - listener = new EventStreamCheckerListener().nextEventCheck(new EventChecker() { - @Override - public void onCheck(BeforeEvent event) { - assertEquals(BEFORE, event.type); - assertEquals(1, event.argumentArray.length); - assertNotNull(event.javaClassLoader); - assertEquals(Calculator.class.getName(), event.javaClassName); - assertEquals("sum", event.javaMethodName); - assertNull(event.target); - assertEquals(int[].class, event.argumentArray[0].getClass()); - assertEquals(10, ((int[]) event.argumentArray[0])[0]); - assertEquals(20, ((int[]) event.argumentArray[0])[1]); - } - }), - BEFORE - ); - assertEquals(30, calculatorSum(computerClass.newInstance(), 10, 20)); - listener.assertIsEmpty(); - } - - @Test - public void test$$event$$return() throws Throwable { - EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - listener = new EventStreamCheckerListener().nextEventCheck(new EventChecker() { - @Override - public void onCheck(ReturnEvent event) { - assertEquals(RETURN, event.type); - assertEquals(30, event.object); - } - }), - RETURN - ); - assertEquals(30, calculatorSum(computerClass.newInstance(), 10, 20)); - listener.assertIsEmpty(); - } - - - @Test(expected = RuntimeException.class) - public void test$$event$$throws() throws Throwable { - EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_ERROR_SUM_FILTER, - listener = new EventStreamCheckerListener().nextEventCheck(new EventChecker() { - @Override - public void onCheck(ThrowsEvent event) { - assertEquals(THROWS, event.type); - assertEquals(RuntimeException.class, event.throwable.getClass()); - assertEquals("THIS IS A TEST!", event.throwable.getMessage()); - } - }), - THROWS - ); - assertCalculatorErrorSum(listener, computerClass); - } - - private void assertCalculatorErrorSum(EventStreamCheckerListener listener, Class computerClass) throws Throwable { - try { - calculatorErrorSum(computerClass.newInstance(), 10, 20); - assertFalse("must throw exception", true); - } catch (RuntimeException cause) { - assertEquals("THIS IS A TEST!", cause.getMessage()); - listener.assertIsEmpty(); - throw cause; - } - } - - @Test - public void test$$event$$call_before() throws Throwable { - - final EventChecker callBeforeEventEventChecker = new EventChecker() { - @Override - public void onCheck(CallBeforeEvent event) { - assertEquals(CALL_BEFORE, event.type); - assertEquals(Calculator.class.getName(), event.owner); - assertEquals("add", event.name); - assertEquals("(II)I", event.desc); - assertEquals(8, event.lineNumber); - } - }; - - EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - listener = new EventStreamCheckerListener() - .nextEventCheck(callBeforeEventEventChecker) - .nextEventCheck(callBeforeEventEventChecker), - CALL_BEFORE - ); - assertEquals(30, calculatorSum(computerClass.newInstance(), 10, 20)); - listener.assertIsEmpty(); - } - - @Test - public void test$$event$$call_return() throws Throwable { - EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - listener = new EventStreamCheckerListener() - .nextEventCheck(CALL_RETURN_CHECKER) - .nextEventCheck(CALL_RETURN_CHECKER), - CALL_RETURN - ); - assertEquals(30, calculatorSum(computerClass.newInstance(), 10, 20)); - listener.assertIsEmpty(); - } - - @Test(expected = RuntimeException.class) - public void test$$event$$call_throws() throws Throwable { - final EventChecker callThrowsEventEventChecker = new EventChecker() { - @Override - public void onCheck(CallThrowsEvent event) { - assertEquals(CALL_THROWS, event.type); - assertEquals(RuntimeException.class.getName(), event.throwException); - } - }; - - EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_ERROR_SUM_FILTER, - listener = new EventStreamCheckerListener() - .nextEventCheck(callThrowsEventEventChecker), - CALL_THROWS - ); - assertCalculatorErrorSum(listener, computerClass); - } - - - private class LineEventChecker implements EventChecker { - - private final int lineNumber; - - private LineEventChecker(int lineNumber) { - this.lineNumber = lineNumber; - } - - @Override - public void onCheck(LineEvent event) { - assertEquals(LINE, event.type); - assertEquals(lineNumber, event.lineNumber); - } - } - - @Test - public void test$$event$$line() throws Throwable { - EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - listener = new EventStreamCheckerListener() - .nextEventCheck(new LineEventChecker(6)) - .nextEventCheck(new LineEventChecker(7)) - .nextEventCheck(new LineEventChecker(8)) - .nextEventCheck(new LineEventChecker(7)) - .nextEventCheck(new LineEventChecker(8)) - .nextEventCheck(new LineEventChecker(7)) - .nextEventCheck(new LineEventChecker(10)) - , - LINE - ); - assertEquals(30, calculatorSum(computerClass.newInstance(), 10, 20)); - listener.assertIsEmpty(); - } - -} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/ICalculatorTestCase.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/ICalculatorTestCase.java new file mode 100644 index 00000000..1ab2463a --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/ICalculatorTestCase.java @@ -0,0 +1,240 @@ +package com.alibaba.jvm.sandbox.qatest.core.enhance; + +/** + * Calculator类测试用例接口 + *

    + * 用例命名规范:{@code <类名>$<方法名>[_方法名]$<执行时机>$<执行动作>[_执行动作]} + *

    + * 例子:{@code cal$sum$before$changeParameters} : cal.sum()方法执行之前修改参数 + */ +public interface ICalculatorTestCase { + + // ------ sum() ------- + + /** + * cal.sum():环绕 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum$around() throws Throwable; + + /** + * cal.sum():行跟踪 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum$line() throws Throwable; + + /** + * cal.sum():方法调用跟踪 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum$call() throws Throwable; + + /** + * cal.sum():方法执行之前修改参数 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum$before$changeParameters() throws Throwable; + + /** + * cal.sum():方法执行之前立即返回 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum$before$returnImmediately() throws Throwable; + + /** + * cal.sum():方法执行之前立即抛出异常 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum$before$throwsImmediately() throws Throwable; + + /** + * cal.sum():返回之前修改参数 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum$return$changeParameters() throws Throwable; + + /** + * cal.sum():返回之前修改返回值 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum$return$returnImmediately() throws Throwable; + + /** + * cal.sum():返回之前抛出异常 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum$return$throwsImmediately() throws Throwable; + + /** + * cal.sum():抛出异常之前修改入参 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum$throws$changeParameters() throws Throwable; + + /** + * cal.sum():抛出异常之前立即返回 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum$throws$returnImmediately() throws Throwable; + + /** + * cal.sum():抛出异常之前立即抛出异常 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum$throws$throwsImmediately() throws Throwable; + + + // ------- sum()_add() -------- + + /** + * cal.sum()_add():环绕 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum_add$around() throws Throwable; + + /** + * cal.sum()_add():行跟踪 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum_add$line() throws Throwable; + + /** + * cal.sum()_add():方法调用跟踪 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum_add$call() throws Throwable; + + /** + * cal.sum()_add():方法执行之前修改参数 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum_add$before$changeParameters_at_add() throws Throwable; + + /** + * cal.sum()_add():方法执行之前立即返回 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum_add$before$returnImmediately_at_add() throws Throwable; + + /** + * sum()_add():方法执行之前立即抛出异常 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum_add$before$throwsImmediately_at_add() throws Throwable; + + /** + * cal.sum()_add():返回之前修改参数 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum_add$return$changeParameters_at_add() throws Throwable; + + /** + * cal.sum()_add():返回之前修改返回值 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum_add$return$returnImmediately_at_add() throws Throwable; + + /** + * cal.sum()_add():返回之前抛出异常 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum_add$return$throwsImmediately_at_add() throws Throwable; + + /** + * cal.sum()_add():抛出异常之前修改入参 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum_add$throws$changeParameters_at_add() throws Throwable; + + /** + * cal.sum()_add():抛出异常之前立即返回 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum_add$throws$returnImmediately_at_add() throws Throwable; + + /** + * cal.sum()_add():抛出异常之前立即抛出异常 + * + * @throws Throwable 用例抛出异常 + */ + void cal$sum_add$throws$throwsImmediately_at_add() throws Throwable; + + + // ------- pow() ------- + + /** + * cal.pow():环绕 + * + * @throws Throwable 用例抛出异常 + */ + void cal$pow$around() throws Throwable; + + /** + * cal.pow():行跟踪 + * + * @throws Throwable 用例抛出异常 + */ + void cal$pow$line() throws Throwable; + + /** + * cal.pow():方法调用跟踪 + * + * @throws Throwable 用例抛出异常 + */ + void cal$pow$call() throws Throwable; + + + // ------- () -------- + + /** + * {@code (TestCase)}:环绕 + * + * @throws Throwable 用例抛出异常 + */ + void cal$init_with_TestCase$around() throws Throwable; + + /** + * {@code (TestCase)}:行跟踪 + * + * @throws Throwable 用例抛出异常 + */ + void cal$init_with_TestCase$line() throws Throwable; + + /** + * {@code (TestCase)}:调用跟踪 + * + * @throws Throwable 用例抛出异常 + */ + void cal$init_with_TestCase$call() throws Throwable; + + /** + * {@code (TestCase)}:改变入参 + * + * @throws Throwable 用例抛出异常 + */ + void cal$init_with_TestCase$before$changeParameters() throws Throwable; + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/NamespaceTestCase.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/NamespaceTestCase.java deleted file mode 100644 index 0ce5406b..00000000 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/NamespaceTestCase.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.alibaba.jvm.sandbox.qatest.core.enhance; - -import com.alibaba.jvm.sandbox.api.ProcessController; -import com.alibaba.jvm.sandbox.api.event.ReturnEvent; -import com.alibaba.jvm.sandbox.api.event.ThrowsEvent; -import com.alibaba.jvm.sandbox.qatest.core.enhance.listener.EventStreamCheckerListener; -import com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator; -import org.junit.Test; - -import static com.alibaba.jvm.sandbox.api.event.Event.Type.RETURN; -import static com.alibaba.jvm.sandbox.api.event.Event.Type.THROWS; -import static junit.framework.Assert.assertEquals; - -/** - * 测试Namespace - */ -public class NamespaceTestCase extends CalculatorTestCase { - - @Test - public void test$$namespace$$changeReturnThenWatching() throws Throwable { - final EventStreamCheckerListener changeReturnListener; - final Class changeReturnCalculatorClass = watchingWithNamespace( - "ns-change", - Calculator.class, - CALCULATOR_ERROR_SUM_FILTER, - changeReturnListener = new EventStreamCheckerListener().nextEventCheck(new EventStreamCheckerListener.EventChecker() { - @Override - public void onCheck(ThrowsEvent event) throws Throwable { - ProcessController.returnImmediately(100); - } - }), - THROWS - ); - - final EventStreamCheckerListener watchingListener; - final Class watchingCalculatorClass = watchingWithNamespace( - "ns-watching", - changeReturnCalculatorClass, - CALCULATOR_ERROR_SUM_FILTER, - watchingListener = new EventStreamCheckerListener().nextEventCheck(new EventStreamCheckerListener.EventChecker() { - @Override - public void onCheck(ReturnEvent event) throws Throwable { - assertEquals(event.object, 100); - } - }), - RETURN - ); - - assertEquals(100, calculatorErrorSum(watchingCalculatorClass.newInstance(), 1, 1)); - changeReturnListener.assertIsEmpty(); - watchingListener.assertIsEmpty(); - } - -} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase.java deleted file mode 100644 index b5efc014..00000000 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.alibaba.jvm.sandbox.qatest.core.enhance; - -import com.alibaba.jvm.sandbox.api.ProcessController; -import com.alibaba.jvm.sandbox.api.event.BeforeEvent; -import com.alibaba.jvm.sandbox.api.event.ReturnEvent; -import com.alibaba.jvm.sandbox.api.event.ThrowsEvent; -import com.alibaba.jvm.sandbox.qatest.core.enhance.listener.EventStreamCheckerListener; -import com.alibaba.jvm.sandbox.qatest.core.enhance.listener.EventStreamCheckerListener.EventChecker; -import com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator; -import org.junit.Test; - -import static com.alibaba.jvm.sandbox.api.event.Event.Type.*; -import static junit.framework.Assert.assertEquals; - -/** - * 事件流程控制测试用例 - */ -public class ProcessControllerTestCase extends CalculatorTestCase { - - @Test - public void test$$process_controller$$changeParameters() throws Throwable { - EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - listener = new EventStreamCheckerListener().nextEventCheck(new EventChecker() { - @Override - public void onCheck(BeforeEvent event) { - event.changeParameter(0, new int[]{40, 60}); - } - }), - BEFORE - ); - - assertEquals(100, calculatorSum(computerClass.newInstance(), 1, 1)); - listener.assertIsEmpty(); - - } - - @Test - public void test$$process_controller$$changeReturnOnBefore() throws Throwable { - EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - listener = new EventStreamCheckerListener().nextEventCheck(new EventChecker() { - @Override - public void onCheck(BeforeEvent event) throws Throwable { - ProcessController.returnImmediately(100); - } - }), - BEFORE - ); - - assertEquals(100, calculatorSum(computerClass.newInstance(), 1, 1)); - listener.assertIsEmpty(); - } - - - @Test - public void test$$process_controller$$changeReturnOnReturn() throws Throwable { - EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_SUM_FILTER, - listener = new EventStreamCheckerListener().nextEventCheck(new EventChecker() { - @Override - public void onCheck(ReturnEvent event) throws Throwable { - assertEquals(event.object, 2); - ProcessController.returnImmediately(100); - } - }), - RETURN - ); - - assertEquals(100, calculatorSum(computerClass.newInstance(), 1, 1)); - listener.assertIsEmpty(); - } - - @Test - public void test$$process_controller$$changeReturnOnThrows() throws Throwable { - EventStreamCheckerListener listener; - final Class computerClass = watching( - Calculator.class, - CALCULATOR_ERROR_SUM_FILTER, - listener = new EventStreamCheckerListener().nextEventCheck(new EventChecker() { - @Override - public void onCheck(ThrowsEvent event) throws Throwable { - ProcessController.returnImmediately(100); - } - }), - THROWS - ); - - assertEquals(100, calculatorErrorSum(computerClass.newInstance(), 1, 1)); - listener.assertIsEmpty(); - } - -} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/EventStreamCheckerListener.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/EventStreamCheckerListener.java deleted file mode 100644 index de27d5c3..00000000 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/EventStreamCheckerListener.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.alibaba.jvm.sandbox.qatest.core.enhance.listener; - -import com.alibaba.jvm.sandbox.api.event.*; -import com.alibaba.jvm.sandbox.api.listener.EventListener; -import com.alibaba.jvm.sandbox.core.enhance.annotation.Interrupted; -import org.junit.Assert; - -import java.util.LinkedList; -import java.util.Queue; - -import static org.hamcrest.core.IsEqual.equalTo; - -/** - * 事件流校验器 - */ -@Interrupted -public class EventStreamCheckerListener implements EventListener { - - private final Queue checkers = new LinkedList(); - - /** - * 下一个事件校验 - * - * @param checker 事件校验器 - * @return this - */ - public EventStreamCheckerListener nextEventCheck(EventChecker checker) { - checkers.offer(checker); - return this; - } - - @Override - public void onEvent(Event event) throws Throwable { - checkers.poll().onCheck(event); - } - - /** - * 当事件流结束时,Check队列必须为空! - */ - public void assertIsEmpty() { - Assert.assertTrue("Event checker queue is not empty!", checkers.isEmpty()); - } - - - /** - * 事件校验器 - */ - public interface EventChecker { - - /** - * 校验事件是否正确 - * - * @param event 事件 - */ - void onCheck(E event) throws Throwable; - - } - - /** - * 事件类型校验器 - * - * @param 事件 - */ - public static final class EventTypeChecker implements EventChecker { - - private final Event.Type type; - - public EventTypeChecker(Event.Type type) { - this.type = type; - } - - @Override - public void onCheck(Event event) { - Assert.assertThat("Event.Type was not match!", type, equalTo(event.type)); - } - - public static final EventTypeChecker BEFORE_CHECKER = new EventTypeChecker(Event.Type.BEFORE); - public static final EventTypeChecker RETURN_CHECKER = new EventTypeChecker(Event.Type.RETURN); - public static final EventTypeChecker THROWS_CHECKER = new EventTypeChecker(Event.Type.THROWS); - public static final EventTypeChecker CALL_BEFORE_CHECKER = new EventTypeChecker(Event.Type.CALL_BEFORE); - public static final EventTypeChecker CALL_RETURN_CHECKER = new EventTypeChecker(Event.Type.CALL_RETURN); - public static final EventTypeChecker CALL_THROWS_CHECKER = new EventTypeChecker(Event.Type.CALL_THROWS); - public static final EventTypeChecker LINE_CHECKER = new EventTypeChecker(Event.Type.LINE); - - } - -} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/InterruptedAdviceAdapterListener.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/InterruptedAdviceAdapterListener.java index ea5d0814..bacd4d87 100644 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/InterruptedAdviceAdapterListener.java +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/InterruptedAdviceAdapterListener.java @@ -9,6 +9,9 @@ public class InterruptedAdviceAdapterListener extends AdviceAdapterListener { public InterruptedAdviceAdapterListener(AdviceListener adviceListener) { super(adviceListener); + if(adviceListener instanceof TracingAdviceListener) { + ((TracingAdviceListener) adviceListener).setEventListener(this); + } } } diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/LineNumTracingEventListener.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/LineNumTracingEventListener.java new file mode 100644 index 00000000..f2dd1034 --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/LineNumTracingEventListener.java @@ -0,0 +1,54 @@ +package com.alibaba.jvm.sandbox.qatest.core.enhance.listener; + +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.api.event.LineEvent; +import com.alibaba.jvm.sandbox.core.enhance.weaver.EventListenerHandlers; +import com.alibaba.jvm.sandbox.core.util.ObjectIDs; + +import java.util.ArrayList; +import java.util.List; + +import static com.alibaba.jvm.sandbox.qatest.core.util.AssertUtils.assertArrayEquals; + +public class LineNumTracingEventListener extends InterruptedEventListener { + private final List lineTracing = new ArrayList(); + + @Override + public void onEvent(Event event) throws Throwable { + if (event instanceof LineEvent){ + LineEvent lineEvent = (LineEvent) event; + lineTracing.add(((LineEvent) event).lineNumber); + } + + } + + /** + * 获取跟踪行信息 + * + * @return 跟踪信息 + */ + public List getLineTracing() { + return lineTracing; + } + + /** + * 断言跟踪行信息 + * + * @param exceptLineNums 期待的行号 + */ + public void assertLIneTracing(final Integer... exceptLineNums) { + assertEventProcessor(); + assertArrayEquals( + exceptLineNums, + getLineTracing().toArray(new Integer[]{}) + ); + } + + // 检查内核事件处理器是否正确 + private void assertEventProcessor() { + EventListenerHandlers + .getSingleton() + .checkEventProcessor(ObjectIDs.instance.identity(this)); + } + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/TracingAdviceListener.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/TracingAdviceListener.java new file mode 100644 index 00000000..ffda505c --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/TracingAdviceListener.java @@ -0,0 +1,236 @@ +package com.alibaba.jvm.sandbox.qatest.core.enhance.listener; + +import com.alibaba.jvm.sandbox.api.listener.EventListener; +import com.alibaba.jvm.sandbox.api.listener.ext.Advice; +import com.alibaba.jvm.sandbox.api.listener.ext.AdviceListener; +import com.alibaba.jvm.sandbox.core.enhance.weaver.EventListenerHandlers; +import com.alibaba.jvm.sandbox.core.util.ObjectIDs; +import org.objectweb.asm.Type; + +import java.util.ArrayList; +import java.util.List; + +import static com.alibaba.jvm.sandbox.api.util.GaStringUtils.getJavaClassName; +import static com.alibaba.jvm.sandbox.api.util.GaStringUtils.getJavaClassNameArray; +import static com.alibaba.jvm.sandbox.core.util.SandboxStringUtils.toJavaClassNameArray; +import static com.alibaba.jvm.sandbox.qatest.core.util.AssertUtils.assertArrayEquals; +import static com.sun.tools.javac.util.StringUtils.toUpperCase; +import static org.apache.commons.lang3.StringUtils.join; + +public class TracingAdviceListener extends AdviceListener { + + public static final boolean IS_TOP = true; + public static final boolean IS_NOT_TOP = false; + + private List tracing = new ArrayList(); + + public static String generateTracing(final String prefix, + final String javaClassName, + final String javaMethodName, + final String[] parameterTypes, + final boolean isTop) { + return String.format( + "%s|%s.%s(%s)|%s", + prefix, + javaClassName, + javaMethodName, + join(parameterTypes, ","), + toUpperCase(Boolean.toString(isTop)) + ); + } + + public static String generateTracing(final String prefix, + final String javaClassName, + final String javaMethodName, + final String[] parameterTypes, + final boolean isTop, + final int callLineNum, + final String callJavaClassName, + final String callJavaMethodName, + final String[] callParameterTypes) { + return String.format( + "%s|%s.%s(%s)|%s|%d|%s.%s(%s)", + prefix, + javaClassName, + javaMethodName, + join(parameterTypes, ","), + toUpperCase(Boolean.toString(isTop)), + callLineNum, + callJavaClassName, + callJavaMethodName, + join(callParameterTypes, ",") + ); + } + + public static String generateTracing(final String prefix, + final String javaClassName, + final String javaMethodName, + final String[] parameterTypes, + final boolean isTop, + final int callLineNum, + final String callJavaClassName, + final String callJavaMethodName, + final String[] callParameterTypes, + final String callThrowJavaClassName) { + return String.format( + "%s|%s.%s(%s)|%s|%d|%s.%s(%s)|%s", + prefix, + javaClassName, + javaMethodName, + join(parameterTypes, ","), + toUpperCase(Boolean.toString(isTop)), + callLineNum, + callJavaClassName, + callJavaMethodName, + join(callParameterTypes, ","), + callThrowJavaClassName + ); + } + + public static String generateTracing(final String prefix, + final String javaClassName, + final String javaMethodName, + final String[] parameterTypes, + final boolean isTop, + final int lineNum) { + return String.format( + "%s|%s.%s(%s)|%s|%d|%s.%s(%s)|%s", + prefix, + javaClassName, + javaMethodName, + join(parameterTypes, ","), + toUpperCase(Boolean.toString(isTop)), + lineNum + ); + } + + @Override + protected void before(Advice advice) throws Throwable { + tracing.add(generateTracing( + "BEFORE", + getJavaClassName(advice.getBehavior().getDeclaringClass()), + advice.getBehavior().getName(), + getJavaClassNameArray(advice.getBehavior().getParameterTypes()), + advice.isProcessTop() + )); + super.before(advice); + } + + @Override + protected void afterReturning(Advice advice) throws Throwable { + tracing.add(generateTracing( + "RETURN", + getJavaClassName(advice.getBehavior().getDeclaringClass()), + advice.getBehavior().getName(), + getJavaClassNameArray(advice.getBehavior().getParameterTypes()), + advice.isProcessTop() + )); + super.afterReturning(advice); + } + + @Override + protected void afterThrowing(Advice advice) throws Throwable { + tracing.add(generateTracing( + "THROWING", + getJavaClassName(advice.getBehavior().getDeclaringClass()), + advice.getBehavior().getName(), + getJavaClassNameArray(advice.getBehavior().getParameterTypes()), + advice.isProcessTop() + )); + super.afterThrowing(advice); + } + + @Override + protected void beforeCall(Advice advice, int callLineNum, String callJavaClassName, String callJavaMethodName, String callJavaMethodDesc) { + tracing.add(generateTracing( + "CALL-BEFORE", + getJavaClassName(advice.getBehavior().getDeclaringClass()), + advice.getBehavior().getName(), + getJavaClassNameArray(advice.getBehavior().getParameterTypes()), + advice.isProcessTop(), + callLineNum, + callJavaClassName, + callJavaMethodName, + toJavaClassNameArray(Type.getMethodType(callJavaMethodDesc).getArgumentTypes()) + )); + super.beforeCall(advice, callLineNum, callJavaClassName, callJavaMethodName, callJavaMethodDesc); + } + + @Override + protected void afterCallReturning(Advice advice, int callLineNum, String callJavaClassName, String callJavaMethodName, String callJavaMethodDesc) { + tracing.add(generateTracing( + "CALL-RETURN", + getJavaClassName(advice.getBehavior().getDeclaringClass()), + advice.getBehavior().getName(), + getJavaClassNameArray(advice.getBehavior().getParameterTypes()), + advice.isProcessTop(), + callLineNum, + callJavaClassName, + callJavaMethodName, + toJavaClassNameArray(Type.getMethodType(callJavaMethodDesc).getArgumentTypes()) + )); + super.afterCallReturning(advice, callLineNum, callJavaClassName, callJavaMethodName, callJavaMethodDesc); + } + + @Override + protected void afterCallThrowing(Advice advice, int callLineNum, String callJavaClassName, String callJavaMethodName, String callJavaMethodDesc, String callThrowJavaClassName) { + tracing.add(generateTracing( + "CALL-THROWS", + getJavaClassName(advice.getBehavior().getDeclaringClass()), + advice.getBehavior().getName(), + getJavaClassNameArray(advice.getBehavior().getParameterTypes()), + advice.isProcessTop(), + callLineNum, + callJavaClassName, + callJavaMethodName, + toJavaClassNameArray(Type.getMethodType(callJavaMethodDesc).getArgumentTypes()), + callThrowJavaClassName + )); + super.afterCallThrowing(advice, callLineNum, callJavaClassName, callJavaMethodName, callJavaMethodDesc, callThrowJavaClassName); + } + + @Override + protected void beforeLine(Advice advice, int lineNum) { + tracing.add(generateTracing( + "CALL-THROWS", + getJavaClassName(advice.getBehavior().getDeclaringClass()), + advice.getBehavior().getName(), + getJavaClassNameArray(advice.getBehavior().getParameterTypes()), + advice.isProcessTop(), + lineNum + )); + super.beforeLine(advice, lineNum); + } + + public List getTracing() { + return tracing; + } + + private EventListener eventListener; + + TracingAdviceListener setEventListener(EventListener eventListener) { + this.eventListener = eventListener; + return this; + } + + /** + * 断言跟踪信息 + * + * @param exceptTracings 期待的跟踪信息 + */ + public void assertTracing(final String... exceptTracings) { + assertEventProcessor(); + assertArrayEquals( + exceptTracings, + getTracing().toArray(new String[]{}) + ); + } + + // 检查内核事件处理器是否正确 + private void assertEventProcessor() { + EventListenerHandlers + .getSingleton() + .checkEventProcessor(ObjectIDs.instance.identity(eventListener)); + } + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/TracingEventListener.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/TracingEventListener.java new file mode 100644 index 00000000..0698d2a6 --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/TracingEventListener.java @@ -0,0 +1,54 @@ +package com.alibaba.jvm.sandbox.qatest.core.enhance.listener; + +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.core.enhance.weaver.EventListenerHandlers; +import com.alibaba.jvm.sandbox.core.util.ObjectIDs; + +import java.util.ArrayList; +import java.util.List; + +import static com.alibaba.jvm.sandbox.qatest.core.util.AssertUtils.assertArrayEquals; + +/** + * 事件跟踪监听器 + */ +public class TracingEventListener extends InterruptedEventListener { + + private final List eventTracing = new ArrayList(); + + @Override + public void onEvent(Event event) throws Throwable { + eventTracing.add(event.type); + } + + /** + * 获取跟踪信息 + * + * @return 跟踪信息 + */ + public List getEventTracing() { + return eventTracing; + } + + /** + * 断言跟踪信息 + * + * @param exceptEventTypes 期待的事件类型 + */ + public void assertEventTracing(final Event.Type... exceptEventTypes) { + assertEventProcessor(); + assertArrayEquals( + exceptEventTypes, + getEventTracing().toArray(new Event.Type[]{}) + ); + } + + // 检查内核事件处理器是否正确 + private void assertEventProcessor() { + EventListenerHandlers + .getSingleton() + .checkEventProcessor(ObjectIDs.instance.identity(this)); + } + + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/target/Calculator.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/target/Calculator.java index 3d244c8c..a416b633 100644 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/target/Calculator.java +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/target/Calculator.java @@ -1,8 +1,96 @@ package com.alibaba.jvm.sandbox.qatest.core.enhance.target; +import static com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator.TestCase.*; + +/** + * 计算器类(靶机类:所有方法拦截都基于这个类进行) + */ public class Calculator { - public static int sum(int... numArray) { + public static final String ERROR_EXCEPTION_MESSAGE = "THIS IS A TEST CAME FROM CALCULATOR!"; + + /** + * 计算器异常 + */ + public static class CalculatorException extends RuntimeException { + public CalculatorException(String message) { + super(message); + } + } + + /** + * 用例场景 + */ + public enum TestCase { + + /** + * 构造函数中抛出异常 + */ + INIT_WITH_TEST_CASE$EXCEPTION, + + /** + * sum()中抛出异常 + */ + SUM$EXCEPTION, + + /** + * add()中抛出异常 + */ + ADD$EXCEPTION, + + /** + * pow()递归中最后一层递归抛出异常 + */ + POW$EXCEPTION$AT_LAST, + + /** + * 正常返回 + */ + NONE + + } + + private final TestCase tCase; + + public Calculator() { + this(NONE); + } + + public Calculator(String tCaseName) { + this(TestCase.valueOf(tCaseName)); + } + + public Calculator(TestCase tCase) { + this.tCase = tCase; + if (tCase == INIT_WITH_TEST_CASE$EXCEPTION) { + throwCalculatorException(); + } + } + + /** + * 求两数之和 + * + * @param a a + * @param b b + * @return a+b + */ + public int add(int a, int b) { + if (tCase == ADD$EXCEPTION) { + throwCalculatorException(); + } + return a + b; + } + + /** + * 求一个数组之和(嵌套方法) + * + * @param numArray 数组 + * @return 数组之和 + */ + public int sum(int... numArray) { + if (tCase == SUM$EXCEPTION) { + throwCalculatorException(); + } int r = 0; for (int n : numArray) { r = add(r, n); @@ -10,17 +98,28 @@ public static int sum(int... numArray) { return r; } - public static int add(int a, int b) { - return a + b; - } - - public static int errorSum(int... numArray) { - throwsRuntimeException("THIS IS A TEST!"); - return 0; + /** + * 求num的n次方(递归方法) + * + * @param num num + * @param n n次方 + * @return num的n次方 + */ + public int pow(int num, int n) { + if (n == 0) { + if (tCase == POW$EXCEPTION$AT_LAST) { + throwCalculatorException(); + } + return 1; + } + return num * pow(num, n - 1); } - private static void throwsRuntimeException(String message) { - throw new RuntimeException(message); + /** + * 模拟抛出异常的方法 + */ + private static void throwCalculatorException() { + throw new RuntimeException(ERROR_EXCEPTION_MESSAGE); } } diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/target/MyCalculator.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/target/MyCalculator.java new file mode 100644 index 00000000..9a1b09ee --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/target/MyCalculator.java @@ -0,0 +1,19 @@ +package com.alibaba.jvm.sandbox.qatest.core.enhance.target; + +public class MyCalculator extends Calculator { + + public MyCalculator(String tCaseName) { + super(tCaseName + .toUpperCase()); + } + + public MyCalculator() { + super(); + } + + @Override + public int sum(int... numArray) { + return super.sum(numArray); + } + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/issues/Issues125.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/issues/Issues125.java new file mode 100644 index 00000000..971a1670 --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/issues/Issues125.java @@ -0,0 +1,35 @@ +package com.alibaba.jvm.sandbox.qatest.core.issues; + +import org.junit.Test; + +/** + * 修复#125 + */ +public class Issues125 { + + /** + * 怀疑Spy被重新加载后EventListenerHandlers的计数器被重置 + */ + @Test + public void test$001() { + +// final TracingEventListener listener; +// final Class calculatorClass = JvmHelper +// .createJvm() +// .defineClass( +// Calculator.class, +// CALCULATOR_SUM_FILTER, +// listener = new TracingEventListener(), +// BEFORE, RETURN, THROWS +// ) +// .loadClass(getJavaClassName(Calculator.class)); +// +// assertEquals(20, calculatorSum(calculatorClass.newInstance(), 10, 10)); +// listener.assertEventTracing( +// BEFORE, +// RETURN +// ); + + } + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/issues/Issues130.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/issues/Issues130.java new file mode 100644 index 00000000..c1c0d10a --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/issues/Issues130.java @@ -0,0 +1,91 @@ +package com.alibaba.jvm.sandbox.qatest.core.issues; + +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.api.listener.EventListener; +import com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator; +import com.alibaba.jvm.sandbox.qatest.core.util.JvmHelper; +import org.junit.Test; + +import static com.alibaba.jvm.sandbox.api.event.Event.Type.CALL_BEFORE; +import static com.alibaba.jvm.sandbox.api.event.Event.Type.LINE; +import static com.alibaba.jvm.sandbox.qatest.core.util.CalculatorHelper.*; +import static org.junit.Assert.assertEquals; + +/** + * 修复#130 + */ +public class Issues130 { + + @Test + public void cal$sum_add$call_before() throws Throwable { + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + new EventListener() { + + @Override + public void onEvent(Event event) throws Throwable { + + } + }, + CALL_BEFORE + ) + .loadClass(CALCULATOR_CLASS_NAME); + + final Object objectOfCal = newInstance(calculatorClass); + for (int i = 0; i < 1000000; i++) { + assertEquals(30, sum(objectOfCal, 10, 20)); + } + } + + @Test + public void cal$sum_add$line() throws Throwable { + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + new EventListener() { + + @Override + public void onEvent(Event event) throws Throwable { + + } + }, + LINE + ) + .loadClass(CALCULATOR_CLASS_NAME); + + final Object objectOfCal = newInstance(calculatorClass); + for (int i = 0; i < 1000000; i++) { + assertEquals(30, sum(objectOfCal, 10, 20)); + } + } + + @Test + public void cal$sum_add$all() throws Throwable { + final Class calculatorClass = JvmHelper + .createJvm() + .defineClass( + Calculator.class, + CALCULATOR_SUM_and_ADD_FILTER, + new EventListener() { + + @Override + public void onEvent(Event event) throws Throwable { + + } + }, + Event.Type.values() + ) + .loadClass(CALCULATOR_CLASS_NAME); + + final Object objectOfCal = newInstance(calculatorClass); + for (int i = 0; i < 1000000; i++) { + assertEquals(30, sum(objectOfCal, 10, 20)); + } + } + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/issues/Issues133.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/issues/Issues133.java new file mode 100644 index 00000000..0b9b3ffa --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/issues/Issues133.java @@ -0,0 +1,22 @@ +package com.alibaba.jvm.sandbox.qatest.core.issues; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.InputStream; + +import static com.alibaba.jvm.sandbox.core.util.AsmUtils.getCommonSuperClass; + +public class Issues133 { + + @Test + public void test() { + final ClassLoader loader = getClass().getClassLoader(); + Assert.assertEquals("java/io/InputStream", getCommonSuperClass("java/io/FileInputStream", "javax/servlet/ServletInputStream", loader)); + Assert.assertEquals("java/lang/Exception", getCommonSuperClass("java/io/IOException", "javax/servlet/ServletException", loader)); + Assert.assertEquals("javax/servlet/ServletResponse", getCommonSuperClass("javax/servlet/ServletResponse", "javax/servlet/http/HttpServletResponse", loader)); + Assert.assertEquals("javax/servlet/ServletResponse", getCommonSuperClass("javax/servlet/http/HttpServletResponse", "javax/servlet/ServletResponse", loader)); + Assert.assertEquals("java/lang/Object", getCommonSuperClass("java/lang/Throwable", "java/io/FileInputStream", loader)); + } + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase.java index 467650da..4c9316d9 100644 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase.java +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase.java @@ -2,22 +2,17 @@ import com.alibaba.jvm.sandbox.api.filter.ExtFilter; import com.alibaba.jvm.sandbox.api.filter.NameRegexFilter; -import com.alibaba.jvm.sandbox.core.CoreConfigure; import com.alibaba.jvm.sandbox.core.manager.CoreLoadedClassDataSource; import com.alibaba.jvm.sandbox.core.manager.impl.DefaultLoadedClassDataSource; +import com.alibaba.jvm.sandbox.qatest.core.mock.EmptyInstrumentation; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import java.lang.instrument.ClassDefinition; -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.Instrumentation; -import java.lang.instrument.UnmodifiableClassException; import java.util.LinkedHashSet; import java.util.Set; -import java.util.jar.JarFile; -class MockLoadedClassesOnlyInstrumentation implements Instrumentation { +class MockLoadedClassesOnlyInstrumentation extends EmptyInstrumentation { final Set> loadedClasses = new LinkedHashSet>(); @@ -25,80 +20,11 @@ void regLoadedClass(Class clazz) { loadedClasses.add(clazz); } - @Override - public void addTransformer(ClassFileTransformer transformer, boolean canRetransform) { - - } - - @Override - public void addTransformer(ClassFileTransformer transformer) { - - } - - @Override - public boolean removeTransformer(ClassFileTransformer transformer) { - return false; - } - - @Override - public boolean isRetransformClassesSupported() { - return false; - } - - @Override - public void retransformClasses(Class... classes) throws UnmodifiableClassException { - - } - - @Override - public boolean isRedefineClassesSupported() { - return false; - } - - @Override - public void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException { - - } - - @Override - public boolean isModifiableClass(Class theClass) { - return false; - } - @Override public Class[] getAllLoadedClasses() { return loadedClasses.toArray(new Class[]{}); } - @Override - public Class[] getInitiatedClasses(ClassLoader loader) { - return new Class[0]; - } - - @Override - public long getObjectSize(Object objectToSize) { - return 0; - } - - @Override - public void appendToBootstrapClassLoaderSearch(JarFile jarfile) { - - } - - @Override - public void appendToSystemClassLoaderSearch(JarFile jarfile) { - - } - - @Override - public boolean isNativeMethodPrefixSupported() { - return false; - } - - @Override - public void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) { - - } } public class CoreLoadedClassDataSourceTestCase { @@ -208,7 +134,7 @@ public void methodOfHuman() { } private final CoreLoadedClassDataSource coreLoadedClassDataSource - = new DefaultLoadedClassDataSource(mockInstrumentation, CoreConfigure.toConfigure("", null)); + = new DefaultLoadedClassDataSource(mockInstrumentation, false); @Test diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase.java index c4213683..4678026b 100644 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase.java +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase.java @@ -3,18 +3,14 @@ import com.alibaba.jvm.sandbox.api.Information; import com.alibaba.jvm.sandbox.api.Module; import com.alibaba.jvm.sandbox.api.ModuleException; -import com.alibaba.jvm.sandbox.api.filter.Filter; import com.alibaba.jvm.sandbox.core.CoreConfigure; -import com.alibaba.jvm.sandbox.core.domain.CoreModule; -import com.alibaba.jvm.sandbox.core.manager.CoreLoadedClassDataSource; +import com.alibaba.jvm.sandbox.core.CoreModule; import com.alibaba.jvm.sandbox.core.manager.CoreModuleManager; -import com.alibaba.jvm.sandbox.core.manager.ModuleLifeCycleEventBus; -import com.alibaba.jvm.sandbox.core.manager.ModuleLifeCycleEventBus.Event; -import com.alibaba.jvm.sandbox.core.manager.ProviderManager; import com.alibaba.jvm.sandbox.core.manager.impl.DefaultCoreModuleManager; -import com.alibaba.jvm.sandbox.core.manager.impl.DefaultModuleLifeCycleEventBus; import com.alibaba.jvm.sandbox.core.util.FeatureCodec; -import com.alibaba.jvm.sandbox.core.util.matcher.Matcher; +import com.alibaba.jvm.sandbox.qatest.core.mock.EmptyCoreLoadedClassDataSource; +import com.alibaba.jvm.sandbox.qatest.core.mock.EmptyInstrumentation; +import com.alibaba.jvm.sandbox.qatest.core.mock.EmptyProviderManager; import com.alibaba.jvm.sandbox.qatest.core.util.SandboxModuleJarBuilder; import org.apache.commons.lang3.StringUtils; import org.junit.Assert; @@ -24,15 +20,13 @@ import java.io.File; import java.io.IOException; -import java.lang.instrument.ClassDefinition; -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.Instrumentation; -import java.lang.instrument.UnmodifiableClassException; import java.util.*; -import java.util.jar.JarFile; import static com.alibaba.jvm.sandbox.api.ModuleException.ErrorCode.MODULE_ACTIVE_ERROR; +import static com.alibaba.jvm.sandbox.qatest.core.manager.TracingLifeCycleModule.LifeCycleType.*; import static java.io.File.createTempFile; +import static org.apache.commons.lang3.ArrayUtils.getLength; +import static org.junit.Assert.assertEquals; public class CoreModuleManagerTestCase { @@ -48,177 +42,69 @@ public static class BrokenOnCInitModule implements Module { } @Information(id = "broken-on-load") - public static class BrokenOnLoadModule extends ModuleLifeCycleAdapter implements Module { + public static class BrokenOnLoadModule extends TracingLifeCycleModule implements Module { @Override public void onLoad() throws Throwable { + super.onLoad(); throw new IllegalAccessException("BROKEN-ON-LOAD"); } } @Information(id = "broken-on-unload") - public static class BrokenOnUnLoadModule extends ModuleLifeCycleAdapter implements Module { + public static class BrokenOnUnLoadModule extends TracingLifeCycleModule implements Module { @Override public void onUnload() { + super.onUnload(); throw new RuntimeException("BROKEN-ON-UNLOAD"); } } @Information(id = "broken-on-active") - public static class BrokenOnActiveModule extends ModuleLifeCycleAdapter implements Module { + public static class BrokenOnActiveModule extends TracingLifeCycleModule implements Module { @Override public void onActive() { + super.onActive(); throw new RuntimeException("BROKEN-ON-ACTIVE"); } } @Information(id = "broken-on-lazy-active", isActiveOnLoad = false) - public static class BrokenOnLazyActiveModule extends ModuleLifeCycleAdapter implements Module { + public static class BrokenOnLazyActiveModule extends TracingLifeCycleModule implements Module { @Override public void onActive() { + super.onActive(); throw new RuntimeException("BROKEN-ON-LAZY-ACTIVE"); } } @Information(id = "broken-on-frozen") - public static class BrokenOnFrozenModule extends ModuleLifeCycleAdapter implements Module { + public static class BrokenOnFrozenModule extends TracingLifeCycleModule implements Module { @Override public void onFrozen() { + super.onFrozen(); throw new RuntimeException("BROKEN-ON-FROZEN"); } } @Information(id = "broken-on-load-completed") - public static class BrokenOnLoadCompletedModule extends ModuleLifeCycleAdapter implements Module { + public static class BrokenOnLoadCompletedModule extends TracingLifeCycleModule implements Module { @Override public void loadCompleted() { + super.loadCompleted(); throw new RuntimeException("BROKEN-ON-LOAD-COMPLETED"); } } @Information(id = "normal-module") - public static class NormalModule extends ModuleLifeCycleAdapter implements Module { + public static class NormalModule extends TracingLifeCycleModule implements Module { } @Information(id = "normal-no-lazy-active-module", isActiveOnLoad = false) - public static class NormalOnLazyActiveModule extends ModuleLifeCycleAdapter implements Module { + public static class NormalOnLazyActiveModule extends TracingLifeCycleModule implements Module { } - final class EmptyInstrumentation implements Instrumentation { - - @Override - public void addTransformer(ClassFileTransformer transformer, boolean canRetransform) { - - } - - @Override - public void addTransformer(ClassFileTransformer transformer) { - - } - - @Override - public boolean removeTransformer(ClassFileTransformer transformer) { - return false; - } - - @Override - public boolean isRetransformClassesSupported() { - return false; - } - - @Override - public void retransformClasses(Class... classes) throws UnmodifiableClassException { - - } - - @Override - public boolean isRedefineClassesSupported() { - return false; - } - - @Override - public void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException { - - } - - @Override - public boolean isModifiableClass(Class theClass) { - return false; - } - - @Override - public Class[] getAllLoadedClasses() { - return new Class[0]; - } - - @Override - public Class[] getInitiatedClasses(ClassLoader loader) { - return new Class[0]; - } - - @Override - public long getObjectSize(Object objectToSize) { - return 0; - } - - @Override - public void appendToBootstrapClassLoaderSearch(JarFile jarfile) { - - } - - @Override - public void appendToSystemClassLoaderSearch(JarFile jarfile) { - - } - - @Override - public boolean isNativeMethodPrefixSupported() { - return false; - } - - @Override - public void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) { - - } - } - - final class EmptyCoreLoadedClassDataSource implements CoreLoadedClassDataSource { - - @Override - public List> findForReTransform(Matcher matcher) { - return null; - } - - @Override - public Set> list() { - return null; - } - - @Override - public Set> find(Filter filter) { - return null; - } - - @Override - public Iterator> iteratorForLoadedClasses() { - return null; - } - } - - final class EmptyProviderManager implements ProviderManager { - - @Override - public void loading(File moduleJarFile) throws Throwable { - - } - - @Override - public void loading(String uniqueId, Class moduleClass, Module module, File moduleJarFile, ClassLoader moduleClassLoader) throws Throwable { - - } - } - private CoreConfigure buildingCoreConfigureWithUserModuleLib(final File... moduleJarFileArray) { final Set moduleJarFilePathSet = new LinkedHashSet(); @@ -245,124 +131,113 @@ private File buildingModuleJarFileWithModuleClass(final File targetModuleJarFile } - @Test - public void test$$CoreModuleManager$$ModuleLifeCycle() throws IOException, ModuleException { - final File moduleJarFile = buildingModuleJarFileWithModuleClass( - createTempFile("test-", ".jar"), - NormalModule.class - ); + private void assertLoadedModule(final CoreModuleManager coreModuleManager, + final String... exceptUniqueIds) { + assertEquals(getLength(exceptUniqueIds), coreModuleManager.list().size()); + final Set actualUniqueIdSet = new LinkedHashSet(); + for (final CoreModule coreModule : coreModuleManager.list()) { + actualUniqueIdSet.add(coreModule.getUniqueId()); + } - final Queue eventQueue = new LinkedList(); - eventQueue.offer(Event.LOAD); - eventQueue.offer(Event.ACTIVE); - eventQueue.offer(Event.LOAD_COMPLETED); - - final ModuleLifeCycleEventBus moduleLifeCycleEventBus = new DefaultModuleLifeCycleEventBus(); - moduleLifeCycleEventBus.append(new ModuleLifeCycleEventBus.ModuleLifeCycleEventListener() { - @Override - public boolean onFire(CoreModule coreModule, Event event) { - Assert.assertEquals("normal-module", coreModule.getUniqueId()); - Assert.assertTrue(coreModule.getModule() instanceof Module); - Assert.assertEquals(moduleJarFile, coreModule.getJarFile()); - if (eventQueue.peek() == event) { - eventQueue.poll(); - } else { - logger.warn("expect-event={} but actual-event={}", eventQueue.peek(), event); - } - return true; - } - }); + assertEquals( + new HashSet(Arrays.asList(exceptUniqueIds)), + actualUniqueIdSet + ); + } - final CoreModuleManager coreModuleManager = new DefaultCoreModuleManager( - buildingCoreConfigureWithUserModuleLib(moduleJarFile), + private CoreModuleManager buildingCoreModuleManager(final File... moduleJarFiles) throws ModuleException { + return new DefaultCoreModuleManager( + buildingCoreConfigureWithUserModuleLib(moduleJarFiles), new EmptyInstrumentation(), - this.getClass().getClassLoader(), new EmptyCoreLoadedClassDataSource(), - moduleLifeCycleEventBus, new EmptyProviderManager() - ); + ).reset(); + } + private void assertTracingLifeCycle(final CoreModuleManager coreModuleManager, + final String uniqueId, + final TracingLifeCycleModule.LifeCycleType... exceptLifeCycleTypes) { + final TracingLifeCycleModule module = (TracingLifeCycleModule) coreModuleManager.get(uniqueId).getModule(); + module.assertTracing(exceptLifeCycleTypes); + } - // 刚完成初始化,注册好的事件应该消化完成 - { - Assert.assertEquals(1, coreModuleManager.list().size()); - Assert.assertEquals("normal-module", coreModuleManager.list().iterator().next().getUniqueId()); - Assert.assertTrue(eventQueue.isEmpty()); - } + private void assertTracingLifeCycle(final CoreModule coreModule, + final TracingLifeCycleModule.LifeCycleType... exceptLifeCycleTypes) { + final TracingLifeCycleModule module = (TracingLifeCycleModule) coreModule.getModule(); + module.assertTracing(exceptLifeCycleTypes); + } + + @Test + public void test$$CoreModuleManager$$ModuleLifeCycle() throws IOException, ModuleException { + final CoreModuleManager coreModuleManager + = buildingCoreModuleManager( + buildingModuleJarFileWithModuleClass( + createTempFile("test-", ".jar"), + NormalModule.class + )); + + assertLoadedModule(coreModuleManager, "normal-module"); + assertTracingLifeCycle( + coreModuleManager, + "normal-module", + LOAD, ACTIVE, LOAD_COMPLETED + ); // 卸载模块 - { - eventQueue.offer(Event.FROZE); - eventQueue.offer(Event.UNLOAD); - coreModuleManager.unload(coreModuleManager.get("normal-module"), false); - Assert.assertEquals(0, coreModuleManager.list().size()); - Assert.assertTrue(eventQueue.isEmpty()); - } + assertTracingLifeCycle( + coreModuleManager.unload(coreModuleManager.get("normal-module"), false), + LOAD, ACTIVE, LOAD_COMPLETED, FROZEN, UNLOAD + ); - // 重新刷新 - { - eventQueue.offer(Event.LOAD); - eventQueue.offer(Event.ACTIVE); - eventQueue.offer(Event.LOAD_COMPLETED); - coreModuleManager.flush(false); - Assert.assertEquals(1, coreModuleManager.list().size()); - Assert.assertEquals("normal-module", coreModuleManager.list().iterator().next().getUniqueId()); - Assert.assertTrue(eventQueue.isEmpty()); - } - // 冻结-激活-冻结 - { - eventQueue.offer(Event.FROZE); - eventQueue.offer(Event.ACTIVE); - eventQueue.offer(Event.FROZE); - coreModuleManager.frozen(coreModuleManager.get("normal-module"), false); - coreModuleManager.active(coreModuleManager.get("normal-module")); - coreModuleManager.frozen(coreModuleManager.get("normal-module"), false); - Assert.assertEquals(1, coreModuleManager.list().size()); - Assert.assertEquals("normal-module", coreModuleManager.list().iterator().next().getUniqueId()); - Assert.assertTrue(eventQueue.isEmpty()); - } + // 重新刷新 + coreModuleManager.flush(false); + assertLoadedModule(coreModuleManager, "normal-module"); + assertTracingLifeCycle( + coreModuleManager, + "normal-module", + LOAD, ACTIVE, LOAD_COMPLETED + ); + // 冻结-冻结-激活-激活-冻结 + coreModuleManager.frozen(coreModuleManager.get("normal-module"), false); + coreModuleManager.active(coreModuleManager.get("normal-module")); + coreModuleManager.frozen(coreModuleManager.get("normal-module"), false); + assertTracingLifeCycle( + coreModuleManager, + "normal-module", + LOAD, ACTIVE, LOAD_COMPLETED, FROZEN, ACTIVE, FROZEN + ); } @Test - public void test$$CoreModuleManager$$loading() throws IOException { - - final File moduleJarFile = buildingModuleJarFileWithModuleClass( - createTempFile("test-", ".jar"), - NormalModule.class, - BrokenOnCInitModule.class, - BrokenOnLazyActiveModule.class, - BrokenOnActiveModule.class, - BrokenOnFrozenModule.class, - BrokenOnLoadModule.class, - BrokenOnUnLoadModule.class, - BrokenOnLoadCompletedModule.class + public void test$$CoreModuleManager$$loading() throws IOException, ModuleException { + + final CoreModuleManager coreModuleManager + = buildingCoreModuleManager( + buildingModuleJarFileWithModuleClass( + createTempFile("test-", ".jar"), + NormalModule.class, + BrokenOnCInitModule.class, + BrokenOnLazyActiveModule.class, + BrokenOnActiveModule.class, + BrokenOnFrozenModule.class, + BrokenOnLoadModule.class, + BrokenOnUnLoadModule.class, + BrokenOnLoadCompletedModule.class + )); + + assertLoadedModule( + coreModuleManager, + "normal-module", + "broken-on-lazy-active", + "broken-on-unload", + "broken-on-frozen", + "broken-on-load-completed" ); - final CoreModuleManager coreModuleManager = new DefaultCoreModuleManager( - buildingCoreConfigureWithUserModuleLib(moduleJarFile), - new EmptyInstrumentation(), - this.getClass().getClassLoader(), - new EmptyCoreLoadedClassDataSource(), - new DefaultModuleLifeCycleEventBus(), - new EmptyProviderManager() - ); - - final Set uniqueIds = new LinkedHashSet(); - for (final CoreModule coreModule : coreModuleManager.list()) { - uniqueIds.add(coreModule.getUniqueId()); - } - - Assert.assertTrue(uniqueIds.contains("normal-module")); - Assert.assertTrue(uniqueIds.contains("broken-on-unload")); - Assert.assertTrue(uniqueIds.contains("broken-on-lazy-active")); - Assert.assertTrue(uniqueIds.contains("broken-on-frozen")); - Assert.assertTrue(uniqueIds.contains("broken-on-load-completed")); - Assert.assertEquals(5, uniqueIds.size()); - } @@ -379,82 +254,65 @@ public static class ModifyAnotherNormalModule implements Module { @Test public void test$$CoreModuleManager$$forceFlush() throws IOException, ModuleException { - final File normalModuleJarFile = buildingModuleJarFileWithModuleClass( - createTempFile("test-", ".jar"), - NormalModule.class - ); - final File anotherNormalModuleJarFile = buildingModuleJarFileWithModuleClass( createTempFile("test-", ".jar"), AnotherNormalModule.class ); - final CoreModuleManager coreModuleManager = new DefaultCoreModuleManager( - buildingCoreConfigureWithUserModuleLib( - normalModuleJarFile, - anotherNormalModuleJarFile + final CoreModuleManager coreModuleManager + = buildingCoreModuleManager( + buildingModuleJarFileWithModuleClass( + createTempFile("test-", ".jar"), + NormalModule.class ), - new EmptyInstrumentation(), - this.getClass().getClassLoader(), - new EmptyCoreLoadedClassDataSource(), - new DefaultModuleLifeCycleEventBus(), - new EmptyProviderManager() + anotherNormalModuleJarFile ); - final Set uniqueIds = new LinkedHashSet(); - for (final CoreModule coreModule : coreModuleManager.list()) { - uniqueIds.add(coreModule.getUniqueId()); - } - - Assert.assertTrue(uniqueIds.contains("normal-module")); - Assert.assertTrue(uniqueIds.contains("another-normal-module")); - Assert.assertEquals(2, uniqueIds.size()); + assertLoadedModule( + coreModuleManager, + "normal-module", + "another-normal-module" + ); Assert.assertTrue(anotherNormalModuleJarFile.delete()); coreModuleManager.flush(true); - Assert.assertEquals(1, coreModuleManager.list().size()); - Assert.assertEquals("normal-module", coreModuleManager.list().iterator().next().getUniqueId()); + + assertLoadedModule( + coreModuleManager, + "normal-module" + ); } @Test public void test$$CoreModuleManager$$softFlush$$delete() throws IOException, ModuleException { - final File normalModuleJarFile = buildingModuleJarFileWithModuleClass( - createTempFile("test-", ".jar"), - NormalModule.class - ); - final File anotherNormalModuleJarFile = buildingModuleJarFileWithModuleClass( createTempFile("test-", ".jar"), AnotherNormalModule.class ); - final CoreModuleManager coreModuleManager = new DefaultCoreModuleManager( - buildingCoreConfigureWithUserModuleLib( - normalModuleJarFile, - anotherNormalModuleJarFile + final CoreModuleManager coreModuleManager + = buildingCoreModuleManager( + buildingModuleJarFileWithModuleClass( + createTempFile("test-", ".jar"), + NormalModule.class ), - new EmptyInstrumentation(), - this.getClass().getClassLoader(), - new EmptyCoreLoadedClassDataSource(), - new DefaultModuleLifeCycleEventBus(), - new EmptyProviderManager() + anotherNormalModuleJarFile ); - final Set uniqueIds = new LinkedHashSet(); - for (final CoreModule coreModule : coreModuleManager.list()) { - uniqueIds.add(coreModule.getUniqueId()); - } - - Assert.assertTrue(uniqueIds.contains("normal-module")); - Assert.assertTrue(uniqueIds.contains("another-normal-module")); - Assert.assertEquals(2, uniqueIds.size()); + assertLoadedModule( + coreModuleManager, + "normal-module", + "another-normal-module" + ); Assert.assertTrue(anotherNormalModuleJarFile.delete()); coreModuleManager.flush(false); - Assert.assertEquals(1, coreModuleManager.list().size()); - Assert.assertEquals("normal-module", coreModuleManager.list().iterator().next().getUniqueId()); + assertLoadedModule( + coreModuleManager, + "normal-module" + ); } @@ -462,59 +320,42 @@ public static class ModifyAnotherNormalModule implements Module { @Test public void test$$CoreModuleManager$$softFlush$$modify() throws IOException, ModuleException { - final File normalModuleJarFile = buildingModuleJarFileWithModuleClass( - createTempFile("test-", ".jar"), - NormalModule.class - ); - final File anotherNormalModuleJarFile = buildingModuleJarFileWithModuleClass( createTempFile("test-", ".jar"), AnotherNormalModule.class ); - final CoreModuleManager coreModuleManager = new DefaultCoreModuleManager( - buildingCoreConfigureWithUserModuleLib( - normalModuleJarFile, - anotherNormalModuleJarFile + final CoreModuleManager coreModuleManager + = buildingCoreModuleManager( + buildingModuleJarFileWithModuleClass( + createTempFile("test-", ".jar"), + NormalModule.class ), - new EmptyInstrumentation(), - this.getClass().getClassLoader(), - new EmptyCoreLoadedClassDataSource(), - new DefaultModuleLifeCycleEventBus(), - new EmptyProviderManager() + anotherNormalModuleJarFile ); - { - final Set uniqueIds = new LinkedHashSet(); - for (final CoreModule coreModule : coreModuleManager.list()) { - uniqueIds.add(coreModule.getUniqueId()); - } - - Assert.assertTrue(uniqueIds.contains("normal-module")); - Assert.assertTrue(uniqueIds.contains("another-normal-module")); - Assert.assertEquals(2, uniqueIds.size()); - } + assertLoadedModule( + coreModuleManager, + "normal-module", + "another-normal-module" + ); - { - buildingModuleJarFileWithModuleClass( - anotherNormalModuleJarFile, - ModifyAnotherNormalModule.class - ); - coreModuleManager.flush(false); + buildingModuleJarFileWithModuleClass( + anotherNormalModuleJarFile, + ModifyAnotherNormalModule.class + ); + coreModuleManager.flush(false); - final Set uniqueIds = new LinkedHashSet(); - for (final CoreModule coreModule : coreModuleManager.list()) { - uniqueIds.add(coreModule.getUniqueId()); - } + assertLoadedModule( + coreModuleManager, + "normal-module", + "another-normal-module" + ); - Assert.assertTrue(uniqueIds.contains("normal-module")); - Assert.assertTrue(uniqueIds.contains("another-normal-module")); - Assert.assertEquals(2, coreModuleManager.list().size()); - Assert.assertEquals( - ModifyAnotherNormalModule.class.getName(), - coreModuleManager.get("another-normal-module").getModule().getClass().getName() - ); - } + Assert.assertEquals( + ModifyAnotherNormalModule.class.getName(), + coreModuleManager.get("another-normal-module").getModule().getClass().getName() + ); } @@ -522,25 +363,19 @@ public static class ModifyAnotherNormalModule implements Module { @Test(expected = ModuleException.class) public void test$$CoreModuleManager$$getThrowsExceptionIfNull() throws IOException, ModuleException { - final File moduleJarFile = buildingModuleJarFileWithModuleClass( - createTempFile("test-", ".jar"), - NormalModule.class, - BrokenOnCInitModule.class, - BrokenOnLazyActiveModule.class, - BrokenOnActiveModule.class, - BrokenOnFrozenModule.class, - BrokenOnLoadModule.class, - BrokenOnUnLoadModule.class, - BrokenOnLoadCompletedModule.class - ); - - final CoreModuleManager coreModuleManager = new DefaultCoreModuleManager( - buildingCoreConfigureWithUserModuleLib(moduleJarFile), - new EmptyInstrumentation(), - this.getClass().getClassLoader(), - new EmptyCoreLoadedClassDataSource(), - new DefaultModuleLifeCycleEventBus(), - new EmptyProviderManager() + final CoreModuleManager coreModuleManager + = buildingCoreModuleManager( + buildingModuleJarFileWithModuleClass( + createTempFile("test-", ".jar"), + NormalModule.class, + BrokenOnCInitModule.class, + BrokenOnLazyActiveModule.class, + BrokenOnActiveModule.class, + BrokenOnFrozenModule.class, + BrokenOnLoadModule.class, + BrokenOnUnLoadModule.class, + BrokenOnLoadCompletedModule.class + ) ); coreModuleManager.getThrowsExceptionIfNull("not-existed-module"); @@ -549,111 +384,73 @@ public static class ModifyAnotherNormalModule implements Module { @Test public void test$$CoreModuleManager$$activeOnSuccess() throws IOException, ModuleException { - final File moduleJarFile = buildingModuleJarFileWithModuleClass( - createTempFile("test-", ".jar"), - NormalOnLazyActiveModule.class + final CoreModuleManager coreModuleManager + = buildingCoreModuleManager( + buildingModuleJarFileWithModuleClass( + createTempFile("test-", ".jar"), + NormalOnLazyActiveModule.class + ) ); - - final Queue eventQueue = new LinkedList(); - eventQueue.offer(Event.LOAD); - eventQueue.offer(Event.LOAD_COMPLETED); - - final ModuleLifeCycleEventBus moduleLifeCycleEventBus = new DefaultModuleLifeCycleEventBus(); - moduleLifeCycleEventBus.append(new ModuleLifeCycleEventBus.ModuleLifeCycleEventListener() { - @Override - public boolean onFire(CoreModule coreModule, Event event) { - Assert.assertEquals("normal-no-lazy-active-module", coreModule.getUniqueId()); - Assert.assertTrue(coreModule.getModule() instanceof Module); - Assert.assertEquals(moduleJarFile, coreModule.getJarFile()); - if (eventQueue.peek() == event) { - eventQueue.poll(); - } else { - logger.warn("expect-event={} but actual-event={}", eventQueue.peek(), event); - } - return true; - } - }); - - final CoreModuleManager coreModuleManager = new DefaultCoreModuleManager( - buildingCoreConfigureWithUserModuleLib(moduleJarFile), - new EmptyInstrumentation(), - this.getClass().getClassLoader(), - new EmptyCoreLoadedClassDataSource(), - moduleLifeCycleEventBus, - new EmptyProviderManager() + assertTracingLifeCycle( + coreModuleManager, + "normal-no-lazy-active-module", + LOAD, LOAD_COMPLETED ); final CoreModule normalNoLazyActiveCoreModule = coreModuleManager .getThrowsExceptionIfNull("normal-no-lazy-active-module"); - { - eventQueue.offer(Event.ACTIVE); - coreModuleManager.active(normalNoLazyActiveCoreModule); - Assert.assertTrue(eventQueue.isEmpty()); - } + coreModuleManager.active(normalNoLazyActiveCoreModule); + assertTracingLifeCycle( + coreModuleManager, + "normal-no-lazy-active-module", + LOAD, LOAD_COMPLETED, ACTIVE + ); - { - eventQueue.offer(Event.FROZE); - coreModuleManager.frozen(normalNoLazyActiveCoreModule, false); - Assert.assertTrue(eventQueue.isEmpty()); - } + coreModuleManager.frozen(normalNoLazyActiveCoreModule, false); + assertTracingLifeCycle( + coreModuleManager, + "normal-no-lazy-active-module", + LOAD, LOAD_COMPLETED, ACTIVE, FROZEN + ); } @Test public void test$$CoreModuleManager$$activeOnFailed() throws IOException, ModuleException { - final File moduleJarFile = buildingModuleJarFileWithModuleClass( - createTempFile("test-", ".jar"), - BrokenOnLazyActiveModule.class - ); - - final Queue eventQueue = new LinkedList(); - eventQueue.offer(Event.LOAD); - eventQueue.offer(Event.LOAD_COMPLETED); - - final ModuleLifeCycleEventBus moduleLifeCycleEventBus = new DefaultModuleLifeCycleEventBus(); - moduleLifeCycleEventBus.append(new ModuleLifeCycleEventBus.ModuleLifeCycleEventListener() { - @Override - public boolean onFire(CoreModule coreModule, Event event) { - Assert.assertEquals("broken-on-lazy-active", coreModule.getUniqueId()); - Assert.assertTrue(coreModule.getModule() instanceof Module); - Assert.assertEquals(moduleJarFile, coreModule.getJarFile()); - if (eventQueue.peek() == event) { - eventQueue.poll(); - } else { - logger.warn("expect-event={} but actual-event={}", eventQueue.peek(), event); - } - return true; - } - }); + final CoreModuleManager coreModuleManager + = buildingCoreModuleManager( + buildingModuleJarFileWithModuleClass( + createTempFile("test-", ".jar"), + BrokenOnLazyActiveModule.class + ) + ); - final CoreModuleManager coreModuleManager = new DefaultCoreModuleManager( - buildingCoreConfigureWithUserModuleLib(moduleJarFile), - new EmptyInstrumentation(), - this.getClass().getClassLoader(), - new EmptyCoreLoadedClassDataSource(), - moduleLifeCycleEventBus, - new EmptyProviderManager() + assertTracingLifeCycle( + coreModuleManager, + "broken-on-lazy-active", + LOAD, LOAD_COMPLETED ); final CoreModule brokenOnLazyActiveCoreModule = coreModuleManager .getThrowsExceptionIfNull("broken-on-lazy-active"); - { - eventQueue.offer(Event.ACTIVE); - try { - coreModuleManager.active(brokenOnLazyActiveCoreModule); - }catch (ModuleException me) { - Assert.assertEquals("broken-on-lazy-active", me.getUniqueId()); - Assert.assertEquals(MODULE_ACTIVE_ERROR, me.getErrorCode()); - } - - Assert.assertFalse(eventQueue.isEmpty()); + try { + coreModuleManager.active(brokenOnLazyActiveCoreModule); + } catch (ModuleException me) { + Assert.assertEquals("broken-on-lazy-active", me.getUniqueId()); + Assert.assertEquals(MODULE_ACTIVE_ERROR, me.getErrorCode()); } + assertTracingLifeCycle( + coreModuleManager, + "broken-on-lazy-active", + LOAD, LOAD_COMPLETED, ACTIVE + ); + } diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/ModuleLifeCycleAdapter.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/ModuleLifeCycleAdapter.java deleted file mode 100644 index accff653..00000000 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/ModuleLifeCycleAdapter.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.alibaba.jvm.sandbox.qatest.core.manager; - -import com.alibaba.jvm.sandbox.api.ModuleLifecycle; - -public class ModuleLifeCycleAdapter implements ModuleLifecycle { - @Override - public void onLoad() throws Throwable { - - } - - @Override - public void onUnload() throws Throwable { - - } - - @Override - public void onActive() throws Throwable { - - } - - @Override - public void onFrozen() throws Throwable { - - } - - @Override - public void loadCompleted() { - - } -} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/TracingLifeCycleModule.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/TracingLifeCycleModule.java new file mode 100644 index 00000000..14539afa --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/manager/TracingLifeCycleModule.java @@ -0,0 +1,62 @@ +package com.alibaba.jvm.sandbox.qatest.core.manager; + +import com.alibaba.jvm.sandbox.api.Module; +import com.alibaba.jvm.sandbox.api.ModuleLifecycle; + +import java.util.ArrayList; +import java.util.List; + +import static com.alibaba.jvm.sandbox.qatest.core.util.AssertUtils.assertArrayEquals; + +/** + * 追踪生命周期管理模块 + */ +public abstract class TracingLifeCycleModule implements ModuleLifecycle, Module { + + private final List lifeCycleTypeTracings = new ArrayList(); + + @Override + public void onLoad() throws Throwable { + lifeCycleTypeTracings.add(LifeCycleType.LOAD); + } + + @Override + public void onUnload() { + lifeCycleTypeTracings.add(LifeCycleType.UNLOAD); + } + + @Override + public void onActive() { + lifeCycleTypeTracings.add(LifeCycleType.ACTIVE); + } + + @Override + public void onFrozen() { + lifeCycleTypeTracings.add(LifeCycleType.FROZEN); + } + + @Override + public void loadCompleted() { + lifeCycleTypeTracings.add(LifeCycleType.LOAD_COMPLETED); + } + + public void assertTracing(final LifeCycleType... exceptLifeCycleTypes) { + assertArrayEquals( + exceptLifeCycleTypes, + lifeCycleTypeTracings.toArray(new LifeCycleType[]{}) + ); + } + + + /** + * 生命周期类型 + */ + public enum LifeCycleType { + LOAD, + UNLOAD, + ACTIVE, + FROZEN, + LOAD_COMPLETED + } + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/mock/EmptyCoreLoadedClassDataSource.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/mock/EmptyCoreLoadedClassDataSource.java new file mode 100644 index 00000000..1d598460 --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/mock/EmptyCoreLoadedClassDataSource.java @@ -0,0 +1,32 @@ +package com.alibaba.jvm.sandbox.qatest.core.mock; + +import com.alibaba.jvm.sandbox.api.filter.Filter; +import com.alibaba.jvm.sandbox.core.manager.CoreLoadedClassDataSource; +import com.alibaba.jvm.sandbox.core.util.matcher.Matcher; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public class EmptyCoreLoadedClassDataSource implements CoreLoadedClassDataSource { + @Override + public List> findForReTransform(Matcher matcher) { + return null; + } + + @Override + public Set> list() { + return null; + } + + @Override + public Set> find(Filter filter) { + return null; + } + + @Override + public Iterator> iteratorForLoadedClasses() { + return null; + } + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/mock/EmptyInstrumentation.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/mock/EmptyInstrumentation.java new file mode 100644 index 00000000..eddeb6ee --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/mock/EmptyInstrumentation.java @@ -0,0 +1,84 @@ +package com.alibaba.jvm.sandbox.qatest.core.mock; + +import java.lang.instrument.ClassDefinition; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.Instrumentation; +import java.lang.instrument.UnmodifiableClassException; +import java.util.jar.JarFile; + +public class EmptyInstrumentation implements Instrumentation { + @Override + public void addTransformer(ClassFileTransformer transformer, boolean canRetransform) { + + } + + @Override + public void addTransformer(ClassFileTransformer transformer) { + + } + + @Override + public boolean removeTransformer(ClassFileTransformer transformer) { + return false; + } + + @Override + public boolean isRetransformClassesSupported() { + return false; + } + + @Override + public void retransformClasses(Class... classes) throws UnmodifiableClassException { + + } + + @Override + public boolean isRedefineClassesSupported() { + return false; + } + + @Override + public void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException { + + } + + @Override + public boolean isModifiableClass(Class theClass) { + return false; + } + + @Override + public Class[] getAllLoadedClasses() { + return new Class[0]; + } + + @Override + public Class[] getInitiatedClasses(ClassLoader loader) { + return new Class[0]; + } + + @Override + public long getObjectSize(Object objectToSize) { + return 0; + } + + @Override + public void appendToBootstrapClassLoaderSearch(JarFile jarfile) { + + } + + @Override + public void appendToSystemClassLoaderSearch(JarFile jarfile) { + + } + + @Override + public boolean isNativeMethodPrefixSupported() { + return false; + } + + @Override + public void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) { + + } +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/mock/EmptyProviderManager.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/mock/EmptyProviderManager.java new file mode 100644 index 00000000..57dd549b --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/mock/EmptyProviderManager.java @@ -0,0 +1,18 @@ +package com.alibaba.jvm.sandbox.qatest.core.mock; + +import com.alibaba.jvm.sandbox.api.Module; +import com.alibaba.jvm.sandbox.core.manager.ProviderManager; + +import java.io.File; + +public class EmptyProviderManager implements ProviderManager { + @Override + public void loading(File moduleJarFile) throws Throwable { + + } + + @Override + public void loading(String uniqueId, Class moduleClass, Module module, File moduleJarFile, ClassLoader moduleClassLoader) throws Throwable { + + } +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/AssertUtils.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/AssertUtils.java new file mode 100644 index 00000000..14b3b91f --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/AssertUtils.java @@ -0,0 +1,25 @@ +package com.alibaba.jvm.sandbox.qatest.core.util; + +import org.apache.commons.lang3.StringUtils; + +import static org.apache.commons.lang3.ArrayUtils.getLength; +import static org.junit.Assert.assertEquals; + +public class AssertUtils { + + public static void assertArrayEquals(E[] exceptArray, E[] actualArray) { + assertEquals( + String.format( + "except size not matched!\n\texcept:%s\n\tactual:%s", + StringUtils.join(exceptArray, ","), + StringUtils.join(actualArray, ",") + ), + getLength(exceptArray), + getLength(actualArray) + ); + for (int index = 0; index < exceptArray.length; index++) { + assertEquals("[" + index + "] not matched", exceptArray[index], actualArray[index]); + } + } + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/CalculatorHelper.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/CalculatorHelper.java new file mode 100644 index 00000000..f1cfd041 --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/CalculatorHelper.java @@ -0,0 +1,210 @@ +package com.alibaba.jvm.sandbox.qatest.core.util; + +import com.alibaba.jvm.sandbox.api.event.BeforeEvent; +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.api.event.ReturnEvent; +import com.alibaba.jvm.sandbox.api.event.ThrowsEvent; +import com.alibaba.jvm.sandbox.api.filter.Filter; +import com.alibaba.jvm.sandbox.api.filter.NameRegexFilter; +import com.alibaba.jvm.sandbox.core.util.UnCaughtException; +import com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator; +import com.alibaba.jvm.sandbox.qatest.core.enhance.target.MyCalculator; + +import java.lang.reflect.InvocationTargetException; +import java.util.Stack; + +import static com.alibaba.jvm.sandbox.api.util.GaStringUtils.getJavaClassName; +import static com.alibaba.jvm.sandbox.core.util.SandboxReflectUtils.unCaughtGetClassDeclaredJavaMethod; +import static com.alibaba.jvm.sandbox.core.util.SandboxReflectUtils.unCaughtInvokeMethod; + +/** + * 计算器辅助类 + */ +public class CalculatorHelper { + + public static final String CALCULATOR_CLASS_NAME = getJavaClassName(Calculator.class); + public static final String MY_CALCULATOR_CLASS_NAME = getJavaClassName(MyCalculator.class); + + /** + * 拦截sum()方法过滤器 + */ + public static final Filter CALCULATOR_SUM_FILTER + = new NameRegexFilter( + "^com\\.alibaba\\.jvm.sandbox\\.qatest\\.core\\.enhance\\.target\\.Calculator$", + "^sum$" + ); + + /** + * 拦截sum()和add()方法过滤器 + */ + public static final Filter CALCULATOR_SUM_and_ADD_FILTER + = new NameRegexFilter( + "^com\\.alibaba\\.jvm.sandbox\\.qatest\\.core\\.enhance\\.target\\.Calculator$", + "^(sum|add)$" + ); + + /** + * 拦截errorSum()方法过滤器 + */ + public static final Filter CALCULATOR_ERROR_SUM_FILTER + = new NameRegexFilter( + "^com\\.alibaba\\.jvm.sandbox\\.qatest\\.core\\.enhance\\.target\\.Calculator$", + "^errorSum$" + ); + + /** + * 拦截pow()方法过滤器 + */ + public static final Filter CALCULATOR_POW_FILTER + = new NameRegexFilter( + "^com\\.alibaba\\.jvm.sandbox\\.qatest\\.core\\.enhance\\.target\\.Calculator$", + "^pow" + ); + + /** + * 拦截初始化方法过滤器 + */ + public static final Filter CALCULATOR_INIT_FILTER + = new NameRegexFilter( + "^com\\.alibaba\\.jvm.sandbox\\.qatest\\.core\\.enhance\\.target\\.Calculator$", + "" + ); + + /** + * 拦截sum()方法过滤器 + */ + public static final Filter MY_CALCULATOR_SUM_FILTER + = new NameRegexFilter( + "^com\\.alibaba\\.jvm.sandbox\\.qatest\\.core\\.enhance\\.target\\.MyCalculator$", + "^sum$" + ); + + public static final Filter CALCULATOR_INIT_FILTER_WITH_TEST_CASE + = new Filter() { + @Override + public boolean doClassFilter(int access, String javaClassName, String superClassTypeJavaClassName, String[] interfaceTypeJavaClassNameArray, String[] annotationTypeJavaClassNameArray) { + return javaClassName.equalsIgnoreCase("com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator"); + } + + @Override + public boolean doMethodFilter(int access, String javaMethodName, String[] parameterTypeJavaClassNameArray, String[] throwsTypeJavaClassNameArray, String[] annotationTypeJavaClassNameArray) { + if (javaMethodName.equalsIgnoreCase("")) + return (parameterTypeJavaClassNameArray.length == 1 + &¶meterTypeJavaClassNameArray[0].equalsIgnoreCase("com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator$TestCase")); + return false; + } + }; + + // 栈 + public static Stack stack = new Stack(); + + /** + * 判断是否是指定方法的Return||Throws事件 + * @param event + * @param javaMethodeName + * @return + */ + public static boolean IsSpecalMethodEnvet(Event event, String javaMethodeName){ + + if (event instanceof BeforeEvent){ + BeforeEvent beforeEvent = new BeforeEvent( + ((BeforeEvent) event).processId, + ((BeforeEvent) event).invokeId, + ((BeforeEvent) event).javaClassLoader, + ((BeforeEvent) event).javaClassName, + ((BeforeEvent) event).javaMethodName, + ((BeforeEvent) event).javaMethodDesc, + ((BeforeEvent) event).target, + ((BeforeEvent) event).argumentArray); + stack.push(beforeEvent); + } + if (event instanceof ReturnEvent){ + Event eventEnd = stack.pop(); + return isSpecalMethod(eventEnd, javaMethodeName); + } + + if (event instanceof ThrowsEvent){ + Event eventEnd = stack.pop(); + return isSpecalMethod(eventEnd, javaMethodeName); + } + return false; + } + + public static boolean isSpecalMethod(Event event, String javaMethodeName){ + if (event instanceof BeforeEvent){ + BeforeEvent beforeEvent = (BeforeEvent) event; + if (beforeEvent.javaMethodName.equalsIgnoreCase(javaMethodeName)){ + return true; + } + } + return false; + } + + /** + * 调用sum()方法 + * + * @param calculatorObject 目标计算器对象实例 + * @param numArray 参数 + * @return 返回值 + * @throws Throwable 调用失败 + */ + public static int sum(final Object calculatorObject, int... numArray) throws Throwable { + try { + return unCaughtInvokeMethod( + unCaughtGetClassDeclaredJavaMethod(calculatorObject.getClass(), "sum", int[].class), + calculatorObject, + numArray + ); + } catch (Throwable cause) { + if (cause instanceof UnCaughtException + && (cause.getCause() instanceof InvocationTargetException)) { + throw ((InvocationTargetException) cause.getCause()).getTargetException(); + } + throw cause; + } + + } + + /** + * 调用sum()方法 + * + * @param calculatorObject pow(); + * @param num num + * @param n n次方 + * @return 返回值 + * @throws Throwable 调用失败 + */ + public static int pow(final Object calculatorObject, int num, int n) throws Throwable { + try { + return unCaughtInvokeMethod( + unCaughtGetClassDeclaredJavaMethod(calculatorObject.getClass(), "pow", int.class, int.class), + calculatorObject, + num, + n + ); + } catch (Throwable cause) { + if (cause instanceof UnCaughtException + && (cause.getCause() instanceof InvocationTargetException)) { + throw ((InvocationTargetException) cause.getCause()).getTargetException(); + } + throw cause; + } + } + + public static Object newInstance(final Class calculatorClass) throws Throwable { + try { + return calculatorClass.getConstructor().newInstance(); + } catch (InvocationTargetException cause) { + throw cause.getTargetException(); + } + } + + public static Object newInstance(final Class calculatorClass, final Calculator.TestCase tCase) throws Throwable { + try { + return calculatorClass.getConstructor(String.class).newInstance(tCase.name()); + } catch (InvocationTargetException cause) { + throw cause.getTargetException(); + } + } + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/JvmHelper.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/JvmHelper.java new file mode 100644 index 00000000..3a4a3a15 --- /dev/null +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/JvmHelper.java @@ -0,0 +1,225 @@ +package com.alibaba.jvm.sandbox.qatest.core.util; + +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.api.filter.Filter; +import com.alibaba.jvm.sandbox.api.listener.EventListener; +import com.alibaba.jvm.sandbox.api.listener.ext.AdviceListener; +import com.alibaba.jvm.sandbox.core.enhance.EventEnhancer; +import com.alibaba.jvm.sandbox.core.enhance.weaver.EventListenerHandlers; +import com.alibaba.jvm.sandbox.core.util.ObjectIDs; +import com.alibaba.jvm.sandbox.core.util.SandboxReflectUtils; +import com.alibaba.jvm.sandbox.core.util.SpyUtils; +import com.alibaba.jvm.sandbox.core.util.matcher.ExtFilterMatcher; +import com.alibaba.jvm.sandbox.core.util.matcher.MatchingResult; +import com.alibaba.jvm.sandbox.core.util.matcher.structure.ClassStructureFactory; +import com.alibaba.jvm.sandbox.qatest.core.enhance.listener.InterruptedAdviceAdapterListener; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.*; + +import static com.alibaba.jvm.sandbox.api.event.Event.Type.*; +import static com.alibaba.jvm.sandbox.api.filter.ExtFilter.ExtFilterFactory.make; +import static com.alibaba.jvm.sandbox.api.util.GaStringUtils.getJavaClassName; +import static com.alibaba.jvm.sandbox.core.CoreConfigure.toConfigure; +import static com.alibaba.jvm.sandbox.qatest.core.util.QaClassUtils.toByteArray; +import static com.alibaba.jvm.sandbox.qatest.core.util.QaClassUtils.toResourceName; +import static org.apache.commons.lang3.ArrayUtils.toArray; + +/** + * JVM帮助类,能模拟一个JVM对类的管理行为 + */ +public class JvmHelper { + + private final String namespace; + private final PrivateClassLoader classLoader + = new PrivateClassLoader(); + + public JvmHelper(final String namespace) { + this.namespace = namespace; + SpyUtils.init(namespace); + toConfigure(String.format(";namespace=%s;", namespace), ""); + } + + public JvmHelper defineClass(final Class clazz) throws IOException, InvocationTargetException, IllegalAccessException { + return defineClass( + getJavaClassName(clazz), + toByteArray(clazz) + ); + } + + public JvmHelper defineClass(final String javaClassName, + final byte[] byteCodeArray) throws InvocationTargetException, IllegalAccessException { + classLoader.defineClass(javaClassName, byteCodeArray); + return this; + } + + public static class Transformer { + + private final Filter filter; + private final EventListener listener; + private final Event.Type[] eventTypes; + + public Transformer(final Filter filter, + final EventListener listener, + final Event.Type... eventTypes) { + this.filter = filter; + this.listener = listener; + this.eventTypes = eventTypes; + } + + public Transformer(final Filter filter, + final AdviceListener listener, + final Event.Type... eventTypes) { + this.filter = filter; + this.listener = new InterruptedAdviceAdapterListener(listener); + final List eventTypeList = new ArrayList(); + CollectionUtils.addAll(eventTypeList, toArray(BEFORE, RETURN, THROWS, IMMEDIATELY_THROWS, IMMEDIATELY_RETURN)); + CollectionUtils.addAll(eventTypeList, eventTypes); + this.eventTypes = eventTypeList.toArray(new Event.Type[]{}); + } + + public byte[] transform(final String namespace, + final ClassLoader loader, + final byte[] byteCodes) { + + final MatchingResult matchingResult = new ExtFilterMatcher(make(filter)) + .matching(ClassStructureFactory.createClassStructure(byteCodes, loader)); + + final int listenerId = ObjectIDs.instance.identity(listener); + EventListenerHandlers.getSingleton().active( + listenerId, + listener, + eventTypes + ); + + if (matchingResult.isMatched()) { + return new EventEnhancer().toByteCodeArray( + loader, + byteCodes, + matchingResult.getBehaviorSignCodes(), + namespace, + listenerId, + eventTypes + ); + } else { + return byteCodes; + } + } + + } + + public JvmHelper defineClass(final Class clazz, + final Filter filter, + final EventListener listener, + final Event.Type... eventType) throws IllegalAccessException, IOException, InvocationTargetException { + return defineClass(new Class[]{clazz}, filter, listener, eventType); + } + + public JvmHelper defineClass(final Class[] classes, + final Filter filter, + final EventListener listener, + final Event.Type... eventTypes) throws IllegalAccessException, IOException, InvocationTargetException { + return defineClass( + classes, + new Transformer(filter, listener, eventTypes) + ); + } + + public JvmHelper defineClass(final Class clazz, + final Transformer... transformers) throws IOException, InvocationTargetException, IllegalAccessException { + return defineClass(new Class[]{clazz}, transformers); + } + + public JvmHelper defineClass(final Class[] classes, + final Transformer... transformers) throws IOException, InvocationTargetException, IllegalAccessException { + for (final Class clazz : classes) { + final String javaClassName = getJavaClassName(clazz); + byte[] byteCodes = toByteArray(clazz); + for (final Transformer transformer : transformers) { + byteCodes = transformer.transform(namespace, classLoader, byteCodes); + } + defineClass(javaClassName, byteCodes); + } + return this; + } + + public Class loadClass(String javaClassName) throws ClassNotFoundException { + return classLoader.loadClass(javaClassName); + } + + + /** + * 私有的ClassLoader + */ + class PrivateClassLoader extends ClassLoader { + + private final Map javaClassByteArrayMap + = new HashMap(); + + private final Set> classes = new LinkedHashSet>(); + + public PrivateClassLoader() { + } + + public PrivateClassLoader(ClassLoader parent) { + super(parent); + } + + @Override + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + + for (final Class clazz : classes) { + if (StringUtils.equals(name, getJavaClassName(clazz))) { + return clazz; + } + } + + final Class loadedClass = findLoadedClass(name); + if (loadedClass == null) { + try { + final Class aClass = findClass(name); + if (resolve) { + resolveClass(aClass); + } + return aClass; + } catch (Exception e) { + return super.loadClass(name, resolve); + } + } else { + return loadedClass; + } + } + + public Class defineClass(final String javaClassName, + final byte[] classByteArray) throws InvocationTargetException, IllegalAccessException { + javaClassByteArrayMap.put(toResourceName(javaClassName), classByteArray); + final Class clazz = SandboxReflectUtils.defineClass(this, javaClassName, classByteArray); + classes.add(clazz); + return clazz; + } + + @Override + public InputStream getResourceAsStream(String name) { + if (javaClassByteArrayMap.containsKey(name)) { + return new ByteArrayInputStream(javaClassByteArrayMap.get(name)); + } + return super.getResourceAsStream(name); + } + + } + + + public static JvmHelper createJvm(final String namespace) { + return new JvmHelper(StringUtils.isBlank(namespace) ? "default" : namespace); + } + + public static JvmHelper createJvm() { + return createJvm("default"); + } + +} diff --git a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/QaClassUtils.java b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/QaClassUtils.java index 076e06df..0c8d2209 100644 --- a/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/QaClassUtils.java +++ b/sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/QaClassUtils.java @@ -1,13 +1,9 @@ package com.alibaba.jvm.sandbox.qatest.core.util; import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.ArrayUtils; import java.io.IOException; import java.io.InputStream; -import java.lang.annotation.Annotation; -import java.util.LinkedHashSet; -import java.util.Set; import static com.alibaba.jvm.sandbox.core.util.SandboxStringUtils.toInternalClassName; @@ -33,78 +29,4 @@ public static String toResourceName(String javaClassName) { return toInternalClassName(javaClassName).concat(".class"); } - public static Set> getJdkFamilySuperClasses(Class clazz) { - final Set> familySuperClasses = new LinkedHashSet>(); - for (Class superClass = clazz.getSuperclass(); - superClass != null; - superClass = superClass.getSuperclass()) { - familySuperClasses.add(superClass); - } - return familySuperClasses; - } - - public static Set> getJdkClassInterfaces(Class clazz) { - final Set> interfaceClasses = new LinkedHashSet>(); - if (ArrayUtils.isNotEmpty(clazz.getInterfaces())) { - for (Class interfaceClass : clazz.getInterfaces()) { - interfaceClasses.add(interfaceClass); - interfaceClasses.addAll(getJdkFamilySuperClasses(interfaceClass)); - } - } - return interfaceClasses; - } - - public static Set> getJdkFamilyClassInterface(Class clazz) { - final Set> familyInterfaceClasses = new LinkedHashSet>(); - for (final Class interfaceClass : getJdkClassInterfaces(clazz)) { - familyInterfaceClasses.add(interfaceClass); - familyInterfaceClasses.addAll(getJdkClassInterfaces(interfaceClass)); - } - return familyInterfaceClasses; - } - - /** - * 获取类的所有类型 - *

    - *

  • 所有父类
  • - *
  • 所有父类的接口及这些接口的所有父类
  • - *
  • 所有接口的父类
  • - *

    - * - * @param clazz - * @return - */ - public static Set> getJdkFamilyClassType(Class clazz) { - - // 获取所有的父类 - final Set> familyTypes = new LinkedHashSet>(getJdkFamilyClassInterface(clazz)); - - for (final Class superClass : getJdkFamilySuperClasses(clazz)) { - familyTypes.add(superClass); - familyTypes.addAll(getJdkFamilyClassInterface(superClass)); - } - - // 递归获取所有接口及其父类 - return familyTypes; - } - - public static Set> getJdkAnnotationType(Class clazz) { - final Set> annotationClasses = new LinkedHashSet>(); - if(ArrayUtils.isNotEmpty(clazz.getAnnotations())) { - for (final Annotation annotation : clazz.getAnnotations()) { - if (annotation.getClass().isAnnotation()) { - annotationClasses.add(annotation.getClass()); - } - for (final Class annotationInterfaceClass : annotation.getClass().getInterfaces()) { - if (annotationInterfaceClass.isAnnotation()) { - annotationClasses.add(annotationInterfaceClass); - } - } - } - } - return annotationClasses; - } - - - } diff --git a/sandbox-core/src/test/resources/lib/sandbox-spy-1.1.0-for-qatest.jar b/sandbox-core/src/test/resources/lib/sandbox-spy-1.1.0-for-qatest.jar deleted file mode 100644 index 46fd103d..00000000 Binary files a/sandbox-core/src/test/resources/lib/sandbox-spy-1.1.0-for-qatest.jar and /dev/null differ diff --git a/sandbox-core/src/test/resources/lib/sandbox-spy-1.2.0-for-qatest.jar b/sandbox-core/src/test/resources/lib/sandbox-spy-1.2.0-for-qatest.jar new file mode 100644 index 00000000..fafd98bb Binary files /dev/null and b/sandbox-core/src/test/resources/lib/sandbox-spy-1.2.0-for-qatest.jar differ diff --git a/sandbox-core/src/test/resources/logback.xml b/sandbox-core/src/test/resources/logback.xml index c7f37818..cdbe9fad 100755 --- a/sandbox-core/src/test/resources/logback.xml +++ b/sandbox-core/src/test/resources/logback.xml @@ -7,7 +7,7 @@ - + diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/CoreConfigure.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/CoreConfigure.class deleted file mode 100644 index 463b1561..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/CoreConfigure.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/CoreLauncher.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/CoreLauncher.class deleted file mode 100644 index 89eb9271..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/CoreLauncher.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/classloader/ModuleClassLoader.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/classloader/ModuleClassLoader.class deleted file mode 100644 index 8381dab9..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/classloader/ModuleClassLoader.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/classloader/ProviderClassLoader.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/classloader/ProviderClassLoader.class deleted file mode 100644 index abd7b8d4..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/classloader/ProviderClassLoader.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/classloader/RoutingURLClassLoader$Routing.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/classloader/RoutingURLClassLoader$Routing.class deleted file mode 100644 index 66c5a018..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/classloader/RoutingURLClassLoader$Routing.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/classloader/RoutingURLClassLoader.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/classloader/RoutingURLClassLoader.class deleted file mode 100644 index 5f3ae96d..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/classloader/RoutingURLClassLoader.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/domain/CoreModule.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/domain/CoreModule.class deleted file mode 100644 index 1c212b78..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/domain/CoreModule.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/Enhancer.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/Enhancer.class deleted file mode 100644 index 2fecd266..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/Enhancer.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/EventEnhancer$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/EventEnhancer$1.class deleted file mode 100644 index dfc9bee3..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/EventEnhancer$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/EventEnhancer.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/EventEnhancer.class deleted file mode 100644 index a03507bd..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/EventEnhancer.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/annotation/Interrupted.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/annotation/Interrupted.class deleted file mode 100644 index 98f82622..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/annotation/Interrupted.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/CodeLock$Block.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/CodeLock$Block.class deleted file mode 100644 index 2257ca5c..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/CodeLock$Block.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/CodeLock.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/CodeLock.class deleted file mode 100644 index a16495c4..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/CodeLock.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$1.class deleted file mode 100644 index 63326a50..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$EventListenerWrap$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$EventListenerWrap$1.class deleted file mode 100644 index c72e30df..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$EventListenerWrap$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$EventListenerWrap$EventProcess.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$EventListenerWrap$EventProcess.class deleted file mode 100644 index 384a1fc7..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$EventListenerWrap$EventProcess.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$EventListenerWrap.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$EventListenerWrap.class deleted file mode 100644 index 015ef721..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$EventListenerWrap.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$InterruptedEventListenerImpl.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$InterruptedEventListenerImpl.class deleted file mode 100644 index c70ce1e1..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers$InterruptedEventListenerImpl.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers.class deleted file mode 100644 index 0d019495..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/EventListenerHandlers.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener$1.class deleted file mode 100644 index 43225d9d..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener$2.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener$2.class deleted file mode 100644 index db3364f0..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener$2.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener$Step.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener$Step.class deleted file mode 100644 index d59ceac0..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener$Step.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener.class deleted file mode 100644 index 498c3e4e..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/SeparateImmediatelyEventListener.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmCodeLock.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmCodeLock.class deleted file mode 100644 index d0a0a949..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmCodeLock.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmMethods$InnerHelper.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmMethods$InnerHelper.class deleted file mode 100644 index fab7d391..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmMethods$InnerHelper.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmMethods.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmMethods.class deleted file mode 100644 index 00c1134f..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmMethods.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmTryCatchBlock.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmTryCatchBlock.class deleted file mode 100644 index 381f8633..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmTryCatchBlock.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmTypes.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmTypes.class deleted file mode 100644 index 0e6759e0..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/AsmTypes.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/CallAsmCodeLock.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/CallAsmCodeLock.class deleted file mode 100644 index 9bd70eb8..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/CallAsmCodeLock.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$1.class deleted file mode 100644 index 25812785..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$2.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$2.class deleted file mode 100644 index 3594c4eb..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$2.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$3.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$3.class deleted file mode 100644 index 99780efb..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$3.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$4.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$4.class deleted file mode 100644 index 628ca7ce..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$4.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$5.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$5.class deleted file mode 100644 index da6152c1..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$5.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$6.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$6.class deleted file mode 100644 index 2fb3c0c8..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$6.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$7.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$7.class deleted file mode 100644 index c50cce99..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$7.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$8.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$8.class deleted file mode 100644 index a2c55400..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1$8.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1.class deleted file mode 100644 index 9f4b98c8..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver.class deleted file mode 100644 index 3108e02e..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/ReWriteMethod.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/ReWriteMethod.class deleted file mode 100644 index fd7202c4..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/ReWriteMethod.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/CoreLoadedClassDataSource.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/CoreLoadedClassDataSource.class deleted file mode 100644 index f0aaedd5..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/CoreLoadedClassDataSource.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/CoreModuleManager.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/CoreModuleManager.class deleted file mode 100644 index 10cc5046..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/CoreModuleManager.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleLifeCycleEventBus$Event.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleLifeCycleEventBus$Event.class deleted file mode 100644 index c1ff0605..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleLifeCycleEventBus$Event.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleLifeCycleEventBus$ModuleLifeCycleEventListener.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleLifeCycleEventBus$ModuleLifeCycleEventListener.class deleted file mode 100644 index a9f8bc28..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleLifeCycleEventBus$ModuleLifeCycleEventListener.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleLifeCycleEventBus.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleLifeCycleEventBus.class deleted file mode 100644 index 801aa88c..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleLifeCycleEventBus.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleResourceManager$WeakResource.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleResourceManager$WeakResource.class deleted file mode 100644 index a26b6f5c..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleResourceManager$WeakResource.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleResourceManager.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleResourceManager.class deleted file mode 100644 index ffa0e6e4..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ModuleResourceManager.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ProviderManager.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ProviderManager.class deleted file mode 100644 index 92dc8bf8..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/ProviderManager.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/AffectStatistic.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/AffectStatistic.class deleted file mode 100644 index 7f27c093..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/AffectStatistic.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultConfigInfo.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultConfigInfo.class deleted file mode 100644 index 74d7955e..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultConfigInfo.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager$1.class deleted file mode 100644 index b9845f24..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager$InnerModuleJarLoadCallback.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager$InnerModuleJarLoadCallback.class deleted file mode 100644 index 3d6bac0e..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager$InnerModuleJarLoadCallback.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager$InnerModuleLoadCallback.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager$InnerModuleLoadCallback.class deleted file mode 100644 index d0cfd9d2..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager$InnerModuleLoadCallback.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager.class deleted file mode 100644 index 0998b2aa..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultCoreModuleManager.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultEventMonitor$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultEventMonitor$1.class deleted file mode 100644 index 2e40047d..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultEventMonitor$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultEventMonitor.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultEventMonitor.class deleted file mode 100644 index 8ce1d806..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultEventMonitor.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultLoadedClassDataSource$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultLoadedClassDataSource$1.class deleted file mode 100644 index 71173e5f..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultLoadedClassDataSource$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultLoadedClassDataSource.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultLoadedClassDataSource.class deleted file mode 100644 index dd8258d5..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultLoadedClassDataSource.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleController.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleController.class deleted file mode 100644 index 1a7f81ad..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleController.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleEventWatcher.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleEventWatcher.class deleted file mode 100644 index abf46b44..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleEventWatcher.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleLifeCycleEventBus.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleLifeCycleEventBus.class deleted file mode 100644 index 98ce0e38..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleLifeCycleEventBus.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleManager.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleManager.class deleted file mode 100644 index 2cc9f91c..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleManager.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleResourceManager.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleResourceManager.class deleted file mode 100644 index 4a0a7ebc..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultModuleResourceManager.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultProviderManager.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultProviderManager.class deleted file mode 100644 index afc6ec49..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/DefaultProviderManager.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader$ModuleJarLoadCallback.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader$ModuleJarLoadCallback.class deleted file mode 100644 index d148e382..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader$ModuleJarLoadCallback.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader$ModuleLoadCallback.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader$ModuleLoadCallback.class deleted file mode 100644 index e38cb161..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader$ModuleLoadCallback.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader.class deleted file mode 100644 index 0c3a6c1e..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/ModuleJarLoader.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/SandboxClassFileTransformer.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/SandboxClassFileTransformer.class deleted file mode 100644 index 2759fe6a..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/manager/impl/SandboxClassFileTransformer.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/CoreServer.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/CoreServer.class deleted file mode 100644 index b6f639a5..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/CoreServer.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/ProxyCoreServer.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/ProxyCoreServer.class deleted file mode 100644 index 59e13fb6..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/ProxyCoreServer.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer$1.class deleted file mode 100644 index a40b7ba0..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer$2.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer$2.class deleted file mode 100644 index 1b421828..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer$2.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer.class deleted file mode 100644 index ce3fe053..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/JettyCoreServer.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/ModuleHttpServlet$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/ModuleHttpServlet$1.class deleted file mode 100644 index 8675497e..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/ModuleHttpServlet$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/ModuleHttpServlet.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/ModuleHttpServlet.class deleted file mode 100644 index 5a063241..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/ModuleHttpServlet.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet$InnerOnTextMessage.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet$InnerOnTextMessage.class deleted file mode 100644 index 4495b9ff..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet$InnerOnTextMessage.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet$InnerWebSocket$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet$InnerWebSocket$1.class deleted file mode 100644 index fd6a4a8f..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet$InnerWebSocket$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet$InnerWebSocket.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet$InnerWebSocket.class deleted file mode 100644 index ef4fffa4..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet$InnerWebSocket.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet$WebSocketConnectionResource.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet$WebSocketConnectionResource.class deleted file mode 100644 index 7e5a4107..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet$WebSocketConnectionResource.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet.class deleted file mode 100644 index dd3eecb2..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/server/jetty/servlet/WebSocketAcceptorServlet.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/BitUtils.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/BitUtils.class deleted file mode 100644 index e8fb4cf7..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/BitUtils.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/EventPool$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/EventPool$1.class deleted file mode 100644 index 21fd5c71..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/EventPool$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/EventPool$EventFactory.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/EventPool$EventFactory.class deleted file mode 100644 index f27b42d4..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/EventPool$EventFactory.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/EventPool.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/EventPool.class deleted file mode 100644 index a180b919..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/EventPool.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/ExceptionUtils.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/ExceptionUtils.class deleted file mode 100644 index b19ed272..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/ExceptionUtils.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/FeatureCodec$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/FeatureCodec$1.class deleted file mode 100644 index 1147cee1..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/FeatureCodec$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/FeatureCodec$ESCAPE_DECODE_STATE.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/FeatureCodec$ESCAPE_DECODE_STATE.class deleted file mode 100644 index 4c5f26b2..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/FeatureCodec$ESCAPE_DECODE_STATE.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/FeatureCodec$ESCAPE_SPLIT_STATE.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/FeatureCodec$ESCAPE_SPLIT_STATE.class deleted file mode 100644 index aed382d6..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/FeatureCodec$ESCAPE_SPLIT_STATE.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/FeatureCodec.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/FeatureCodec.class deleted file mode 100644 index 9d80041f..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/FeatureCodec.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/Initializer$Processor.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/Initializer$Processor.class deleted file mode 100644 index e135c205..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/Initializer$Processor.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/Initializer$State.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/Initializer$State.class deleted file mode 100644 index bf8fb302..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/Initializer$State.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/Initializer.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/Initializer.class deleted file mode 100644 index 83fe8868..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/Initializer.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/LazyGet.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/LazyGet.class deleted file mode 100644 index 5b2e969f..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/LazyGet.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/NamespaceConvert.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/NamespaceConvert.class deleted file mode 100644 index 98ff4bb7..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/NamespaceConvert.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/NetworkUtils.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/NetworkUtils.class deleted file mode 100644 index 35720fb1..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/NetworkUtils.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/ObjectIDs$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/ObjectIDs$1.class deleted file mode 100644 index 192f09af..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/ObjectIDs$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/ObjectIDs$IdentityWeakReference.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/ObjectIDs$IdentityWeakReference.class deleted file mode 100644 index 6faac2a1..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/ObjectIDs$IdentityWeakReference.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/ObjectIDs.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/ObjectIDs.class deleted file mode 100644 index 389ef595..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/ObjectIDs.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/SandboxReflectUtils.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/SandboxReflectUtils.class deleted file mode 100644 index 9a8d09a2..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/SandboxReflectUtils.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/SandboxStringUtils.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/SandboxStringUtils.class deleted file mode 100644 index 63b5f970..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/SandboxStringUtils.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/Sequencer.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/Sequencer.class deleted file mode 100644 index aa2b4c69..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/Sequencer.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/SpyUtils.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/SpyUtils.class deleted file mode 100644 index 1ce92dcc..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/SpyUtils.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/UnCaughtException.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/UnCaughtException.class deleted file mode 100644 index b5d2b137..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/UnCaughtException.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/UnsafeUtils.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/UnsafeUtils.class deleted file mode 100644 index 136956c0..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/UnsafeUtils.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/collection/GaLRUCache.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/collection/GaLRUCache.class deleted file mode 100644 index ebb75d2e..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/collection/GaLRUCache.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/collection/GaStack.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/collection/GaStack.class deleted file mode 100644 index 7da0d551..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/collection/GaStack.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/collection/Pair.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/collection/Pair.class deleted file mode 100644 index a0a56801..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/collection/Pair.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/collection/ThreadUnsafeGaStack.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/collection/ThreadUnsafeGaStack.class deleted file mode 100644 index b01fd11a..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/collection/ThreadUnsafeGaStack.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/ExtFilterMatcher.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/ExtFilterMatcher.class deleted file mode 100644 index b554e5e2..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/ExtFilterMatcher.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/GroupMatcher$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/GroupMatcher$1.class deleted file mode 100644 index 69c2409a..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/GroupMatcher$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/GroupMatcher$And.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/GroupMatcher$And.class deleted file mode 100644 index a2c1d309..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/GroupMatcher$And.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/GroupMatcher$Or.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/GroupMatcher$Or.class deleted file mode 100644 index 79642e45..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/GroupMatcher$Or.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/GroupMatcher.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/GroupMatcher.class deleted file mode 100644 index 7ca2a63a..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/GroupMatcher.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/Matcher.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/Matcher.class deleted file mode 100644 index 57265004..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/Matcher.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/MatchingResult.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/MatchingResult.class deleted file mode 100644 index 31845053..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/MatchingResult.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/UnsupportedMatcher.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/UnsupportedMatcher.class deleted file mode 100644 index d2669383..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/UnsupportedMatcher.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/Access.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/Access.class deleted file mode 100644 index 913e2657..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/Access.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/AccessImplByAsm.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/AccessImplByAsm.class deleted file mode 100644 index 7bacf442..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/AccessImplByAsm.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/AccessImplByJDKBehavior.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/AccessImplByJDKBehavior.class deleted file mode 100644 index abc325d3..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/AccessImplByJDKBehavior.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/AccessImplByJDKClass.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/AccessImplByJDKClass.class deleted file mode 100644 index 0d31afb2..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/AccessImplByJDKClass.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ArrayClassStructure.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ArrayClassStructure.class deleted file mode 100644 index 2701bcea..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ArrayClassStructure.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/BehaviorStructure$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/BehaviorStructure$1.class deleted file mode 100644 index bd78b6a9..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/BehaviorStructure$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/BehaviorStructure$2.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/BehaviorStructure$2.class deleted file mode 100644 index 6d7813e2..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/BehaviorStructure$2.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/BehaviorStructure.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/BehaviorStructure.class deleted file mode 100644 index 7fa20c52..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/BehaviorStructure.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructure.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructure.class deleted file mode 100644 index dc7f1a5b..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructure.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureFactory.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureFactory.class deleted file mode 100644 index 35280ab1..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureFactory.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$1.class deleted file mode 100644 index b3124e8d..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$2.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$2.class deleted file mode 100644 index 69cb4033..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$2.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$3.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$3.class deleted file mode 100644 index c471a2ba..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$3.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$4$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$4$1.class deleted file mode 100644 index 943249a4..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$4$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$4.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$4.class deleted file mode 100644 index b2f4389e..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$4.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$5$1$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$5$1$1.class deleted file mode 100644 index 828f7320..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$5$1$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$5$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$5$1.class deleted file mode 100644 index c308041f..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$5$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$5.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$5.class deleted file mode 100644 index cfd550b9..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm$5.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm.class deleted file mode 100644 index 66428be7..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByAsm.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByJDK$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByJDK$1.class deleted file mode 100644 index 1d60a17f..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByJDK$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByJDK$2.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByJDK$2.class deleted file mode 100644 index c76da054..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByJDK$2.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByJDK.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByJDK.class deleted file mode 100644 index fa9a0519..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ClassStructureImplByJDK.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/EmptyClassStructure.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/EmptyClassStructure.class deleted file mode 100644 index a434e059..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/EmptyClassStructure.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure$1.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure$1.class deleted file mode 100644 index 9dbef045..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure$1.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure$2.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure$2.class deleted file mode 100644 index d0d7e06c..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure$2.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure$3.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure$3.class deleted file mode 100644 index b3af529b..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure$3.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure$4.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure$4.class deleted file mode 100644 index a2e911ed..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure$4.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure.class deleted file mode 100644 index caf93490..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/FamilyClassStructure.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/MemberStructure.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/MemberStructure.class deleted file mode 100644 index b265321b..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/MemberStructure.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ModifierAccess.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ModifierAccess.class deleted file mode 100644 index 5a1718f7..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/ModifierAccess.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/PrimitiveClassStructure$Primitive.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/PrimitiveClassStructure$Primitive.class deleted file mode 100644 index 45319747..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/PrimitiveClassStructure$Primitive.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/PrimitiveClassStructure.class b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/PrimitiveClassStructure.class deleted file mode 100644 index 54dcbeea..00000000 Binary files a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/core/util/matcher/structure/PrimitiveClassStructure.class and /dev/null differ diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/logo b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/logo deleted file mode 100644 index b4a26f05..00000000 --- a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/logo +++ /dev/null @@ -1,5 +0,0 @@ - ___ ____ __ ____ _ _ _ ____ ____ _____ __ - | \ \ / / \/ | / ___| / \ | \ | | _ \| __ ) / _ \ \/ / - _ | |\ \ / /| |\/| |____\___ \ / _ \ | \| | | | | _ \| | | \ / -| |_| | \ V / | | | |_____|__) / ___ \| |\ | |_| | |_) | |_| / \ - \___/ \_/ |_| |_| |____/_/ \_\_| \_|____/|____/ \___/_/\_\ \ No newline at end of file diff --git a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/version b/sandbox-core/target/classes/com/alibaba/jvm/sandbox/version deleted file mode 100644 index 4fb5f668..00000000 --- a/sandbox-core/target/classes/com/alibaba/jvm/sandbox/version +++ /dev/null @@ -1 +0,0 @@ -1.1.2-SNAPSHOT \ No newline at end of file diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$1.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$1.class deleted file mode 100644 index 18a806b8..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$1.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$2.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$2.class deleted file mode 100644 index ad4bb361..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$2.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$3.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$3.class deleted file mode 100644 index a1402599..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$3.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$4.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$4.class deleted file mode 100644 index c8b3529f..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$4.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$5.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$5.class deleted file mode 100644 index 4d55745d..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$5.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$6.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$6.class deleted file mode 100644 index d77cdb57..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase$6.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase.class deleted file mode 100644 index b937943b..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/AdviceTestCase.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/CalculatorTestCase.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/CalculatorTestCase.class deleted file mode 100644 index 3584cb7c..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/CalculatorTestCase.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/CoreEnhanceBaseTestCase$1.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/CoreEnhanceBaseTestCase$1.class deleted file mode 100644 index 822f5ba2..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/CoreEnhanceBaseTestCase$1.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/CoreEnhanceBaseTestCase$TestClassLoader.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/CoreEnhanceBaseTestCase$TestClassLoader.class deleted file mode 100644 index 3fd09036..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/CoreEnhanceBaseTestCase$TestClassLoader.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/CoreEnhanceBaseTestCase.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/CoreEnhanceBaseTestCase.class deleted file mode 100644 index 8ed0a159..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/CoreEnhanceBaseTestCase.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase$1.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase$1.class deleted file mode 100644 index 4001e370..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase$1.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase$2.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase$2.class deleted file mode 100644 index 0ed16c24..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase$2.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase$3.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase$3.class deleted file mode 100644 index b3c2b375..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase$3.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase$4.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase$4.class deleted file mode 100644 index 78938815..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase$4.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase.class deleted file mode 100644 index 8758ca50..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStackTestCase.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStreamTestCase.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStreamTestCase.class deleted file mode 100644 index 9690db2b..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventStreamTestCase.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$1.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$1.class deleted file mode 100644 index 7a371077..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$1.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$2.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$2.class deleted file mode 100644 index 68d1eeb3..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$2.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$3.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$3.class deleted file mode 100644 index 48c2ddee..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$3.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$4.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$4.class deleted file mode 100644 index a14ad9db..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$4.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$5.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$5.class deleted file mode 100644 index 8bc58815..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$5.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$LineEventChecker.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$LineEventChecker.class deleted file mode 100644 index 5f949f9a..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase$LineEventChecker.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase.class deleted file mode 100644 index f9328b93..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/EventTestCase.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/NamespaceTestCase$1.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/NamespaceTestCase$1.class deleted file mode 100644 index 26854043..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/NamespaceTestCase$1.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/NamespaceTestCase$2.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/NamespaceTestCase$2.class deleted file mode 100644 index c41ce4e0..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/NamespaceTestCase$2.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/NamespaceTestCase.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/NamespaceTestCase.class deleted file mode 100644 index 22da2da8..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/NamespaceTestCase.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase$1.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase$1.class deleted file mode 100644 index e0043382..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase$1.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase$2.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase$2.class deleted file mode 100644 index 4b5d8877..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase$2.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase$3.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase$3.class deleted file mode 100644 index 2b16143e..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase$3.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase$4.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase$4.class deleted file mode 100644 index feeb2b4e..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase$4.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase.class deleted file mode 100644 index 28ca99a4..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/ProcessControllerTestCase.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/EventStreamCheckerListener$EventChecker.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/EventStreamCheckerListener$EventChecker.class deleted file mode 100644 index ffeb0fb1..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/EventStreamCheckerListener$EventChecker.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/EventStreamCheckerListener$EventTypeChecker.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/EventStreamCheckerListener$EventTypeChecker.class deleted file mode 100644 index c1cbe8b6..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/EventStreamCheckerListener$EventTypeChecker.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/EventStreamCheckerListener.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/EventStreamCheckerListener.class deleted file mode 100644 index 4513fd4d..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/EventStreamCheckerListener.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/InterruptedAdviceAdapterListener.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/InterruptedAdviceAdapterListener.class deleted file mode 100644 index 99218cf6..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/InterruptedAdviceAdapterListener.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/InterruptedEventListener.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/InterruptedEventListener.class deleted file mode 100644 index 929ef5f9..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/listener/InterruptedEventListener.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/target/Calculator.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/target/Calculator.class deleted file mode 100644 index da1c4642..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/enhance/target/Calculator.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$1.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$1.class deleted file mode 100644 index 3a0fe1bd..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$1.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$2.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$2.class deleted file mode 100644 index 13fcc600..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$2.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$Human.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$Human.class deleted file mode 100644 index a1eb4103..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$Human.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$InnerWorker.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$InnerWorker.class deleted file mode 100644 index dc5c48e7..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$InnerWorker.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$Man.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$Man.class deleted file mode 100644 index 76896a35..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$Man.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$NameRegexWithSubClassesExtFilter.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$NameRegexWithSubClassesExtFilter.class deleted file mode 100644 index e55a9b27..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$NameRegexWithSubClassesExtFilter.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$Woman.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$Woman.class deleted file mode 100644 index 3c12db9d..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$Woman.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$Worker.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$Worker.class deleted file mode 100644 index c0c8cf4d..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase$Worker.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase.class deleted file mode 100644 index 577890d8..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreLoadedClassDataSourceTestCase.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$1.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$1.class deleted file mode 100644 index 860cef94..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$1.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$2.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$2.class deleted file mode 100644 index 54be2c14..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$2.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$3.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$3.class deleted file mode 100644 index 4a92fee8..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$3.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$AnotherNormalModule.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$AnotherNormalModule.class deleted file mode 100644 index b8cfa311..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$AnotherNormalModule.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnActiveModule.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnActiveModule.class deleted file mode 100644 index 84fc1f45..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnActiveModule.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnCInitModule.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnCInitModule.class deleted file mode 100644 index d7d5e19e..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnCInitModule.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnFrozenModule.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnFrozenModule.class deleted file mode 100644 index 88fbd1b8..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnFrozenModule.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnLazyActiveModule.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnLazyActiveModule.class deleted file mode 100644 index 689ced10..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnLazyActiveModule.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnLoadCompletedModule.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnLoadCompletedModule.class deleted file mode 100644 index 27dab64e..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnLoadCompletedModule.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnLoadModule.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnLoadModule.class deleted file mode 100644 index 0b82fec8..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnLoadModule.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnUnLoadModule.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnUnLoadModule.class deleted file mode 100644 index c00a2dbd..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$BrokenOnUnLoadModule.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$EmptyCoreLoadedClassDataSource.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$EmptyCoreLoadedClassDataSource.class deleted file mode 100644 index 4fa06809..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$EmptyCoreLoadedClassDataSource.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$EmptyInstrumentation.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$EmptyInstrumentation.class deleted file mode 100644 index c8d634c2..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$EmptyInstrumentation.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$EmptyProviderManager.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$EmptyProviderManager.class deleted file mode 100644 index 5e65619d..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$EmptyProviderManager.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$ModifyAnotherNormalModule.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$ModifyAnotherNormalModule.class deleted file mode 100644 index 592c1934..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$ModifyAnotherNormalModule.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$NormalModule.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$NormalModule.class deleted file mode 100644 index 01c9b8cc..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$NormalModule.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$NormalOnLazyActiveModule.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$NormalOnLazyActiveModule.class deleted file mode 100644 index deead6f2..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase$NormalOnLazyActiveModule.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase.class deleted file mode 100644 index 19d9690d..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/CoreModuleManagerTestCase.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/MockLoadedClassesOnlyInstrumentation.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/MockLoadedClassesOnlyInstrumentation.class deleted file mode 100644 index 67afe948..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/MockLoadedClassesOnlyInstrumentation.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/ModuleLifeCycleAdapter.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/ModuleLifeCycleAdapter.class deleted file mode 100644 index aeff4415..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/manager/ModuleLifeCycleAdapter.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/JarBuilder.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/JarBuilder.class deleted file mode 100644 index 82cfff67..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/JarBuilder.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/ModuleTests$TestModule.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/ModuleTests$TestModule.class deleted file mode 100644 index 68a2dfa7..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/ModuleTests$TestModule.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/ModuleTests.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/ModuleTests.class deleted file mode 100644 index 1bdd70fd..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/ModuleTests.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/QaClassUtils.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/QaClassUtils.class deleted file mode 100644 index 89bca32e..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/QaClassUtils.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/SandboxModuleJarBuilder.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/SandboxModuleJarBuilder.class deleted file mode 100644 index 2e13844b..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/SandboxModuleJarBuilder.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/ClassStructureTestCaseByChildClass.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/ClassStructureTestCaseByChildClass.class deleted file mode 100644 index 188bc678..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/ClassStructureTestCaseByChildClass.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/AccessAsserter$AccessIsEnum.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/AccessAsserter$AccessIsEnum.class deleted file mode 100644 index 66df3546..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/AccessAsserter$AccessIsEnum.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/AccessAsserter.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/AccessAsserter.class deleted file mode 100644 index 9395f3e2..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/AccessAsserter.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/Asserter.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/Asserter.class deleted file mode 100644 index 7f773607..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/Asserter.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/BehaviorStructureAsserter.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/BehaviorStructureAsserter.class deleted file mode 100644 index 3adb14ca..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/BehaviorStructureAsserter.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/BehaviorStructureCollectionAsserter.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/BehaviorStructureCollectionAsserter.class deleted file mode 100644 index 69f3972c..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/BehaviorStructureCollectionAsserter.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/ClassStructureAsserter.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/ClassStructureAsserter.class deleted file mode 100644 index 86ceb83c..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/ClassStructureAsserter.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/ClassStructureCollectionAsserter.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/ClassStructureCollectionAsserter.class deleted file mode 100644 index 52d53192..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/ClassStructureCollectionAsserter.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/MappingAsserter$Mode.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/MappingAsserter$Mode.class deleted file mode 100644 index 42179401..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/MappingAsserter$Mode.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/MappingAsserter.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/MappingAsserter.class deleted file mode 100644 index 278322b8..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/asserts/MappingAsserter.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$InnerClass.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$InnerClass.class deleted file mode 100644 index 708b7161..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$InnerClass.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$ProtectedEnum.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$ProtectedEnum.class deleted file mode 100644 index 567ebe96..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$ProtectedEnum.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$ProtectedInterface.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$ProtectedInterface.class deleted file mode 100644 index f69754ce..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$ProtectedInterface.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$ProtectedStaticClass.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$ProtectedStaticClass.class deleted file mode 100644 index 40e75edc..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$ProtectedStaticClass.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$PublicEnum.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$PublicEnum.class deleted file mode 100644 index 0c261247..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$PublicEnum.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$PublicInterface.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$PublicInterface.class deleted file mode 100644 index 17b9fe6f..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$PublicInterface.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$PublicStaticClass.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$PublicStaticClass.class deleted file mode 100644 index 0d2363d7..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass$PublicStaticClass.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass.class deleted file mode 100644 index 14cbb202..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ChildClass.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/GrandpaClass.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/GrandpaClass.class deleted file mode 100644 index b1028e20..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/GrandpaClass.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IGrandpaInterfaceFirst.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IGrandpaInterfaceFirst.class deleted file mode 100644 index 8dca7ca0..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IGrandpaInterfaceFirst.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IGrandpaInterfaceFirstFirst.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IGrandpaInterfaceFirstFirst.class deleted file mode 100644 index 66d01910..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IGrandpaInterfaceFirstFirst.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IParentInterfaceFirst.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IParentInterfaceFirst.class deleted file mode 100644 index 6651214e..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IParentInterfaceFirst.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IParentInterfaceFirstFirst.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IParentInterfaceFirstFirst.class deleted file mode 100644 index f29666f8..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IParentInterfaceFirstFirst.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IParentInterfaceFirstSecond.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IParentInterfaceFirstSecond.class deleted file mode 100644 index 988d9d6b..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IParentInterfaceFirstSecond.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IParentInterfaceSecond.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IParentInterfaceSecond.class deleted file mode 100644 index bbabb4f1..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IParentInterfaceSecond.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IllInheritedAnnotation.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IllInheritedAnnotation.class deleted file mode 100644 index 2d63669f..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/IllInheritedAnnotation.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/InheritedAnnotation.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/InheritedAnnotation.class deleted file mode 100644 index 72fe85a1..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/InheritedAnnotation.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ParentClass.class b/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ParentClass.class deleted file mode 100644 index 1e1d7054..00000000 Binary files a/sandbox-core/target/test-classes/com/alibaba/jvm/sandbox/qatest/core/util/matcher/target/ParentClass.class and /dev/null differ diff --git a/sandbox-core/target/test-classes/lib/sandbox-spy-1.1.0-for-qatest.jar b/sandbox-core/target/test-classes/lib/sandbox-spy-1.1.0-for-qatest.jar deleted file mode 100644 index 46fd103d..00000000 Binary files a/sandbox-core/target/test-classes/lib/sandbox-spy-1.1.0-for-qatest.jar and /dev/null differ diff --git a/sandbox-core/target/test-classes/logback.xml b/sandbox-core/target/test-classes/logback.xml deleted file mode 100755 index c7f37818..00000000 --- a/sandbox-core/target/test-classes/logback.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - %d{yyyy-MM-dd HH:mm:ss} %5level %msg%n   - - - - - - - - \ No newline at end of file diff --git a/sandbox-debug-module/pom.xml b/sandbox-debug-module/pom.xml index 20022526..f91efe1c 100755 --- a/sandbox-debug-module/pom.xml +++ b/sandbox-debug-module/pom.xml @@ -6,7 +6,7 @@ com.alibaba.jvm.sandbox sandbox-module-starter - 1.1.2-SNAPSHOT + 1.2.0-SNAPSHOT ../sandbox-module-starter/pom.xml sandbox-debug-module diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule.java index 69df51ca..439aea1c 100644 --- a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule.java +++ b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule.java @@ -2,11 +2,10 @@ import com.alibaba.jvm.sandbox.api.Information; import com.alibaba.jvm.sandbox.api.Module; -import com.alibaba.jvm.sandbox.api.ProcessController; +import com.alibaba.jvm.sandbox.api.annotation.Command; import com.alibaba.jvm.sandbox.api.event.BeforeEvent; import com.alibaba.jvm.sandbox.api.event.Event; import com.alibaba.jvm.sandbox.api.event.InvokeEvent; -import com.alibaba.jvm.sandbox.api.http.Http; import com.alibaba.jvm.sandbox.api.http.printer.ConcurrentLinkedQueuePrinter; import com.alibaba.jvm.sandbox.api.http.printer.Printer; import com.alibaba.jvm.sandbox.api.listener.EventListener; @@ -18,9 +17,9 @@ import org.kohsuke.MetaInfServices; import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.io.PrintWriter; +import java.util.Map; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -28,6 +27,7 @@ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; +import static com.alibaba.jvm.sandbox.api.ProcessController.throwsImmediately; import static com.alibaba.jvm.sandbox.api.event.Event.Type.*; /** @@ -43,8 +43,8 @@ *
*/ @MetaInfServices(Module.class) -@Information(id = "debug-ralph", version = "0.0.1", author = "luanjia@taobao.com") -public class DebugRalphModule extends HttpSupported implements Module { +@Information(id = "debug-ralph", version = "0.0.2", author = "luanjia@taobao.com") +public class DebugRalphModule extends ParamSupported implements Module { @Resource private ModuleEventWatcher moduleEventWatcher; @@ -53,95 +53,85 @@ public class DebugRalphModule extends HttpSupported implements Module { * 并发控制 * -d 'debug-ralph/c-limit?class=&method=&c=' */ - @Http("/c-limit") - public void concurrentLimit(final HttpServletRequest req, - final HttpServletResponse resp) throws IOException { - - final Printer printer = new ConcurrentLinkedQueuePrinter(resp.getWriter()); - - try { - - // --- 解析参数 --- - - final String cnPattern = getParameter(req, "class"); - final String mnPattern = getParameter(req, "method"); - final int concurrent = getParameter(req, "c", int.class); - - final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher) - .onClass(cnPattern) - .includeSubClasses() - .includeBootstrap() - .onBehavior(mnPattern) - .onWatching() - .withProgress(new ProgressPrinter(printer)) - .onWatch(new EventListener() { - - // 设定一个本次拦截共享的并发限制器,所有被匹配上的类的入口 - // 将会共同被同一个并发限制! - final Semaphore sph = new Semaphore(concurrent); - - // 是否一次拦截调用链的入口 - private boolean isProcessTop(InvokeEvent event) { - return event.processId == event.invokeId; + @Command("c-limit") + public void concurrentLimit(final Map param, final PrintWriter writer) { + + final Printer printer = new ConcurrentLinkedQueuePrinter(writer); + + // --- 解析参数 --- + + final String cnPattern = getParameter(param, "class"); + final String mnPattern = getParameter(param, "method"); + final int concurrent = getParameter(param, "c", int.class); + + final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher) + .onClass(cnPattern) + .includeSubClasses() + .includeBootstrap() + .onBehavior(mnPattern) + .onWatching() + .withProgress(new ProgressPrinter(printer)) + .onWatch(new EventListener() { + + // 设定一个本次拦截共享的并发限制器,所有被匹配上的类的入口 + // 将会共同被同一个并发限制! + final Semaphore sph = new Semaphore(concurrent); + + // 是否一次拦截调用链的入口 + private boolean isProcessTop(InvokeEvent event) { + return event.processId == event.invokeId; + } + + @Override + public void onEvent(Event event) throws Throwable { + + final InvokeEvent iEvent = (InvokeEvent) event; + // 不是顶层调用,说明之前已经通过并发控制的闸门,可以不受到并发的制约 + if (!isProcessTop(iEvent)) { + return; } - @Override - public void onEvent(Event event) throws Throwable { - - final InvokeEvent iEvent = (InvokeEvent) event; - // 不是顶层调用,说明之前已经通过并发控制的闸门,可以不受到并发的制约 - if (!isProcessTop(iEvent)) { - return; - } - - switch (event.type) { - case BEFORE: { - final BeforeEvent bEvent = (BeforeEvent) event; - // 如果是顶层的调用,必须通过流控获取继续调用的门票 - // 没有拿到门票的就让他快速失败掉 - if (!sph.tryAcquire()) { - printer.println(String.format( - "%s.%s will be limit by concurrent: %s on %s", - bEvent.javaClassName, - bEvent.javaMethodName, - concurrent, - Thread.currentThread().getName() - )); - ProcessController.throwsImmediately(new RuntimeException("concurrent-limit by Ralph!!!")); - } - break; - } - case RETURN: - case THROWS: { - sph.release(); - break; + switch (event.type) { + case BEFORE: { + final BeforeEvent bEvent = (BeforeEvent) event; + // 如果是顶层的调用,必须通过流控获取继续调用的门票 + // 没有拿到门票的就让他快速失败掉 + if (!sph.tryAcquire()) { + printer.println(String.format( + "%s.%s will be limit by concurrent: %s on %s", + bEvent.javaClassName, + bEvent.javaMethodName, + concurrent, + Thread.currentThread().getName() + )); + throwsImmediately(new RuntimeException("concurrent-limit by Ralph!!!")); } + break; + } + case RETURN: + case THROWS: { + sph.release(); + break; + } - default: - // ignore... - }//switch - - }//onEvent + } - }, BEFORE, RETURN, THROWS); + }//onEvent - // --- 等待结束 --- + }, BEFORE, RETURN, THROWS); - try { - printer.println(String.format( - "concurrent-limit on [%s#%s] concurrent:%s.\nPress CTRL_C abort it!", - cnPattern, - mnPattern, - concurrent - )); - printer.waitingForBroken(); - } finally { - watcher.onUnWatched(); - } + // --- 等待结束 --- - } catch (HttpErrorCodeException hece) { - resp.sendError(hece.getCode(), hece.getMessage()); - return; + try { + printer.println(String.format( + "concurrent-limit on [%s#%s] concurrent:%s.\nPress CTRL_C abort it!", + cnPattern, + mnPattern, + concurrent + )); + printer.waitingForBroken(); + } finally { + watcher.onUnWatched(); } } @@ -151,81 +141,73 @@ public void onEvent(Event event) throws Throwable { * 速率控制 * -d 'debug-ralph/r-limit?class=&method=&c=' */ - @Http("/r-limit") - public void rateLimit(final HttpServletRequest req, - final HttpServletResponse resp) throws IOException { - - final Printer printer = new ConcurrentLinkedQueuePrinter(resp.getWriter()); - - try { - - // --- 解析参数 --- - - final String cnPattern = getParameter(req, "class"); - final String mnPattern = getParameter(req, "method"); - final double rate = getParameter(req, "r", double.class); - - final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher) - .onClass(cnPattern) - .includeSubClasses() - .includeBootstrap() - .onBehavior(mnPattern) - .onWatching() - .withProgress(new ProgressPrinter(printer)) - .onWatch(new EventListener() { - - // 设定一个本次拦截共享的速率限制器,所有被匹配上的类的入口 - // 将会共同被同一个速率限速! - final RateLimiter limiter = RateLimiter.create(rate); - - // 是否一次拦截调用链的入口 - private boolean isProcessTop(InvokeEvent event) { - return event.processId == event.invokeId; + @Command("r-limit") + public void rateLimit(final Map param, final PrintWriter writer) { + + final Printer printer = new ConcurrentLinkedQueuePrinter(writer); + + // --- 解析参数 --- + + final String cnPattern = getParameter(param, "class"); + final String mnPattern = getParameter(param, "method"); + final double rate = getParameter(param, "r", double.class); + + final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher) + .onClass(cnPattern) + .includeSubClasses() + .includeBootstrap() + .onBehavior(mnPattern) + .onWatching() + .withProgress(new ProgressPrinter(printer)) + .onWatch(new EventListener() { + + // 设定一个本次拦截共享的速率限制器,所有被匹配上的类的入口 + // 将会共同被同一个速率限速! + final RateLimiter limiter = RateLimiter.create(rate); + + // 是否一次拦截调用链的入口 + private boolean isProcessTop(InvokeEvent event) { + return event.processId == event.invokeId; + } + + @Override + public void onEvent(Event event) throws Throwable { + final BeforeEvent bEvent = (BeforeEvent) event; + + // 不是顶层调用,说明之前已经通过流控的闸门,可以不受到流控的制约 + if (!isProcessTop(bEvent)) { + return; } - @Override - public void onEvent(Event event) throws Throwable { - final BeforeEvent bEvent = (BeforeEvent) event; - - // 不是顶层调用,说明之前已经通过流控的闸门,可以不受到流控的制约 - if (!isProcessTop(bEvent)) { - return; - } - - // 如果是顶层的调用,必须通过流控获取继续调用的门票 - // 没有拿到门票的就让他快速失败掉 - if (!limiter.tryAcquire()) { - printer.println(String.format( - "%s.%s will be limit by rate: %s on %s", - bEvent.javaClassName, - bEvent.javaMethodName, - rate, - Thread.currentThread().getName() - )); - ProcessController.throwsImmediately(new RuntimeException("rate-limit by Ralph!!!")); - } - + // 如果是顶层的调用,必须通过流控获取继续调用的门票 + // 没有拿到门票的就让他快速失败掉 + if (!limiter.tryAcquire()) { + printer.println(String.format( + "%s.%s will be limit by rate: %s on %s", + bEvent.javaClassName, + bEvent.javaMethodName, + rate, + Thread.currentThread().getName() + )); + throwsImmediately(new RuntimeException("rate-limit by Ralph!!!")); } - }, BEFORE); + } - // --- 等待结束 --- + }, BEFORE); - try { - printer.println(String.format( - "rate-limit on [%s#%s] rate:%.2f(TPS).\nPress CTRL_C abort it!", - cnPattern, - mnPattern, - rate - )); - printer.waitingForBroken(); - } finally { - watcher.onUnWatched(); - } + // --- 等待结束 --- - } catch (HttpErrorCodeException hece) { - resp.sendError(hece.getCode(), hece.getMessage()); - return; + try { + printer.println(String.format( + "rate-limit on [%s#%s] rate:%.2f(TPS).\nPress CTRL_C abort it!", + cnPattern, + mnPattern, + rate + )); + printer.waitingForBroken(); + } finally { + watcher.onUnWatched(); } } @@ -283,73 +265,65 @@ public Exception throwIt(final String message) throws Exception { * 注入异常 * -d 'debug-ralph/wreck?class=&method=&type=' */ - @Http("/wreck") - public void exception(final HttpServletRequest req, - final HttpServletResponse resp) throws IOException { - - final Printer printer = new ConcurrentLinkedQueuePrinter(resp.getWriter()); + @Command("wreck") + public void exception(final Map param, final PrintWriter writer) { + + final Printer printer = new ConcurrentLinkedQueuePrinter(writer); + + // --- 解析参数 --- + + final String cnPattern = getParameter(param, "class"); + final String mnPattern = getParameter(param, "method"); + final ExceptionType exType = getParameter( + param, + "type", + new Converter() { + @Override + public ExceptionType convert(String string) { + return EnumUtils.getEnum(ExceptionType.class, string); + } + }, + ExceptionType.RuntimeException + ); + + // --- 开始增强 --- + + final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher) + .onClass(cnPattern) + .includeSubClasses() + .includeBootstrap() + .onBehavior(mnPattern) + .onWatching() + .withProgress(new ProgressPrinter(printer)) + .onWatch(new EventListener() { + @Override + public void onEvent(Event event) throws Throwable { + + final BeforeEvent bEvent = (BeforeEvent) event; + printer.println(String.format( + "%s.%s will be wreck by exception: %s on %s", + bEvent.javaClassName, + bEvent.javaMethodName, + exType.name(), + Thread.currentThread().getName() + )); + + throwsImmediately(exType.throwIt("wreck-it by Ralph!!!")); + } + }, BEFORE); + + // --- 等待结束 --- try { - - // --- 解析参数 --- - - final String cnPattern = getParameter(req, "class"); - final String mnPattern = getParameter(req, "method"); - final ExceptionType exType = getParameter( - req, - "type", - new Converter() { - @Override - public ExceptionType convert(String string) { - return EnumUtils.getEnum(ExceptionType.class, string); - } - }, - ExceptionType.RuntimeException - ); - - // --- 开始增强 --- - - final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher) - .onClass(cnPattern) - .includeSubClasses() - .includeBootstrap() - .onBehavior(mnPattern) - .onWatching() - .withProgress(new ProgressPrinter(printer)) - .onWatch(new EventListener() { - @Override - public void onEvent(Event event) throws Throwable { - - final BeforeEvent bEvent = (BeforeEvent) event; - printer.println(String.format( - "%s.%s will be wreck by exception: %s on %s", - bEvent.javaClassName, - bEvent.javaMethodName, - exType.name(), - Thread.currentThread().getName() - )); - - ProcessController.throwsImmediately(exType.throwIt("wreck-it by Ralph!!!")); - } - }, BEFORE); - - // --- 等待结束 --- - - try { - printer.println(String.format( - "exception on [%s#%s] exception: %s.\nPress CTRL_C abort it!", - cnPattern, - mnPattern, - exType.name() - )); - printer.waitingForBroken(); - } finally { - watcher.onUnWatched(); - } - - } catch (HttpErrorCodeException hece) { - resp.sendError(hece.getCode(), hece.getMessage()); - return; + printer.println(String.format( + "exception on [%s#%s] exception: %s.\nPress CTRL_C abort it!", + cnPattern, + mnPattern, + exType.name() + )); + printer.waitingForBroken(); + } finally { + watcher.onUnWatched(); } } @@ -358,85 +332,77 @@ public void onEvent(Event event) throws Throwable { * 注入延时 * -d 'debug-ralph/delay?class=&method=&delay=' */ - @Http("/delay") - public void delay(final HttpServletRequest req, - final HttpServletResponse resp) throws IOException { + @Command("delay") + public void delay(final Map param, final PrintWriter writer) { final ReentrantLock delayLock = new ReentrantLock(); final Condition delayCondition = delayLock.newCondition(); - final Printer printer = new ConcurrentLinkedQueuePrinter(resp.getWriter()); + final Printer printer = new ConcurrentLinkedQueuePrinter(writer); final AtomicBoolean isFinishRef = new AtomicBoolean(false); - try { - - // --- 解析参数 --- - - final String cnPattern = getParameter(req, "class"); - final String mnPattern = getParameter(req, "method"); - final long delayMs = getParameter(req, "delay", long.class); - - // --- 开始增强 --- - - final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher) - .onClass(cnPattern) - .includeSubClasses() - .includeBootstrap() - .onBehavior(mnPattern) - .onWatching() - .withProgress(new ProgressPrinter(printer)) - .onWatch(new EventListener() { - @Override - public void onEvent(Event event) throws Throwable { - - final BeforeEvent bEvent = (BeforeEvent) event; - printer.println(String.format( - "%s.%s will be delay %s(ms) on %s", - bEvent.javaClassName, - bEvent.javaMethodName, - delayMs, - Thread.currentThread().getName() - )); - - delayLock.lock(); - try { - // 如果已经结束,则放弃本次请求 - if (isFinishRef.get()) { - return; - } - delayCondition.await(delayMs, TimeUnit.MILLISECONDS); - } finally { - delayLock.unlock(); + // --- 解析参数 --- + + final String cnPattern = getParameter(param, "class"); + final String mnPattern = getParameter(param, "method"); + final long delayMs = getParameter(param, "delay", long.class); + + // --- 开始增强 --- + + final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher) + .onClass(cnPattern) + .includeSubClasses() + .includeBootstrap() + .onBehavior(mnPattern) + .onWatching() + .withProgress(new ProgressPrinter(printer)) + .onWatch(new EventListener() { + @Override + public void onEvent(Event event) throws Throwable { + + final BeforeEvent bEvent = (BeforeEvent) event; + printer.println(String.format( + "%s.%s will be delay %s(ms) on %s", + bEvent.javaClassName, + bEvent.javaMethodName, + delayMs, + Thread.currentThread().getName() + )); + + delayLock.lock(); + try { + // 如果已经结束,则放弃本次请求 + if (isFinishRef.get()) { + return; } + delayCondition.await(delayMs, TimeUnit.MILLISECONDS); + } finally { + delayLock.unlock(); } - }, BEFORE); + } + }, BEFORE); - // --- 等待结束 --- + // --- 等待结束 --- + try { + printer.println(String.format( + "delay on [%s#%s] %s(ms).\nPress CTRL_C abort it!", + cnPattern, + mnPattern, + delayMs + )); + printer.waitingForBroken(); + } finally { + + // 释放锁 + delayLock.lock(); try { - printer.println(String.format( - "delay on [%s#%s] %s(ms).\nPress CTRL_C abort it!", - cnPattern, - mnPattern, - delayMs - )); - printer.waitingForBroken(); + isFinishRef.set(true); + delayCondition.signalAll(); } finally { - - // 释放锁 - delayLock.lock(); - try { - isFinishRef.set(true); - delayCondition.signalAll(); - } finally { - delayLock.unlock(); - } - - watcher.onUnWatched(); + delayLock.unlock(); } - } catch (HttpErrorCodeException hece) { - resp.sendError(hece.getCode(), hece.getMessage()); - return; + watcher.onUnWatched(); } } diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/DebugTraceModule.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/DebugTraceModule.java index 85c60f51..4d424fd4 100644 --- a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/DebugTraceModule.java +++ b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/DebugTraceModule.java @@ -2,7 +2,7 @@ import com.alibaba.jvm.sandbox.api.Information; import com.alibaba.jvm.sandbox.api.Module; -import com.alibaba.jvm.sandbox.api.http.Http; +import com.alibaba.jvm.sandbox.api.annotation.Command; import com.alibaba.jvm.sandbox.api.http.printer.ConcurrentLinkedQueuePrinter; import com.alibaba.jvm.sandbox.api.http.printer.Printer; import com.alibaba.jvm.sandbox.api.listener.ext.Advice; @@ -10,47 +10,39 @@ import com.alibaba.jvm.sandbox.api.listener.ext.EventWatchBuilder; import com.alibaba.jvm.sandbox.api.listener.ext.EventWatcher; import com.alibaba.jvm.sandbox.api.resource.ModuleEventWatcher; +import com.alibaba.jvm.sandbox.api.resource.ModuleManager; import com.alibaba.jvm.sandbox.module.debug.textui.TTree; import org.kohsuke.MetaInfServices; import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; +import java.io.PrintWriter; +import java.util.Map; /** * 模仿Greys的trace命令 *

测试用模块

*/ @MetaInfServices(Module.class) -@Information(id = "debug-trace", version = "0.0.1", author = "luanjia@taobao.com") -public class DebugTraceModule extends HttpSupported implements Module { +@Information(id = "debug-trace", version = "0.0.2", author = "luanjia@taobao.com") +public class DebugTraceModule extends ParamSupported implements Module { @Resource private ModuleEventWatcher moduleEventWatcher; - @Http("/trace") - public void trace(final HttpServletRequest req, - final HttpServletResponse resp) throws IOException { - try { - final String cnPattern = getParameter(req, "class"); - final String mnPattern = getParameter(req, "method"); - final Printer printer = new ConcurrentLinkedQueuePrinter(resp.getWriter()); - debugTrace(cnPattern, mnPattern, printer); - } catch (HttpSupported.HttpErrorCodeException hece) { - resp.sendError(hece.getCode(), hece.getMessage()); - return; - } - } - private void debugTrace(final String cnPattern, - final String mnPattern, - final Printer printer) { + @Command("trace") + public void trace(final Map param, final PrintWriter writer) { + + final String cnPattern = getParameter(param, "class"); + final String mnPattern = getParameter(param, "method"); + final Printer printer = new ConcurrentLinkedQueuePrinter(writer); final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher) .onClass(cnPattern).includeSubClasses() .onBehavior(mnPattern) - .onWatching().withProgress(new ProgressPrinter(printer)).withCall() + .onWatching() + .withCall() + .withProgress(new ProgressPrinter(printer)) .onWatch(new AdviceListener() { private String getTracingTitle(final Advice advice) { diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule.java index 405f6da3..ac3a56fe 100644 --- a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule.java +++ b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule.java @@ -2,7 +2,7 @@ import com.alibaba.jvm.sandbox.api.Information; import com.alibaba.jvm.sandbox.api.Module; -import com.alibaba.jvm.sandbox.api.http.Http; +import com.alibaba.jvm.sandbox.api.annotation.Command; import com.alibaba.jvm.sandbox.api.http.printer.ConcurrentLinkedQueuePrinter; import com.alibaba.jvm.sandbox.api.http.printer.Printer; import com.alibaba.jvm.sandbox.api.listener.ext.Advice; @@ -15,11 +15,10 @@ import org.kohsuke.MetaInfServices; import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; +import java.io.PrintWriter; import java.util.HashMap; import java.util.List; +import java.util.Map; import static com.alibaba.jvm.sandbox.module.debug.DebugWatchModule.Trigger.*; @@ -30,47 +29,39 @@ * @author luanjia@taobao.com */ @MetaInfServices(Module.class) -@Information(id = "debug-watch", version = "0.0.1", author = "luanjia@taobao.com") -public class DebugWatchModule extends HttpSupported implements Module { +@Information(id = "debug-watch", version = "0.0.2", author = "luanjia@taobao.com") +public class DebugWatchModule extends ParamSupported implements Module { @Resource private ModuleEventWatcher moduleEventWatcher; - @Http("/watch") - public void watch(final HttpServletRequest req, - final HttpServletResponse resp) throws IOException { - try { - final String cnPattern = getParameter(req, "class"); - final String mnPattern = getParameter(req, "method"); - final String watchExpress = getParameter(req, "watch"); - final List triggers = getParameters( - req, - "at", - new Converter() { - @Override - public Trigger convert(String string) { - return EnumUtils.getEnum(Trigger.class, string); - } - }, - new Trigger[]{Trigger.BEFORE}); - final Printer printer = new ConcurrentLinkedQueuePrinter(resp.getWriter()); - debugWatch(cnPattern, mnPattern, watchExpress, triggers, printer); - } catch (HttpSupported.HttpErrorCodeException hece) { - resp.sendError(hece.getCode(), hece.getMessage()); - return; - } - } + @Command("watch") + public void watch(final Map param, + final Map params, + final PrintWriter writer) { + + final String cnPattern = getParameter(param, "class"); + final String mnPattern = getParameter(param, "method"); + final String watchExpress = getParameter(param, "watch"); + final List triggers = getParameters( + params, + "at", + new Converter() { + @Override + public Trigger convert(String string) { + return EnumUtils.getEnum(Trigger.class, string); + } + }, + Trigger.BEFORE); + final Printer printer = new ConcurrentLinkedQueuePrinter(writer); - private void debugWatch(final String cnPattern, - final String mnPattern, - final String watchExpress, - final List triggers, - final Printer printer) { final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher) - .onClass(cnPattern).includeSubClasses() + .onClass(cnPattern) + .includeSubClasses() .onBehavior(mnPattern) - .onWatching().withProgress(new ProgressPrinter(printer)) + .onWatching() + .withProgress(new ProgressPrinter(printer)) .onWatch(new AdviceListener() { @Override @@ -137,6 +128,7 @@ private void printlnByExpress(final Bind bind) { } + private static String toString(final Object object) { return null == object ? "null" diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule.java deleted file mode 100644 index 63878232..00000000 --- a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule.java +++ /dev/null @@ -1,231 +0,0 @@ -package com.alibaba.jvm.sandbox.module.debug; - -import com.alibaba.jvm.sandbox.api.Information; -import com.alibaba.jvm.sandbox.api.LoadCompleted; -import com.alibaba.jvm.sandbox.api.Module; -import com.alibaba.jvm.sandbox.api.listener.Sentry; -import com.alibaba.jvm.sandbox.api.listener.ext.Advice; -import com.alibaba.jvm.sandbox.api.listener.ext.AdviceListener; -import com.alibaba.jvm.sandbox.api.listener.ext.EventWatchBuilder; -import com.alibaba.jvm.sandbox.api.resource.ModuleEventWatcher; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.reflect.MethodUtils; -import org.kohsuke.MetaInfServices; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.annotation.Resource; -import java.lang.reflect.InvocationTargetException; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import static com.alibaba.jvm.sandbox.module.debug.HttpHttpAccessLoggerModule.HttpProcessStep.*; - -/** - * 基于HTTP-SERVLET(v2.4)规范的HTTP访问日志 - * - * @author luanjia@taobao.com - */ -@MetaInfServices(Module.class) -@Information(id = "debug-http-logger", version = "0.0.1", author = "luanjia@taobao.com") -public class HttpHttpAccessLoggerModule implements Module, LoadCompleted { - - private final Logger stLogger = LoggerFactory.getLogger("DEBUG-SERVLET-LOGGER"); - - @Resource - private ModuleEventWatcher moduleEventWatcher; - - - /** - * HTTP处理步骤 - * {@code - * HttpServlet.service():BEGIN - * -> HttpServletResponse.[setState/sendError]():BEGIN - * -> HttpServletResponse.[setState/sendError]():FINISH - * -> HttpServlet.service():FINISH - * } - */ - enum HttpProcessStep { - waitingHttpServletServiceBegin, - waitingHttpServletResponseState, - waitingHttpServletServiceFinish - } - - /** - * HTTP接入信息 - */ - class HttpAccess { - String from; - String method; - String uri; - Map parameterMap; - String userAgent; - int status; - long beginTimestamp; - } - - // 安排一个哨兵,用于观察Servlet执行步骤 - private final Sentry sentry = new Sentry(waitingHttpServletServiceBegin); - - @Override - public void loadCompleted() { - buildingHttpStatusFillBack(); - buildingHttpServletService(); - } - - /* - * HTTP状态码回填 - * 因为在3.0之前你都很难拿到HTTP的应答状态,必须拦截HttpServletResponse的setStatus/sendError才能拿到 - * 而且还必须要考虑到200这种状态码为默认状态码的情况 - */ - private void buildingHttpStatusFillBack() { - new EventWatchBuilder(moduleEventWatcher) - .onClass("javax.servlet.http.HttpServletResponse") - /**/.includeSubClasses() - .onBehavior("setStatus") - /**/.withParameterTypes(int.class) - .onBehavior("sendError") - /**/.withParameterTypes(int.class) - /**/.withParameterTypes(int.class, String.class) - .onWatch(new AdviceListener() { - @Override - public void before(Advice advice) { - if (sentry.next(waitingHttpServletResponseState, waitingHttpServletServiceFinish)) { - final HttpAccess ha = sentry.attachment(); - ha.status = (Integer) advice.getParameterArray()[0]; - } - } - }); - } - - /* - * 拦截HttpServlet的服务请求入口 - */ - private void buildingHttpServletService() { - new EventWatchBuilder(moduleEventWatcher) - .onClass("javax.servlet.http.HttpServlet") - .includeBootstrap() - .onBehavior("service") - .withParameterTypes( - "javax.servlet.http.HttpServletRequest", - "javax.servlet.http.HttpServletResponse" - ) - .onWatch(new AdviceListener() { - - final String MARK_HTTP_BEGIN = "MARK_HTTP_BEGIN"; - - @Override - public void before(Advice advice) throws Throwable { - if (sentry.next(waitingHttpServletServiceBegin, waitingHttpServletResponseState)) { - final Object objectOfHttpServletRequest = advice.getParameterArray()[0]; - final HttpAccess ha = new HttpAccess(); - ha.from = invokeMethod(objectOfHttpServletRequest, "getRemoteAddr"); - ha.method = invokeMethod(objectOfHttpServletRequest, "getMethod"); - ha.uri = invokeMethod(objectOfHttpServletRequest, "getRequestURI"); - ha.parameterMap = invokeMethod(objectOfHttpServletRequest, "getParameterMap"); - ha.userAgent = invokeMethod(objectOfHttpServletRequest, "getHeader", "User-Agent"); - ha.beginTimestamp = System.currentTimeMillis(); - sentry.attach(ha); - advice.mark(MARK_HTTP_BEGIN); - } - } - - @Override - public void afterReturning(Advice advice) { - if (finishing(advice)) { - final HttpAccess ha = sentry.attachment(); - final long cost = System.currentTimeMillis() - ha.beginTimestamp; - logAccess(ha, cost, null); - } - } - - @Override - public void afterThrowing(Advice advice) { - if (finishing(advice)) { - final HttpAccess ha = sentry.attachment(); - final long cost = System.currentTimeMillis() - ha.beginTimestamp; - logAccess(ha, cost, advice.getThrowable()); - } - } - - /** - * 判断是否请求对称结束 - * - * @param advice 通知 - * @return TRUE:对称结束;FALSE:非对称结束 - */ - private boolean finishing(Advice advice) { - - // 一些HttpServletResponse在实现的时候,status默认值就是200 - // 所以这些实现类就会偷懒不去主动调用setStatus(),仅拦截setStatus/sendError是无法完全获取所有的,HTTP状态码 - // 这里做一个判断,如果走的是默认值,则主动补偿上这个200 - // - // 调用路径 - // HttpServlet.service():BEGIN - // `-HttpServlet.service():FINISH - if (advice.hasMark(MARK_HTTP_BEGIN) - && sentry.next(waitingHttpServletResponseState, waitingHttpServletServiceBegin)) { - final HttpAccess ha = sentry.attachment(); - ha.status = 200; - return true; - } - - // 调用路径 - // HttpServlet.service():BEGIN - // `- HttpServletResponse.[setState/sendError]():BEGIN - // `- HttpServletResponse.[setState/sendError]():FINISH - // `- HttpServlet.service():FINISH - return advice.hasMark(MARK_HTTP_BEGIN) - && sentry.next(waitingHttpServletServiceFinish, waitingHttpServletServiceBegin); - - } - - }); - } - - /* - * 泛型转换方法调用 - * 底层使用apache common实现 - */ - private static T invokeMethod(final Object object, - final String methodName, - final Object... args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - return (T) MethodUtils.invokeMethod(object, methodName, args); - } - - // 格式化ParameterMap - private static String formatParameterMap(final Map parameterMap) { - final Set kvPairs = new LinkedHashSet(); - for (final Map.Entry entry : parameterMap.entrySet()) { - final String[] valueArray = entry.getValue(); - if (null == valueArray) { - continue; - } - for (final String value : valueArray) { - kvPairs.add(String.format("%s=%s", entry.getKey(), value)); - } - } - return StringUtils.join(kvPairs, "&"); - } - - - /* - * 记录access日志 - */ - private void logAccess(final HttpAccess ha, - final long costMs, - final Throwable cause) { - stLogger.info("{};{};{};{}ms;{};[{}];{};", - ha.from, - ha.status, - ha.method, - costMs, - ha.uri, - formatParameterMap(ha.parameterMap), - ha.userAgent, - cause - ); - } - -} diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/HttpSupported.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/HttpSupported.java deleted file mode 100644 index 2a80a6b7..00000000 --- a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/HttpSupported.java +++ /dev/null @@ -1,188 +0,0 @@ -package com.alibaba.jvm.sandbox.module.debug; - -import com.alibaba.jvm.sandbox.api.util.GaArrayUtils; -import org.apache.commons.lang3.StringUtils; - -import javax.servlet.http.HttpServletRequest; -import java.util.*; - -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; - -public class HttpSupported { - - /** - * 封装HTTP错误码 - */ - protected static class HttpErrorCodeException extends Exception { - private final int code; - - HttpErrorCodeException(int code, String message) { - super(message); - this.code = code; - } - - int getCode() { - return code; - } - - } - - interface Converter { - T convert(String string); - } - - static Map, Converter> converterMap = new HashMap, Converter>(); - - static { - regConverter(new Converter() { - @Override - public String convert(String string) { - return string; - } - }, String.class); - - regConverter(new Converter() { - @Override - public Long convert(String string) { - return Long.valueOf(string); - } - }, long.class, Long.class); - - regConverter(new Converter() { - @Override - public Double convert(String string) { - return Double.valueOf(string); - } - }, double.class, Double.class); - - regConverter(new Converter() { - @Override - public Integer convert(String string) { - return Integer.valueOf(string); - } - }, int.class, Integer.class); - - } - - /** - * 注册类型转换器 - * - * @param converter 转换器 - * @param typeArray 类型的Java类数组 - * @param 类型 - */ - protected static void regConverter(Converter converter, Class... typeArray) { - for (final Class type : typeArray) { - converterMap.put(type, converter); - } - } - - private static T convert(final Converter converter, - final String string, - final String name) throws HttpErrorCodeException { - if (null == converter) { - throw new HttpErrorCodeException(SC_BAD_REQUEST, String.format("parameter:%s is unknow type!", name)); - } - try { - return converter.convert(string); - } catch (Throwable cause) { - throw new HttpErrorCodeException(SC_BAD_REQUEST, String.format("paramater:%s is illegal format!", name)); - } - } - - protected static T getParameter(final HttpServletRequest req, - final String name, - final Converter converter, - final T defaultValue) throws HttpErrorCodeException { - final String string = req.getParameter(name); - - // 参数值为空 - if (StringUtils.isBlank(string)) { - if (null == defaultValue) { - throw new HttpErrorCodeException(SC_BAD_REQUEST, String.format("parameter:%s is require!", name)); - } - return defaultValue; - } - - // 参数值不为空 - else { - return convert(converter, string, name); - } - } - - protected static List getParameters(final HttpServletRequest req, - final String name, - final Converter converter, - final T... defaultValueArray) throws HttpErrorCodeException { - final String[] stringArray = req.getParameterValues(name); - if (GaArrayUtils.isEmpty(stringArray)) { - if (null == defaultValueArray) { - throw new HttpErrorCodeException(SC_BAD_REQUEST, String.format("parameter:%s is require!", name)); - } - return Arrays.asList(defaultValueArray); - } - final List values = new ArrayList(); - for (final String string : stringArray) { - values.add(convert(converter, string, name)); - } - return values; - } - - - protected static String getParameter(final HttpServletRequest req, - final String name) throws HttpErrorCodeException { - return getParameter( - req, name, - String.class, - null - ); - } - - protected static String getParameter(final HttpServletRequest req, - final String name, - final String defaultString) throws HttpErrorCodeException { - return getParameter( - req, - name, - String.class, - defaultString - ); - } - - protected static T getParameter(final HttpServletRequest req, - final String name, - final Class type) throws HttpErrorCodeException { - return getParameter( - req, - name, - type, - null - ); - } - - protected static T getParameter(final HttpServletRequest req, - final String name, - final Class type, - final T defaultValue) throws HttpErrorCodeException { - return getParameter( - req, - name, - (Converter) converterMap.get(type), - defaultValue - ); - } - - protected static List getParameters(final HttpServletRequest req, - final String name, - final Class type, - final T... defaultValueArray) throws HttpErrorCodeException { - return getParameters( - req, - name, - (Converter) converterMap.get(type), - defaultValueArray - ); - } - - -} diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule.java deleted file mode 100644 index abdd03b7..00000000 --- a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule.java +++ /dev/null @@ -1,167 +0,0 @@ -package com.alibaba.jvm.sandbox.module.debug; - -import com.alibaba.jvm.sandbox.api.Information; -import com.alibaba.jvm.sandbox.api.LoadCompleted; -import com.alibaba.jvm.sandbox.api.Module; -import com.alibaba.jvm.sandbox.api.listener.Sentry; -import com.alibaba.jvm.sandbox.api.listener.ext.Advice; -import com.alibaba.jvm.sandbox.api.listener.ext.AdviceListener; -import com.alibaba.jvm.sandbox.api.listener.ext.EventWatchBuilder; -import com.alibaba.jvm.sandbox.api.resource.ModuleEventWatcher; -import org.kohsuke.MetaInfServices; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.annotation.Resource; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.Statement; - -import static com.alibaba.jvm.sandbox.module.debug.JdbcLoggerModule.MonitorJavaSqlPreparedStatementStep.*; - -/** - * 基于JDBC的SQL日志 - * - * @author luanjia@taobao.com - */ -@MetaInfServices(Module.class) -@Information(id = "debug-jdbc-logger", version = "0.0.1", author = "luanjia@taobao.com") -public class JdbcLoggerModule implements Module, LoadCompleted { - - private final Logger smLogger = LoggerFactory.getLogger("DEBUG-JDBC-LOGGER"); - - @Resource - private ModuleEventWatcher moduleEventWatcher; - - @Override - public void loadCompleted() { - monitorJavaSqlStatement(); - monitorJavaSqlPreparedStatement(); - } - - // 监控java.sql.Statement的所有实现类 - private void monitorJavaSqlStatement() { - new EventWatchBuilder(moduleEventWatcher) - .onClass(Statement.class).includeSubClasses() - .onBehavior("execute*") - /**/.withParameterTypes(String.class) - /**/.withParameterTypes(String.class, int.class) - /**/.withParameterTypes(String.class, int[].class) - /**/.withParameterTypes(String.class, String[].class) - .onWatch(new AdviceListener() { - - private final String MARK_STATEMENT_EXECUTE = "MARK_STATEMENT_EXECUTE"; - private final String PREFIX = "STMT"; - - @Override - public void before(Advice advice) { - advice.attach(System.currentTimeMillis(), MARK_STATEMENT_EXECUTE); - } - - @Override - public void afterReturning(Advice advice) { - if (advice.hasMark(MARK_STATEMENT_EXECUTE)) { - final long costMs = System.currentTimeMillis() - (Long) advice.attachment(); - final String sql = advice.getParameterArray()[0].toString(); - logSql(PREFIX, sql, costMs, true, null); - } - } - - @Override - public void afterThrowing(Advice advice) { - if (advice.hasMark(MARK_STATEMENT_EXECUTE)) { - final long costMs = System.currentTimeMillis() - (Long) advice.attachment(); - final String sql = advice.getParameterArray()[0].toString(); - logSql(PREFIX, sql, costMs, false, advice.getThrowable()); - } - } - - }); - } - - enum MonitorJavaSqlPreparedStatementStep { - waiting_Connection_prepareStatement, - waiting_PreparedStatement_execute, - waiting_PreparedStatement_execute_finish, - } - - private void monitorJavaSqlPreparedStatement() { - - new EventWatchBuilder(moduleEventWatcher) - .onClass(Connection.class) - .includeSubClasses() - .onBehavior("prepareStatement") - .onClass(PreparedStatement.class) - .includeSubClasses() - .onBehavior("execute*") - .onWatch(new AdviceListener() { - - private final String MARK_PREPARED_STATEMENT_EXECUTE = "MARK_PREPARED_STATEMENT_EXECUTE"; - private final String PREFIX = "PSTMT"; - - - private final Sentry sentry - = new Sentry(waiting_Connection_prepareStatement); - - @Override - public void before(Advice advice) { - - // Connection.prepareStatement() - if (advice.getTarget() instanceof Connection - && sentry.next(waiting_Connection_prepareStatement, waiting_PreparedStatement_execute)) { - sentry.attach(advice.getParameterArray()[0].toString()); - } - - // PreparedStatement.execute*() - if (advice.getTarget() instanceof PreparedStatement - && sentry.next(waiting_PreparedStatement_execute, waiting_PreparedStatement_execute_finish)) { - advice.attach(System.currentTimeMillis(), MARK_PREPARED_STATEMENT_EXECUTE); - } - - } - - @Override - public void afterReturning(Advice advice) { - if (finishing(sentry, advice)) { - final long costMs = System.currentTimeMillis() - (Long) advice.attachment(); - final String sql = sentry.attachment(); - logSql(PREFIX, sql, costMs, true, null); - } - } - - @Override - public void afterThrowing(Advice advice) { - if (finishing(sentry, advice)) { - final long costMs = System.currentTimeMillis() - (Long) advice.attachment(); - final String sql = sentry.attachment(); - logSql(PREFIX, sql, costMs, false, advice.getThrowable()); - } - } - - private boolean finishing(final Sentry sentry, - final Advice advice) { - return advice.hasMark(MARK_PREPARED_STATEMENT_EXECUTE) - && sentry.next(waiting_PreparedStatement_execute_finish, waiting_Connection_prepareStatement); - } - - }); - } - - // SQL日志输出 - private void logSql(final String prefix, - final String sql, - final long costMs, - final boolean isSuccess, - final Throwable cause) { - smLogger.info("{};cost:{}ms;{};sql:{}", - prefix, - costMs, - isSuccess - ? "success" - : "failed", - sql, - cause - ); - } - -} diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/ExceptionLoggerModule.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/LogExceptionModule.java similarity index 54% rename from sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/ExceptionLoggerModule.java rename to sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/LogExceptionModule.java index b617544d..616138ce 100644 --- a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/ExceptionLoggerModule.java +++ b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/LogExceptionModule.java @@ -3,8 +3,9 @@ import com.alibaba.jvm.sandbox.api.Information; import com.alibaba.jvm.sandbox.api.LoadCompleted; import com.alibaba.jvm.sandbox.api.Module; -import com.alibaba.jvm.sandbox.api.listener.ext.Advice; -import com.alibaba.jvm.sandbox.api.listener.ext.AdviceListener; +import com.alibaba.jvm.sandbox.api.event.BeforeEvent; +import com.alibaba.jvm.sandbox.api.event.Event; +import com.alibaba.jvm.sandbox.api.listener.EventListener; import com.alibaba.jvm.sandbox.api.listener.ext.EventWatchBuilder; import com.alibaba.jvm.sandbox.api.resource.ModuleEventWatcher; import org.kohsuke.MetaInfServices; @@ -13,14 +14,17 @@ import javax.annotation.Resource; +import static com.alibaba.jvm.sandbox.api.event.Event.Type.BEFORE; +import static com.alibaba.jvm.sandbox.api.util.GaStringUtils.getJavaClassName; + /** * 异常类创建日志 * * @author luanjia@taobao.com */ @MetaInfServices(Module.class) -@Information(id = "debug-exception-logger", version = "0.0.1", author = "luanjia@taobao.com") -public class ExceptionLoggerModule implements Module, LoadCompleted { +@Information(id = "debug-exception-logger", version = "0.0.2", author = "luanjia@taobao.com") +public class LogExceptionModule implements Module, LoadCompleted { private final Logger exLogger = LoggerFactory.getLogger("DEBUG-EXCEPTION-LOGGER"); @@ -30,19 +34,19 @@ public class ExceptionLoggerModule implements Module, LoadCompleted { @Override public void loadCompleted() { new EventWatchBuilder(moduleEventWatcher) - .onClass(Exception.class).includeBootstrap() + .onClass(Exception.class) + .includeBootstrap() .onBehavior("") - .onWatch(new AdviceListener() { - + .onWatch(new EventListener() { @Override - public void afterReturning(Advice advice) { + public void onEvent(Event event) throws Throwable { + final BeforeEvent bEvent = (BeforeEvent) event; exLogger.info("occur an exception: {}", - advice.getTarget().getClass().getName(), - advice.getTarget() + getJavaClassName(bEvent.target.getClass()), + bEvent.target ); } - - }); + }, BEFORE); } } diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/LogServletAccessModule.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/LogServletAccessModule.java new file mode 100644 index 00000000..2abb7ff0 --- /dev/null +++ b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/LogServletAccessModule.java @@ -0,0 +1,228 @@ +package com.alibaba.jvm.sandbox.module.debug; + +import com.alibaba.jvm.sandbox.api.Information; +import com.alibaba.jvm.sandbox.api.LoadCompleted; +import com.alibaba.jvm.sandbox.api.Module; +import com.alibaba.jvm.sandbox.api.listener.ext.Advice; +import com.alibaba.jvm.sandbox.api.listener.ext.AdviceListener; +import com.alibaba.jvm.sandbox.api.listener.ext.EventWatchBuilder; +import com.alibaba.jvm.sandbox.api.resource.ModuleEventWatcher; +import com.alibaba.jvm.sandbox.module.debug.util.InterfaceProxyUtils.MethodInterceptor; +import com.alibaba.jvm.sandbox.module.debug.util.InterfaceProxyUtils.MethodInvocation; +import com.alibaba.jvm.sandbox.module.debug.util.InterfaceProxyUtils.ProxyMethod; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.kohsuke.MetaInfServices; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.Resource; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import static com.alibaba.jvm.sandbox.module.debug.util.InterfaceProxyUtils.intercept; +import static com.alibaba.jvm.sandbox.module.debug.util.InterfaceProxyUtils.puppet; +import static org.apache.commons.lang3.ArrayUtils.contains; + +/** + * 基于HTTP-SERVLET(v2.4)规范的HTTP访问日志 + * + * @author luanjia@taobao.com + */ +@MetaInfServices(Module.class) +@Information(id = "debug-servlet-access", version = "0.0.2", author = "luanjia@taobao.com") +public class LogServletAccessModule implements Module, LoadCompleted { + + private final Logger logger = LoggerFactory.getLogger("DEBUG-SERVLET-ACCESS"); + + @Resource + private ModuleEventWatcher moduleEventWatcher; + + /** + * HTTP接入信息 + */ + class HttpAccess { + final long beginTimestamp = System.currentTimeMillis(); + final String from; + final String method; + final String uri; + final Map parameterMap; + final String userAgent; + int status = 200; + + HttpAccess(final String from, + final String method, + final String uri, + final Map parameterMap, + final String userAgent) { + this.from = from; + this.method = method; + this.uri = uri; + this.parameterMap = parameterMap; + this.userAgent = userAgent; + } + + void setStatus(int status) { + this.status = status; + } + + } + + interface IHttpServletRequest { + + @ProxyMethod(name = "getRemoteAddr") + String getRemoteAddress(); + + String getMethod(); + + String getRequestURI(); + + Map getParameterMap(); + + String getHeader(String name); + + } + + @Override + public void loadCompleted() { + new EventWatchBuilder(moduleEventWatcher) + .onClass("javax.servlet.http.HttpServlet") + .includeSubClasses() + .onBehavior("service") + .withParameterTypes( + "javax.servlet.http.HttpServletRequest", + "javax.servlet.http.HttpServletResponse" + ) + .onWatch(new AdviceListener() { + + @Override + protected void before(Advice advice) throws Throwable { + + // 只关心顶层调用 + if (!advice.isProcessTop()) { + return; + } + + // 俘虏HttpServletRequest参数为傀儡 + final IHttpServletRequest httpServletRequest = puppet( + IHttpServletRequest.class, + advice.getParameterArray()[0] + ); + + // 初始化HttpAccess + final HttpAccess httpAccess = new HttpAccess( + httpServletRequest.getRemoteAddress(), + httpServletRequest.getMethod(), + httpServletRequest.getRequestURI(), + httpServletRequest.getParameterMap(), + httpServletRequest.getHeader("User-Agent") + ); + + // 附加到advice上,以便在onReturning()和onThrowing()中取出 + advice.attach(httpAccess); + + final Class classOfHttpServletResponse = advice.getBehavior() + .getDeclaringClass() + .getClassLoader() + .loadClass("javax.servlet.http.HttpServletResponse"); + + // 替换HttpServletResponse参数 + advice.changeParameter(1, intercept( + classOfHttpServletResponse, + advice.getTarget().getClass().getClassLoader(), + advice.getParameterArray()[1], + new MethodInterceptor() { + @Override + public Object invoke(MethodInvocation methodInvocation) throws Throwable { + if (contains( + new String[]{ + "setStatus", + "sendError" + }, + methodInvocation.getMethod().getName())) { + httpAccess.setStatus((Integer) methodInvocation.getArguments()[0]); + } + return methodInvocation.proceed(); + } + })); + + } + + @Override + protected void afterReturning(Advice advice) { + // 只关心顶层调用 + if (!advice.isProcessTop()) { + return; + } + + final HttpAccess httpAccess = advice.attachment(); + if (null == httpAccess) { + return; + } + + logAccess( + httpAccess, + System.currentTimeMillis() - httpAccess.beginTimestamp, + null + ); + } + + @Override + protected void afterThrowing(Advice advice) { + // 只关心顶层调用 + if (!advice.isProcessTop()) { + return; + } + + final HttpAccess httpAccess = advice.attachment(); + if (null == httpAccess) { + return; + } + + logAccess( + httpAccess, + System.currentTimeMillis() - httpAccess.beginTimestamp, + advice.getThrowable() + ); + } + + }); + + } + + // 格式化ParameterMap + private static String formatParameterMap(final Map parameterMap) { + if (MapUtils.isEmpty(parameterMap)) { + return StringUtils.EMPTY; + } + final Set kvPairs = new LinkedHashSet(); + for (final Map.Entry entry : parameterMap.entrySet()) { + kvPairs.add(String.format("%s=%s", + entry.getKey(), + StringUtils.join(entry.getValue(), ",") + )); + } + return StringUtils.join(kvPairs, "&"); + } + + + /* + * 记录access日志 + */ + private void logAccess(final HttpAccess ha, + final long costMs, + final Throwable cause) { + logger.info("{};{};{};{}ms;{};[{}];{};", + ha.from, + ha.status, + ha.method, + costMs, + ha.uri, + formatParameterMap(ha.parameterMap), + ha.userAgent, + cause + ); + } + +} diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/OnJarUnLoadCompleted.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/OnJarUnLoadCompleted.java new file mode 100644 index 00000000..f2ab0d40 --- /dev/null +++ b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/OnJarUnLoadCompleted.java @@ -0,0 +1,25 @@ +package com.alibaba.jvm.sandbox.module.debug; + +import ch.qos.logback.classic.LoggerContext; +import com.alibaba.jvm.sandbox.api.spi.ModuleJarUnLoadSpi; +import org.kohsuke.MetaInfServices; +import org.slf4j.LoggerFactory; + +@MetaInfServices(ModuleJarUnLoadSpi.class) +public class OnJarUnLoadCompleted implements ModuleJarUnLoadSpi { + + @Override + public void onJarUnLoadCompleted() { + closeLogback(); + } + + // 关闭Logback日志框架 + private void closeLogback() { + try { + ((LoggerContext) LoggerFactory.getILoggerFactory()).stop(); + } catch (Throwable cause) { + cause.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/ParamSupported.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/ParamSupported.java new file mode 100644 index 00000000..1d8469bd --- /dev/null +++ b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/ParamSupported.java @@ -0,0 +1,176 @@ +package com.alibaba.jvm.sandbox.module.debug; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.alibaba.jvm.sandbox.api.util.GaArrayUtils.isEmpty; +import static java.util.Arrays.asList; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +/** + * 命令参数支撑类 + */ +public class ParamSupported { + + /** + * 转换器(字符串到指定类型的转换器) + * + * @param 转换目标类型 + */ + interface Converter { + + /** + * 转换字符串为目标类型 + * + * @param string 字符串内容 + * @return 目标类型 + */ + T convert(String string); + } + + // 转换器集合 + final static Map, Converter> converterMap = new HashMap, Converter>(); + + static { + + /** + * 转换为字符串 + */ + regConverter(new Converter() { + @Override + public String convert(String string) { + return string; + } + }, String.class); + + /** + * 转换为Long + */ + regConverter(new Converter() { + @Override + public Long convert(String string) { + return Long.valueOf(string); + } + }, long.class, Long.class); + + /** + * 转换为Double + */ + regConverter(new Converter() { + @Override + public Double convert(String string) { + return Double.valueOf(string); + } + }, double.class, Double.class); + + /** + * 转换为Integer + */ + regConverter(new Converter() { + @Override + public Integer convert(String string) { + return Integer.valueOf(string); + } + }, int.class, Integer.class); + + } + + /** + * 注册类型转换器 + * + * @param converter 转换器 + * @param typeArray 类型的Java类数组 + * @param 类型 + */ + protected static void regConverter(Converter converter, Class... typeArray) { + for (final Class type : typeArray) { + converterMap.put(type, converter); + } + } + + protected static T getParameter(final Map param, + final String name, + final Converter converter, + final T defaultValue) { + final String string = param.get(name); + return isNotBlank(string) + ? converter.convert(string) + : defaultValue; + } + + protected static List getParameters(final Map param, + final String name, + final Converter converter, + final T... defaultValueArray) { + final String[] stringArray = param.get(name); + if (isEmpty(stringArray)) { + return asList(defaultValueArray); + } + final List values = new ArrayList(); + for (final String string : stringArray) { + values.add(converter.convert(string)); + } + return values; + } + + + protected static String getParameter(final Map param, + final String name) { + return getParameter( + param, + name, + String.class, + null + ); + } + + protected static String getParameter(final Map param, + final String name, + final String defaultString) { + return getParameter( + param, + name, + String.class, + defaultString + ); + } + + protected static T getParameter(final Map param, + final String name, + final Class type) { + return getParameter( + param, + name, + type, + null + ); + } + + protected static T getParameter(final Map param, + final String name, + final Class type, + final T defaultValue) { + return getParameter( + param, + name, + (Converter) converterMap.get(type), + defaultValue + ); + } + + protected static List getParameters(final Map param, + final String name, + final Class type, + final T... defaultValueArray) { + return getParameters( + param, + name, + (Converter) converterMap.get(type), + defaultValueArray + ); + } + + +} diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/SpringLoggerModule.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/SpringLoggerModule.java deleted file mode 100644 index 1ef10ba2..00000000 --- a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/SpringLoggerModule.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.alibaba.jvm.sandbox.module.debug; - -import com.alibaba.jvm.sandbox.api.Information; -import com.alibaba.jvm.sandbox.api.LoadCompleted; -import com.alibaba.jvm.sandbox.api.Module; -import com.alibaba.jvm.sandbox.api.listener.ext.Advice; -import com.alibaba.jvm.sandbox.api.listener.ext.AdviceListener; -import com.alibaba.jvm.sandbox.api.listener.ext.EventWatchBuilder; -import com.alibaba.jvm.sandbox.api.resource.ModuleEventWatcher; -import org.kohsuke.MetaInfServices; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.annotation.Resource; - -/** - * Spring容器的调试日志 - */ -@MetaInfServices(Module.class) -@Information(id = "debug-spring-logger", version = "0.0.1", author = "luanjia@taobao.com") -public class SpringLoggerModule implements Module, LoadCompleted { - - private final Logger spLogger = LoggerFactory.getLogger("DEBUG-SPRING-LOGGER"); - - @Resource - private ModuleEventWatcher moduleEventWatcher; - - @Override - public void loadCompleted() { - buildingSpringRestController(); - } - - private void buildingSpringRestController() { - new EventWatchBuilder(moduleEventWatcher) - .onAnyClass() - .hasAnnotationTypes("org.springframework.web.bind.annotation.RestController") - .onAnyBehavior() - .hasAnnotationTypes("org.springframework.web.bind.annotation.RequestMapping") - .onWatch(new AdviceListener() { - - @Override - public void before(Advice advice) { - advice.attach(System.currentTimeMillis()); - } - - @Override - public void afterReturning(Advice advice) { - logSpringRestController(advice); - } - - @Override - public void afterThrowing(Advice advice) { - logSpringRestController(advice); - } - - private void logSpringRestController(Advice advice) { - logSpring( - "REST", - System.currentTimeMillis() - (Long) advice.attachment(), - advice.getTarget().getClass().getName() + "#" + advice.getBehavior().getName(), - advice.isReturn() ? "SUC" : "FAL", - advice.isThrows() ? advice.getThrowable() : null - ); - } - - }); - } - - /* - * 时间:日志框架提供 - * 地点:SpringMod - * 耗时:costMs - * 人物:who - * 事件:message/throwable - */ - private void logSpring(final String springMod, - final long cost, - final String who, - final String message, - final Throwable throwable) { - spLogger.info("{}:{}ms:{}:{}", springMod, cost, who, message, throwable); - } - -} diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/util/Express.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/util/Express.java index 860bc6f6..ad6a6871 100755 --- a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/util/Express.java +++ b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/util/Express.java @@ -89,12 +89,12 @@ public String getExpress() { */ class ExpressFactory { - private static final ThreadLocal expressRef = new ThreadLocal() { - @Override - protected Express initialValue() { - return new OgnlExpress(); - } - }; +// private static final ThreadLocal expressRef = new ThreadLocal() { +// @Override +// protected Express initialValue() { +// return new OgnlExpress(); +// } +// }; /** * 构造表达式执行类 @@ -103,7 +103,7 @@ protected Express initialValue() { * @return 返回表达式实现 */ public static Express newExpress(Object object) { - return expressRef.get().reset().bind(object); + return new OgnlExpress().reset().bind(object); // return new OgnlExpress().bind(object); } diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/util/InterfaceProxyUtils.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/util/InterfaceProxyUtils.java new file mode 100644 index 00000000..ccbcd098 --- /dev/null +++ b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/util/InterfaceProxyUtils.java @@ -0,0 +1,186 @@ +package com.alibaba.jvm.sandbox.module.debug.util; + +import org.apache.commons.lang3.StringUtils; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import static com.alibaba.jvm.sandbox.api.util.GaStringUtils.getJavaClassName; +import static com.alibaba.jvm.sandbox.api.util.GaStringUtils.getJavaClassNameArray; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static org.apache.commons.lang3.ArrayUtils.getLength; + +public class InterfaceProxyUtils { + + @Target(METHOD) + @Retention(RUNTIME) + public @interface ProxyMethod { + + /** + * 目标方法名 + * + * @return 目标方法名 + */ + String name(); + + } + + /** + * 用于包装目标对象操作的代理方法处理 + */ + static abstract class WrapInvocationHandler implements InvocationHandler { + + final Map mappingOfWrapMethods = new ConcurrentHashMap(); + + String getInterfaceMethodName(final Method interfaceMethod) { + final ProxyMethod proxyMethod = interfaceMethod.getAnnotation(ProxyMethod.class); + return null == proxyMethod + ? interfaceMethod.getName() + : proxyMethod.name(); + } + + boolean isEquals(final String[] srcStringArray, + final String[] dstStringArray) { + final int length; + if ((length = getLength(srcStringArray)) != getLength(dstStringArray)) { + return false; + } + for (int index = 0; index < length; index++) { + if (!StringUtils.equals(srcStringArray[index], dstStringArray[index])) { + return false; + } + } + return true; + } + + /** + * 比较interfaceMethod和targetMethod两个方法是否接近 + * + * @param interfaceMethod 接口声明的方法 + * @param targetMethod 目标对象声明的方法 + * @return TRUE:接近;FALSE:不接近 + */ + boolean isCloseTo(final Method interfaceMethod, final Method targetMethod) { + return StringUtils.equals(getInterfaceMethodName(interfaceMethod), targetMethod.getName()) + && isEquals(getJavaClassNameArray(interfaceMethod.getParameterTypes()), getJavaClassNameArray(targetMethod.getParameterTypes())); + + } + + Method getTargetMethod(final Method interfaceMethod, final Object target) throws NoSuchMethodException { + if (mappingOfWrapMethods.containsKey(interfaceMethod)) { + return mappingOfWrapMethods.get(interfaceMethod); + } + for (final Method targetMethod : target.getClass().getMethods()) { + if (isCloseTo(interfaceMethod, targetMethod)) { + mappingOfWrapMethods.put(interfaceMethod, targetMethod); + return targetMethod; + } + } + throw new NoSuchMethodException(String.format("%s.%s(%s) method not found!", + getJavaClassName(target.getClass()), + getInterfaceMethodName(interfaceMethod), + StringUtils.join(getJavaClassNameArray(interfaceMethod.getParameterTypes()), ",") + )); + } + + } + + /** + * 构造一个接口的实现傀儡类,用接口去调用目标类 + * + * @param interfaceClass 目标接口 + * @param target 傀儡类实例 + * @param 目标接口类型 + * @return 被目标接口操纵的傀儡对象实例 + */ + public static T puppet(final Class interfaceClass, + final Object target) { + return (T) Proxy.newProxyInstance( + interfaceClass.getClassLoader(), + new Class[]{interfaceClass}, + new WrapInvocationHandler() { + + @Override + public Object invoke(Object proxy, Method interfaceMethod, Object[] args) throws Throwable { + return getTargetMethod(interfaceMethod, target).invoke(target, args); + } + + } + ); + } + + + public interface MethodInterceptor { + Object invoke(MethodInvocation methodInvocation) throws Throwable; + } + + public interface MethodInvocation { + Method getMethod(); + + Object[] getArguments(); + + Object proceed() throws Throwable; + + Object getThis(); + + AccessibleObject getStaticPart(); + } + + /** + * 拦截目标类的方法 + * + * @param interfaceClassInTargetClassLoader 目标接口 + * @param targetClassLoader 目标对象所在ClassLoader + * @param target 目标对象实例 + * @param interceptor 拦截器 + * @return 带拦截器的目标对象实例 + */ + public static Object intercept(final Class interfaceClassInTargetClassLoader, + final ClassLoader targetClassLoader, + final Object target, + final MethodInterceptor interceptor) { + return Proxy.newProxyInstance( + targetClassLoader, + new Class[]{interfaceClassInTargetClassLoader}, + new InvocationHandler() { + @Override + public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable { + return interceptor.invoke(new MethodInvocation() { + @Override + public Method getMethod() { + return method; + } + + @Override + public Object[] getArguments() { + return args; + } + + @Override + public Object proceed() throws Throwable { + return method.invoke(target, args); + } + + @Override + public Object getThis() { + return target; + } + + @Override + public AccessibleObject getStaticPart() { + return method; + } + }); + } + } + ); + } + +} diff --git a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/util/SimpleDateFormatHolder.java b/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/util/SimpleDateFormatHolder.java deleted file mode 100755 index 62335d8a..00000000 --- a/sandbox-debug-module/src/main/java/com/alibaba/jvm/sandbox/module/debug/util/SimpleDateFormatHolder.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.alibaba.jvm.sandbox.module.debug.util; - -import java.text.SimpleDateFormat; -import java.util.Date; - -/** - * SimpleDateFormat Holder - * - * @author oldmanpushcart@gmail.com - */ -public class SimpleDateFormatHolder extends ThreadLocal { - - @Override - protected SimpleDateFormat initialValue() { - return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - } - - private static final SimpleDateFormatHolder instance = new SimpleDateFormatHolder(); - - private SimpleDateFormatHolder() { - // - } - - public static SimpleDateFormatHolder getInstance() { - return instance; - } - - /** - * 格式化日期 - * - * @param date 日期 - * @return 格式化后字符串 - */ - public String format(Date date) { - return getInstance().get().format(date); - } - - - /** - * 格式化日期 - * - * @param gmt gmt - * @return 格式化后字符串 - */ - public String format(long gmt) { - return getInstance().get().format(new Date(gmt)); - } - -} diff --git a/sandbox-debug-module/src/main/resources/logback.xml b/sandbox-debug-module/src/main/resources/logback.xml index d80c27bd..ed64a6e3 100755 --- a/sandbox-debug-module/src/main/resources/logback.xml +++ b/sandbox-debug-module/src/main/resources/logback.xml @@ -2,11 +2,11 @@ - + - ${user.home}/logs/sandbox/debug/servlet-monitor.log + ${user.home}/logs/sandbox/debug/servlet-access.log - ${user.home}/logs/sandbox/debug/servlet-monitor.log.%d{yyyy-MM-dd} + ${user.home}/logs/sandbox/debug/servlet-access.log.%d{yyyy-MM-dd} 30 @@ -16,6 +16,22 @@ + + diff --git a/sandbox-debug-module/target/classes/META-INF/services/com.alibaba.jvm.sandbox.api.Module b/sandbox-debug-module/target/classes/META-INF/services/com.alibaba.jvm.sandbox.api.Module deleted file mode 100644 index 19000a60..00000000 --- a/sandbox-debug-module/target/classes/META-INF/services/com.alibaba.jvm.sandbox.api.Module +++ /dev/null @@ -1,7 +0,0 @@ -com.alibaba.jvm.sandbox.module.debug.DebugRalphModule -com.alibaba.jvm.sandbox.module.debug.DebugTraceModule -com.alibaba.jvm.sandbox.module.debug.DebugWatchModule -com.alibaba.jvm.sandbox.module.debug.ExceptionLoggerModule -com.alibaba.jvm.sandbox.module.debug.HttpHttpAccessLoggerModule -com.alibaba.jvm.sandbox.module.debug.JdbcLoggerModule -com.alibaba.jvm.sandbox.module.debug.SpringLoggerModule diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$1.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$1.class deleted file mode 100644 index 776be39b..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$1.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$2.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$2.class deleted file mode 100644 index 70f31989..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$2.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$3.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$3.class deleted file mode 100644 index ae606de1..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$3.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$4.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$4.class deleted file mode 100644 index 5be34be3..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$4.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$5.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$5.class deleted file mode 100644 index 482f742a..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$5.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$6.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$6.class deleted file mode 100644 index 0474db73..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$6.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionFactory.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionFactory.class deleted file mode 100644 index 289712ba..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionFactory.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType$1.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType$1.class deleted file mode 100644 index 22b2681d..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType$1.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType$2.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType$2.class deleted file mode 100644 index 34134ac6..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType$2.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType$3.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType$3.class deleted file mode 100644 index ee0e1c1a..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType$3.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType$4.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType$4.class deleted file mode 100644 index 78c2a924..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType$4.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType.class deleted file mode 100644 index 48f8bb34..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule$ExceptionType.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule.class deleted file mode 100644 index 7d747f97..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugRalphModule.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugTraceModule$1.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugTraceModule$1.class deleted file mode 100644 index 54390c51..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugTraceModule$1.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugTraceModule.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugTraceModule.class deleted file mode 100644 index 1a4b653a..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugTraceModule.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule$1.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule$1.class deleted file mode 100644 index ee410901..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule$1.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule$2.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule$2.class deleted file mode 100644 index 415404f8..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule$2.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule$Bind.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule$Bind.class deleted file mode 100644 index e9df0ea2..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule$Bind.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule$Trigger.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule$Trigger.class deleted file mode 100644 index 04ad4ca8..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule$Trigger.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule.class deleted file mode 100644 index 264ae81d..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/DebugWatchModule.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/ExceptionLoggerModule$1.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/ExceptionLoggerModule$1.class deleted file mode 100644 index 811cea7b..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/ExceptionLoggerModule$1.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/ExceptionLoggerModule.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/ExceptionLoggerModule.class deleted file mode 100644 index ad0c2cff..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/ExceptionLoggerModule.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule$1.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule$1.class deleted file mode 100644 index fac06932..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule$1.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule$2.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule$2.class deleted file mode 100644 index 8efd9161..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule$2.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule$HttpAccess.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule$HttpAccess.class deleted file mode 100644 index 7b05be13..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule$HttpAccess.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule$HttpProcessStep.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule$HttpProcessStep.class deleted file mode 100644 index 505e43b4..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule$HttpProcessStep.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule.class deleted file mode 100644 index 9705a508..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpHttpAccessLoggerModule.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$1.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$1.class deleted file mode 100644 index ab851791..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$1.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$2.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$2.class deleted file mode 100644 index 8fde122d..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$2.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$3.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$3.class deleted file mode 100644 index baa1cf63..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$3.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$4.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$4.class deleted file mode 100644 index 29c8380e..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$4.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$Converter.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$Converter.class deleted file mode 100644 index 559059ad..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$Converter.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$HttpErrorCodeException.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$HttpErrorCodeException.class deleted file mode 100644 index b5d782c2..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported$HttpErrorCodeException.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported.class deleted file mode 100644 index 89e61f29..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/HttpSupported.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule$1.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule$1.class deleted file mode 100644 index a184c08b..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule$1.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule$2.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule$2.class deleted file mode 100644 index c55c6f2b..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule$2.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule$MonitorJavaSqlPreparedStatementStep.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule$MonitorJavaSqlPreparedStatementStep.class deleted file mode 100644 index 1d6e2d31..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule$MonitorJavaSqlPreparedStatementStep.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule.class deleted file mode 100644 index 9a2c74c2..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/JdbcLoggerModule.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/ProgressPrinter.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/ProgressPrinter.class deleted file mode 100644 index bb02de2e..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/ProgressPrinter.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/SpringLoggerModule$1.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/SpringLoggerModule$1.class deleted file mode 100644 index 338d2427..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/SpringLoggerModule$1.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/SpringLoggerModule.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/SpringLoggerModule.class deleted file mode 100644 index c1d2caf9..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/SpringLoggerModule.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TComponent.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TComponent.class deleted file mode 100644 index 2d645cc7..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TComponent.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TTree$1.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TTree$1.class deleted file mode 100644 index 4be6c3d2..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TTree$1.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TTree$Callback.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TTree$Callback.class deleted file mode 100644 index f8e0a910..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TTree$Callback.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TTree$Node.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TTree$Node.class deleted file mode 100644 index 162f26f3..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TTree$Node.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TTree.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TTree.class deleted file mode 100644 index b81c08c7..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/textui/TTree.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express$ExpressException.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express$ExpressException.class deleted file mode 100644 index 8898ec01..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express$ExpressException.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express$ExpressFactory$1.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express$ExpressFactory$1.class deleted file mode 100644 index d47dc88a..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express$ExpressFactory$1.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express$ExpressFactory.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express$ExpressFactory.class deleted file mode 100644 index 49194afe..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express$ExpressFactory.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express$OgnlExpress.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express$OgnlExpress.class deleted file mode 100644 index 3472e9af..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express$OgnlExpress.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express.class deleted file mode 100644 index 3fc582cb..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/Express.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/GaEnumUtils.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/GaEnumUtils.class deleted file mode 100644 index 6ce45033..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/GaEnumUtils.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/SimpleDateFormatHolder.class b/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/SimpleDateFormatHolder.class deleted file mode 100644 index 1297d9a4..00000000 Binary files a/sandbox-debug-module/target/classes/com/alibaba/jvm/sandbox/module/debug/util/SimpleDateFormatHolder.class and /dev/null differ diff --git a/sandbox-debug-module/target/classes/logback.xml b/sandbox-debug-module/target/classes/logback.xml deleted file mode 100755 index d80c27bd..00000000 --- a/sandbox-debug-module/target/classes/logback.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - ${user.home}/logs/sandbox/debug/servlet-monitor.log - - ${user.home}/logs/sandbox/debug/servlet-monitor.log.%d{yyyy-MM-dd} - 30 - - - %d{yyyy-MM-dd HH:mm:ss} %-5level %msg%n - UTF-8 - - - - - - - - ${user.home}/logs/sandbox/debug/exception-monitor.log - - ${user.home}/logs/sandbox/debug/exception-monitor.log.%d{yyyy-MM-dd} - 30 - - - %d{yyyy-MM-dd HH:mm:ss} %-5level %msg%n - UTF-8 - - - - - - - - ${user.home}/logs/sandbox/debug/jdbc-monitor.log - - ${user.home}/logs/sandbox/debug/jdbc-monitor.log.%d{yyyy-MM-dd} - 30 - - - %d{yyyy-MM-dd HH:mm:ss} %-5level %msg%n - UTF-8 - - - - - - - - ${user.home}/logs/sandbox/debug/spring-monitor.log - - ${user.home}/logs/sandbox/debug/spring-monitor.log.%d{yyyy-MM-dd} - 30 - - - %d{yyyy-MM-dd HH:mm:ss} %-5level %msg%n - UTF-8 - - - - - - - - ${user.home}/logs/sandbox/debug/debug.log - - ${user.home}/logs/sandbox/debug/debug.log.%d{yyyy-MM-dd} - 30 - - - %d{yyyy-MM-dd HH:mm:ss} %-5level %msg%n - UTF-8 - - - - - \ No newline at end of file diff --git a/sandbox-mgr-module/pom.xml b/sandbox-mgr-module/pom.xml index 0d17e5f7..7bf4238b 100755 --- a/sandbox-mgr-module/pom.xml +++ b/sandbox-mgr-module/pom.xml @@ -6,7 +6,7 @@ com.alibaba.jvm.sandbox sandbox-module-starter - 1.1.2-SNAPSHOT + 1.2.0-SNAPSHOT ../sandbox-module-starter/pom.xml sandbox-mgr-module diff --git a/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/ControlModule.java b/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/ControlModule.java index 32986785..2cb6bbbd 100644 --- a/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/ControlModule.java +++ b/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/ControlModule.java @@ -2,21 +2,19 @@ import com.alibaba.jvm.sandbox.api.Information; import com.alibaba.jvm.sandbox.api.Module; -import com.alibaba.jvm.sandbox.api.ModuleException; -import com.alibaba.jvm.sandbox.api.http.Http; +import com.alibaba.jvm.sandbox.api.annotation.Command; import com.alibaba.jvm.sandbox.api.resource.ConfigInfo; -import com.alibaba.jvm.sandbox.api.resource.ModuleManager; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.MethodUtils; +import org.kohsuke.MetaInfServices; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -@Information(id = "control", version = "0.0.1", author = "luanjia@taobao.com") +@MetaInfServices(Module.class) +@Information(id = "sandbox-control", version = "0.0.3", author = "luanjia@taobao.com") public class ControlModule implements Module { private final Logger logger = LoggerFactory.getLogger(getClass()); @@ -24,112 +22,30 @@ public class ControlModule implements Module { @Resource private ConfigInfo configInfo; - @Resource - private ModuleManager moduleManager; - - private ClassLoader getSandboxClassLoader(final Class classOfAgentLauncher) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - return (ClassLoader) MethodUtils.invokeStaticMethod( - classOfAgentLauncher, - "getClassLoader", - configInfo.getNamespace() - ); - } + // 卸载jvm-sandbox + private void uninstall() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { + final Class classOfAgentLauncher = getClass().getClassLoader() + .loadClass("com.alibaba.jvm.sandbox.agent.AgentLauncher"); - // 清理命名空间所对应的SandboxClassLoader - private ClassLoader cleanSandboxClassLoader(final Class classOfAgentLauncher) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - // 清理AgentLauncher.sandboxClassLoaderMap - final ClassLoader sandboxClassLoader = (ClassLoader) MethodUtils.invokeStaticMethod( + MethodUtils.invokeStaticMethod( classOfAgentLauncher, - "cleanClassLoader", + "uninstall", configInfo.getNamespace() ); - logger.info("clean SandboxClassLoader from jvm-sandbox[{}] success, for shutdown.", configInfo.getNamespace()); - return sandboxClassLoader; - } - - // 清理Spy中对Method的引用 - private void cleanSpy() throws ClassNotFoundException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { - final String namespace = configInfo.getNamespace(); - MethodUtils.invokeStaticMethod( - getClass().getClassLoader().loadClass("java.com.alibaba.jvm.sandbox.spy.Spy"), - "clean", - namespace - ); - logger.info("clean Spy's method from jvm-sandbox[{}] success, for shutdown.", namespace); - } - - // 卸载所有模块 - // 从这里开始只允许调用JDK自带的反射方法,因为ControlModule已经完成卸载,你找不到apache的包了 - private void unloadModules() throws ModuleException { - - for (final Module module : moduleManager.list()) { - final Information information = module.getClass().getAnnotation(Information.class); - if (null == information - || StringUtils.isBlank(information.id())) { - continue; - } - // 如果遇到自己,需要最后才卸载 - if (module == this) { - continue; - } - moduleManager.unload(information.id()); - logger.info("unload module={} from jvm-sandbox[{}] success, for shutdown.", information.id(), configInfo.getNamespace()); - } - - } - - // 卸载自己 - private void unloadSelf() throws ModuleException { - // 卸载自己 - final String self = getClass().getAnnotation(Information.class).id(); - moduleManager.unload(self); - logger.info("unload module={} from jvm-sandbox[{}] success, for shutdown.", self, configInfo.getNamespace()); - } - - // 关闭HTTP服务器 - private void shutdownServer(final ClassLoader sandboxClassLoader) - throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { - - if (null == sandboxClassLoader) { - logger.warn("detection an warning, target SandboxClassLoader[namespace={}] is null, shutdown server will be ignore", - configInfo.getNamespace()); - return; - } - - final Class classOfCoreServer = sandboxClassLoader - .loadClass("com.alibaba.jvm.sandbox.core.server.ProxyCoreServer"); - final Object objectOfJettyCoreServer = classOfCoreServer.getMethod("getInstance").invoke(null); - final Method methodOfDestroy = classOfCoreServer.getMethod("destroy"); - methodOfDestroy.invoke(objectOfJettyCoreServer); - logger.info("shutdown jvm-sandbox[{}] server success for shutdown.", configInfo.getNamespace()); } - @Http("/shutdown") - public void shutdown(final HttpServletResponse resp) throws Exception { + // @Http("/shutdown") + @Command("shutdown") + public void shutdown(final PrintWriter writer) { logger.info("prepare to shutdown jvm-sandbox[{}].", configInfo.getNamespace()); - final Class classOfAgentLauncher = getClass().getClassLoader() - .loadClass("com.alibaba.jvm.sandbox.agent.AgentLauncher"); - - // 卸载模块 - unloadModules(); - - // 清理Spy的注册方法回调 - cleanSpy(); - // 关闭HTTP服务器 final Thread shutdownJvmSandboxHook = new Thread(new Runnable() { @Override public void run() { try { - - shutdownServer(getSandboxClassLoader(classOfAgentLauncher)); - unloadSelf(); - cleanSandboxClassLoader(classOfAgentLauncher); - + uninstall(); } catch (Throwable cause) { logger.warn("shutdown jvm-sandbox[{}] failed.", configInfo.getNamespace(), cause); } @@ -138,9 +54,9 @@ public void run() { shutdownJvmSandboxHook.setDaemon(true); // 在卸载自己之前,先向这个世界发出最后的呐喊吧! - resp.getWriter().println(String.format("jvm-sandbox[%s] shutdown finished.", configInfo.getNamespace())); - resp.getWriter().flush(); - resp.getWriter().close(); + writer.println(String.format("jvm-sandbox[%s] shutdown finished.", configInfo.getNamespace())); + writer.flush(); + writer.close(); shutdownJvmSandboxHook.start(); diff --git a/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/InfoModule.java b/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/InfoModule.java index 5d7907c1..af7abffa 100755 --- a/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/InfoModule.java +++ b/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/InfoModule.java @@ -2,31 +2,33 @@ import com.alibaba.jvm.sandbox.api.Information; import com.alibaba.jvm.sandbox.api.Module; +import com.alibaba.jvm.sandbox.api.annotation.Command; import com.alibaba.jvm.sandbox.api.event.Event; -import com.alibaba.jvm.sandbox.api.http.Http; import com.alibaba.jvm.sandbox.api.resource.ConfigInfo; -import com.alibaba.jvm.sandbox.api.resource.EventMonitor; +import org.kohsuke.MetaInfServices; import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.io.PrintWriter; /** * 沙箱信息模块 * * @author luanjia@taobao.com */ -@Information(id = "info", version = "0.0.3", author = "luanjia@taobao.com") +@MetaInfServices(Module.class) +@Information(id = "sandbox-info", version = "0.0.4", author = "luanjia@taobao.com") public class InfoModule implements Module { @Resource private ConfigInfo configInfo; - @Resource - private EventMonitor eventMonitor; +// @Resource +// private EventMonitor eventMonitor; - @Http("/version") - public void version(final HttpServletResponse resp) throws IOException { + //@Http("/version") + @Command("version") + public void version(final PrintWriter writer) throws IOException { final StringBuilder versionSB = new StringBuilder() .append(" NAMESPACE : ").append(configInfo.getNamespace()).append("\n") @@ -40,32 +42,29 @@ public void version(final HttpServletResponse resp) throws IOException { .append(" USER_MODULE_LIB : ").append(configInfo.getUserModuleLibPath()).append("\n") .append(" SYSTEM_PROVIDER_LIB : ").append(configInfo.getSystemProviderLibPath()).append("\n") .append(" EVENT_POOL_SUPPORT : ").append(configInfo.isEnableEventPool() ? "ENABLE" : "DISABLE"); - /*############################# : */ - if (configInfo.isEnableEventPool()) { - versionSB - .append("\n") - /*############################# : */ - .append(" EVENT_POOL_PER_KEY_IDLE_MIN : ").append(configInfo.getEventPoolMinIdlePerEvent()).append("\n") - .append(" EVENT_POOL_PER_KEY_IDLE_MAX : ").append(configInfo.getEventPoolMaxIdlePerEvent()).append("\n") - .append(" EVENT_POOL_PER_KEY_TOTAL_MAX : ").append(configInfo.getEventPoolMaxTotalPerEvent()).append("\n") - .append(" EVENT_POOL_TOTAL : ").append(configInfo.getEventPoolMaxTotal()) - ; - } +// /*############################# : */ +// if (configInfo.isEnableEventPool()) { +// versionSB +// .append("\n") +// /*############################# : */ +// .append(" EVENT_POOL_PER_KEY_IDLE_MIN : ").append(configInfo.getEventPoolMinIdlePerEvent()).append("\n") +// .append(" EVENT_POOL_PER_KEY_IDLE_MAX : ").append(configInfo.getEventPoolMaxIdlePerEvent()).append("\n") +// .append(" EVENT_POOL_PER_KEY_TOTAL_MAX : ").append(configInfo.getEventPoolMaxTotalPerEvent()).append("\n") +// .append(" EVENT_POOL_TOTAL : ").append(configInfo.getEventPoolMaxTotal()) +// ; +// } - resp.getWriter().println(versionSB.toString()); + writer.println(versionSB.toString()); + writer.flush(); } - @Http("/event-pool") - public void eventPool(final HttpServletResponse resp) throws IOException { + //@Http("/event-pool") + @Command("event-pool") + public void eventPool(final PrintWriter writer) throws IOException { for (Event.Type type : Event.Type.values()) { - resp.getWriter().println(String.format( - "%18s : %d / %d", - type, - eventMonitor.getEventPoolInfo().getNumActive(type), - eventMonitor.getEventPoolInfo().getNumIdle(type) - )); + writer.println(String.format("%18s : %d / %d", type, 0, 0)); } } diff --git a/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/ModuleMgrModule.java b/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/ModuleMgrModule.java index 728bb987..c3cecee7 100755 --- a/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/ModuleMgrModule.java +++ b/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/ModuleMgrModule.java @@ -3,26 +3,24 @@ import com.alibaba.jvm.sandbox.api.Information; import com.alibaba.jvm.sandbox.api.Module; import com.alibaba.jvm.sandbox.api.ModuleException; -import com.alibaba.jvm.sandbox.api.http.Http; +import com.alibaba.jvm.sandbox.api.annotation.Command; import com.alibaba.jvm.sandbox.api.resource.ModuleManager; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import org.kohsuke.MetaInfServices; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Resource; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; +import java.util.Map; import static com.alibaba.jvm.sandbox.api.util.GaStringUtils.matching; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import static org.apache.commons.lang3.StringUtils.EMPTY; /** @@ -30,7 +28,8 @@ * * @author luanjia@taobao.com */ -@Information(id = "module-mgr", author = "luanjia@taobao.com", version = "0.0.1") +@MetaInfServices(Module.class) +@Information(id = "sandbox-module-mgr", author = "luanjia@taobao.com", version = "0.0.2") public class ModuleMgrModule implements Module { private final Logger logger = LoggerFactory.getLogger(getClass()); @@ -39,8 +38,8 @@ public class ModuleMgrModule implements Module { private ModuleManager moduleManager; // 获取参数值 - private String getParamWithDefault(final HttpServletRequest req, final String name, final String defaultValue) { - final String valueFromReq = req.getParameter(name); + private String getParamWithDefault(final Map param, final String name, final String defaultValue) { + final String valueFromReq = param.get(name); return StringUtils.isBlank(valueFromReq) ? defaultValue : valueFromReq; @@ -64,11 +63,11 @@ private void output(final PrintWriter writer, final String format, final Object. writer.println(String.format(format, objectArray)); } - @Http("/list") - public void list(final HttpServletResponse resp) throws IOException { + // @Http("/list") + @Command("list") + public void list(final PrintWriter writer) throws IOException { int total = 0; - final PrintWriter writer = resp.getWriter(); for (final Module module : moduleManager.list()) { final Information info = module.getClass().getAnnotation(Information.class); @@ -104,26 +103,29 @@ public void list(final HttpServletResponse resp) throws IOException { output(writer, "total=%s", total); } - @Http("/flush") - public void flush(final HttpServletRequest req, - final HttpServletResponse resp) throws ModuleException, IOException { - final String isForceString = getParamWithDefault(req, "force", EMPTY); + // @Http("/flush") + @Command("flush") + public void flush(final Map param, + final PrintWriter writer) throws ModuleException { + final String isForceString = getParamWithDefault(param, "force", EMPTY); final boolean isForce = BooleanUtils.toBoolean(isForceString); moduleManager.flush(isForce); - output(resp.getWriter(), "module flush finished, total=%s;", moduleManager.list().size()); + output(writer, "module flush finished, total=%s;", moduleManager.list().size()); } - @Http("/reset") - public void reset(final HttpServletResponse resp) throws ModuleException, IOException { + // @Http("/reset") + @Command("reset") + public void reset(final PrintWriter writer) throws ModuleException { moduleManager.reset(); - output(resp.getWriter(), "module reset finished, total=%s;", moduleManager.list().size()); + output(writer, "module reset finished, total=%s;", moduleManager.list().size()); } - @Http("/unload") - public void unload(final HttpServletRequest req, - final HttpServletResponse resp) throws ServletException, IOException { + // @Http("/unload") + @Command("unload") + public void unload(final Map param, + final PrintWriter writer) { int total = 0; - final String idsStringPattern = getParamWithDefault(req, "ids", EMPTY); + final String idsStringPattern = getParamWithDefault(param, "ids", EMPTY); for (final Module module : search(idsStringPattern)) { final Information info = module.getClass().getAnnotation(Information.class); try { @@ -133,14 +135,15 @@ public void unload(final HttpServletRequest req, logger.warn("unload module[id={};] occur error={}.", me.getUniqueId(), me.getErrorCode(), me); } } - output(resp.getWriter(), "total %s module unloaded.", total); + output(writer, "total %s module unloaded.", total); } - @Http("/active") - public void active(final HttpServletRequest req, - final HttpServletResponse resp) throws ModuleException, IOException { + // @Http("/active") + @Command("active") + public void active(final Map param, + final PrintWriter writer) throws ModuleException { int total = 0; - final String idsStringPattern = getParamWithDefault(req, "ids", EMPTY); + final String idsStringPattern = getParamWithDefault(param, "ids", EMPTY); for (final Module module : search(idsStringPattern)) { final Information info = module.getClass().getAnnotation(Information.class); final boolean isActivated = moduleManager.isActivated(info.id()); @@ -155,14 +158,15 @@ public void active(final HttpServletRequest req, total++; } }// for - output(resp.getWriter(), "total %s module activated.", total); + output(writer, "total %s module activated.", total); } - @Http("/frozen") - public void frozen(final HttpServletRequest req, - final HttpServletResponse resp) throws ModuleException, IOException { + // @Http("/frozen") + @Command("frozen") + public void frozen(final Map param, + final PrintWriter writer) throws ModuleException { int total = 0; - final String idsStringPattern = getParamWithDefault(req, "ids", EMPTY); + final String idsStringPattern = getParamWithDefault(param, "ids", EMPTY); for (final Module module : search(idsStringPattern)) { final Information info = module.getClass().getAnnotation(Information.class); final boolean isActivated = moduleManager.isActivated(info.id()); @@ -178,22 +182,23 @@ public void frozen(final HttpServletRequest req, } } - output(resp.getWriter(), "total %s module frozen.", total); + output(writer, "total %s module frozen.", total); } - @Http("/detail") - public void detail(final HttpServletRequest req, - final HttpServletResponse resp) throws ModuleException, IOException { - final String uniqueId = req.getParameter("id"); + // @Http("/detail") + @Command("detail") + public void detail(final Map param, + final PrintWriter writer) throws ModuleException { + final String uniqueId = param.get("id"); if (StringUtils.isBlank(uniqueId)) { // 如果参数不对,则认为找不到对应的沙箱模块,返回400 - resp.sendError(SC_BAD_REQUEST, "id parameter was required."); + writer.println("id parameter was required."); return; } final Module module = moduleManager.get(uniqueId); if (null == module) { - resp.sendError(SC_BAD_REQUEST, String.format("module[id=%s] is not existed.", uniqueId)); + writer.println(String.format("module[id=%s] is not existed.", uniqueId)); return; } @@ -214,7 +219,7 @@ public void detail(final HttpServletRequest req, " cCnt : " + cCnt + "\n" + " mCnt : " + mCnt; - output(resp.getWriter(), sb); + output(writer, sb); } diff --git a/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/OnJarUnLoadCompleted.java b/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/OnJarUnLoadCompleted.java new file mode 100644 index 00000000..dd2ff5bb --- /dev/null +++ b/sandbox-mgr-module/src/main/java/com/alibaba/jvm/sandbox/module/mgr/OnJarUnLoadCompleted.java @@ -0,0 +1,25 @@ +package com.alibaba.jvm.sandbox.module.mgr; + +import ch.qos.logback.classic.LoggerContext; +import com.alibaba.jvm.sandbox.api.spi.ModuleJarUnLoadSpi; +import org.kohsuke.MetaInfServices; +import org.slf4j.LoggerFactory; + +@MetaInfServices(ModuleJarUnLoadSpi.class) +public class OnJarUnLoadCompleted implements ModuleJarUnLoadSpi { + + @Override + public void onJarUnLoadCompleted() { + closeLogback(); + } + + // 关闭Logback日志框架 + private void closeLogback() { + try { + ((LoggerContext) LoggerFactory.getILoggerFactory()).stop(); + } catch (Throwable cause) { + cause.printStackTrace(); + } + } + +} diff --git a/sandbox-mgr-module/src/main/resources/META-INF/services/com.alibaba.jvm.sandbox.api.Module b/sandbox-mgr-module/src/main/resources/META-INF/services/com.alibaba.jvm.sandbox.api.Module deleted file mode 100755 index b90a60e6..00000000 --- a/sandbox-mgr-module/src/main/resources/META-INF/services/com.alibaba.jvm.sandbox.api.Module +++ /dev/null @@ -1,3 +0,0 @@ -com.alibaba.jvm.sandbox.module.mgr.ModuleMgrModule -com.alibaba.jvm.sandbox.module.mgr.InfoModule -com.alibaba.jvm.sandbox.module.mgr.ControlModule \ No newline at end of file diff --git a/sandbox-mgr-module/target/classes/META-INF/services/com.alibaba.jvm.sandbox.api.Module b/sandbox-mgr-module/target/classes/META-INF/services/com.alibaba.jvm.sandbox.api.Module deleted file mode 100755 index b90a60e6..00000000 --- a/sandbox-mgr-module/target/classes/META-INF/services/com.alibaba.jvm.sandbox.api.Module +++ /dev/null @@ -1,3 +0,0 @@ -com.alibaba.jvm.sandbox.module.mgr.ModuleMgrModule -com.alibaba.jvm.sandbox.module.mgr.InfoModule -com.alibaba.jvm.sandbox.module.mgr.ControlModule \ No newline at end of file diff --git a/sandbox-mgr-module/target/classes/com/alibaba/jvm/sandbox/module/mgr/ControlModule$1.class b/sandbox-mgr-module/target/classes/com/alibaba/jvm/sandbox/module/mgr/ControlModule$1.class deleted file mode 100644 index edd62582..00000000 Binary files a/sandbox-mgr-module/target/classes/com/alibaba/jvm/sandbox/module/mgr/ControlModule$1.class and /dev/null differ diff --git a/sandbox-mgr-module/target/classes/com/alibaba/jvm/sandbox/module/mgr/ControlModule.class b/sandbox-mgr-module/target/classes/com/alibaba/jvm/sandbox/module/mgr/ControlModule.class deleted file mode 100644 index f82dea63..00000000 Binary files a/sandbox-mgr-module/target/classes/com/alibaba/jvm/sandbox/module/mgr/ControlModule.class and /dev/null differ diff --git a/sandbox-mgr-module/target/classes/com/alibaba/jvm/sandbox/module/mgr/InfoModule.class b/sandbox-mgr-module/target/classes/com/alibaba/jvm/sandbox/module/mgr/InfoModule.class deleted file mode 100644 index bfbc7b49..00000000 Binary files a/sandbox-mgr-module/target/classes/com/alibaba/jvm/sandbox/module/mgr/InfoModule.class and /dev/null differ diff --git a/sandbox-mgr-module/target/classes/com/alibaba/jvm/sandbox/module/mgr/ModuleMgrModule.class b/sandbox-mgr-module/target/classes/com/alibaba/jvm/sandbox/module/mgr/ModuleMgrModule.class deleted file mode 100644 index 40240d56..00000000 Binary files a/sandbox-mgr-module/target/classes/com/alibaba/jvm/sandbox/module/mgr/ModuleMgrModule.class and /dev/null differ diff --git a/sandbox-mgr-module/target/classes/logback.xml b/sandbox-mgr-module/target/classes/logback.xml deleted file mode 100755 index e5836cd2..00000000 --- a/sandbox-mgr-module/target/classes/logback.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - ${user.home}/logs/sandbox/sandbox-mgr.log - - ${user.home}/logs/sandbox/sandbox-mgr.log.%d{yyyy-MM-dd} - 30 - - - %d{yyyy-MM-dd HH:mm:ss} %-5level %msg%n - UTF-8 - - - - - \ No newline at end of file diff --git a/sandbox-mgr-provider/pom.xml b/sandbox-mgr-provider/pom.xml index a69e579b..19497bef 100644 --- a/sandbox-mgr-provider/pom.xml +++ b/sandbox-mgr-provider/pom.xml @@ -6,7 +6,7 @@ sandbox com.alibaba.jvm.sandbox - 1.1.2-SNAPSHOT + 1.2.0-SNAPSHOT sandbox-mgr-provider sandbox-mgr-provider ${sandbox.version} diff --git a/sandbox-mgr-provider/target/classes/META-INF/services/com.alibaba.jvm.sandbox.provider.api.ModuleJarLoadingChain b/sandbox-mgr-provider/target/classes/META-INF/services/com.alibaba.jvm.sandbox.provider.api.ModuleJarLoadingChain deleted file mode 100644 index 8a1bd53c..00000000 --- a/sandbox-mgr-provider/target/classes/META-INF/services/com.alibaba.jvm.sandbox.provider.api.ModuleJarLoadingChain +++ /dev/null @@ -1 +0,0 @@ -com.alibaba.jvm.sandbox.provider.mgr.EmptyModuleJarLoadingChain \ No newline at end of file diff --git a/sandbox-mgr-provider/target/classes/META-INF/services/com.alibaba.jvm.sandbox.provider.api.ModuleLoadingChain b/sandbox-mgr-provider/target/classes/META-INF/services/com.alibaba.jvm.sandbox.provider.api.ModuleLoadingChain deleted file mode 100644 index 7457548b..00000000 --- a/sandbox-mgr-provider/target/classes/META-INF/services/com.alibaba.jvm.sandbox.provider.api.ModuleLoadingChain +++ /dev/null @@ -1 +0,0 @@ -com.alibaba.jvm.sandbox.provider.mgr.EmptyModuleLoadingChain \ No newline at end of file diff --git a/sandbox-mgr-provider/target/classes/com/alibaba/jvm/sandbox/provider/mgr/EmptyModuleJarLoadingChain.class b/sandbox-mgr-provider/target/classes/com/alibaba/jvm/sandbox/provider/mgr/EmptyModuleJarLoadingChain.class deleted file mode 100644 index ddc309fb..00000000 Binary files a/sandbox-mgr-provider/target/classes/com/alibaba/jvm/sandbox/provider/mgr/EmptyModuleJarLoadingChain.class and /dev/null differ diff --git a/sandbox-mgr-provider/target/classes/com/alibaba/jvm/sandbox/provider/mgr/EmptyModuleLoadingChain.class b/sandbox-mgr-provider/target/classes/com/alibaba/jvm/sandbox/provider/mgr/EmptyModuleLoadingChain.class deleted file mode 100644 index 506969b3..00000000 Binary files a/sandbox-mgr-provider/target/classes/com/alibaba/jvm/sandbox/provider/mgr/EmptyModuleLoadingChain.class and /dev/null differ diff --git a/sandbox-module-starter/pom.xml b/sandbox-module-starter/pom.xml index 9565a09c..46ec8977 100644 --- a/sandbox-module-starter/pom.xml +++ b/sandbox-module-starter/pom.xml @@ -6,7 +6,7 @@ com.alibaba.jvm.sandbox sandbox - 1.1.2-SNAPSHOT + 1.2.0-SNAPSHOT sandbox-module-starter sandbox-module-starter ${sandbox.version} diff --git a/sandbox-provider-api/pom.xml b/sandbox-provider-api/pom.xml index 12f0344f..4807571e 100644 --- a/sandbox-provider-api/pom.xml +++ b/sandbox-provider-api/pom.xml @@ -6,7 +6,7 @@ sandbox com.alibaba.jvm.sandbox - 1.1.2-SNAPSHOT + 1.2.0-SNAPSHOT sandbox-provider-api sandbox-provider-api ${sandbox.version} diff --git a/sandbox-provider-api/target/classes/com/alibaba/jvm/sandbox/provider/api/ModuleJarLoadingChain.class b/sandbox-provider-api/target/classes/com/alibaba/jvm/sandbox/provider/api/ModuleJarLoadingChain.class deleted file mode 100644 index e3805afb..00000000 Binary files a/sandbox-provider-api/target/classes/com/alibaba/jvm/sandbox/provider/api/ModuleJarLoadingChain.class and /dev/null differ diff --git a/sandbox-provider-api/target/classes/com/alibaba/jvm/sandbox/provider/api/ModuleLoadingChain.class b/sandbox-provider-api/target/classes/com/alibaba/jvm/sandbox/provider/api/ModuleLoadingChain.class deleted file mode 100644 index 6d578adb..00000000 Binary files a/sandbox-provider-api/target/classes/com/alibaba/jvm/sandbox/provider/api/ModuleLoadingChain.class and /dev/null differ diff --git a/sandbox-spy/pom.xml b/sandbox-spy/pom.xml index df4cfc43..39a495ef 100755 --- a/sandbox-spy/pom.xml +++ b/sandbox-spy/pom.xml @@ -6,7 +6,7 @@ com.alibaba.jvm.sandbox sandbox - 1.1.2-SNAPSHOT + 1.2.0-SNAPSHOT sandbox-spy sandbox-spy ${sandbox.version} diff --git a/sandbox-spy/src/main/java/java/com/alibaba/jvm/sandbox/spy/Spy.java b/sandbox-spy/src/main/java/java/com/alibaba/jvm/sandbox/spy/Spy.java index 5b6de7fe..55b20d77 100755 --- a/sandbox-spy/src/main/java/java/com/alibaba/jvm/sandbox/spy/Spy.java +++ b/sandbox-spy/src/main/java/java/com/alibaba/jvm/sandbox/spy/Spy.java @@ -19,6 +19,13 @@ */ public class Spy { + /** + * 控制Spy是否在发生异常时主动对外抛出 + * T:主动对外抛出,会中断方法 + * F:不对外抛出,只将异常信息打印出来 + */ + public static volatile boolean isSpyThrowException = false; + private static final Class SPY_RET_CLASS = Spy.Ret.class; private static final Map namespaceMethodHookMap @@ -85,6 +92,30 @@ public static void clean(final String namespace) { } + + // 全局序列 + private static volatile int sequence = 1000; + + /** + * 生成全局唯一序列, + * 在JVM-SANDBOX中允许多个命名空间的存在,不同的命名空间下listenerId/objectId将会被植入到同一份字节码中, + * 此时需要用全局的ID生成策略规避不同的命名空间 + * + * @return 全局自增序列 + */ + public static synchronized int nextSequence() { + return sequence++; + } + + + private static void handleException(Throwable cause) throws Throwable { + if (isSpyThrowException) { + throw cause; + } else { + cause.printStackTrace(); + } + } + private static final SelfCallBarrier selfCallBarrier = new SelfCallBarrier(); public static void spyMethodOnCallBefore(final int lineNumber, @@ -93,24 +124,52 @@ public static void spyMethodOnCallBefore(final int lineNumber, final String desc, final String namespace, final int listenerId) throws Throwable { - namespaceMethodHookMap.get(namespace).ON_CALL_BEFORE_METHOD.invoke(null, listenerId, lineNumber, owner, name, desc); + try { + final MethodHook hook = namespaceMethodHookMap.get(namespace); + if (null != hook) { + hook.ON_CALL_BEFORE_METHOD.invoke(null, listenerId, lineNumber, owner, name, desc); + } + } catch (Throwable cause) { + handleException(cause); + } } public static void spyMethodOnCallReturn(final String namespace, final int listenerId) throws Throwable { - namespaceMethodHookMap.get(namespace).ON_CALL_RETURN_METHOD.invoke(null, listenerId); + try { + final MethodHook hook = namespaceMethodHookMap.get(namespace); + if (null != hook) { + hook.ON_CALL_RETURN_METHOD.invoke(null, listenerId); + } + } catch (Throwable cause) { + handleException(cause); + } } public static void spyMethodOnCallThrows(final String throwException, final String namespace, final int listenerId) throws Throwable { - namespaceMethodHookMap.get(namespace).ON_CALL_THROWS_METHOD.invoke(null, listenerId, throwException); + try { + final MethodHook hook = namespaceMethodHookMap.get(namespace); + if (null != hook) { + hook.ON_CALL_THROWS_METHOD.invoke(null, listenerId, throwException); + } + } catch (Throwable cause) { + handleException(cause); + } } public static void spyMethodOnLine(final int lineNumber, final String namespace, final int listenerId) throws Throwable { - namespaceMethodHookMap.get(namespace).ON_LINE_METHOD.invoke(null, listenerId, lineNumber); + try { + final MethodHook hook = namespaceMethodHookMap.get(namespace); + if (null != hook) { + hook.ON_LINE_METHOD.invoke(null, listenerId, lineNumber); + } + } catch (Throwable cause) { + handleException(cause); + } } public static Ret spyMethodOnBefore(final Object[] argumentArray, @@ -127,8 +186,15 @@ public static Ret spyMethodOnBefore(final Object[] argumentArray, } final SelfCallBarrier.Node node = selfCallBarrier.enter(thread); try { - return (Ret) namespaceMethodHookMap.get(namespace).ON_BEFORE_METHOD.invoke(null, + final MethodHook hook = namespaceMethodHookMap.get(namespace); + if (null == hook) { + return Ret.RET_NONE; + } + return (Ret) hook.ON_BEFORE_METHOD.invoke(null, listenerId, targetClassLoaderObjectID, SPY_RET_CLASS, javaClassName, javaMethodName, javaMethodDesc, target, argumentArray); + } catch (Throwable cause) { + handleException(cause); + return Ret.RET_NONE; } finally { selfCallBarrier.exit(thread, node); } @@ -143,7 +209,14 @@ public static Ret spyMethodOnReturn(final Object object, } final SelfCallBarrier.Node node = selfCallBarrier.enter(thread); try { - return (Ret) namespaceMethodHookMap.get(namespace).ON_RETURN_METHOD.invoke(null, listenerId, SPY_RET_CLASS, object); + final MethodHook hook = namespaceMethodHookMap.get(namespace); + if (null == hook) { + return Ret.RET_NONE; + } + return (Ret) hook.ON_RETURN_METHOD.invoke(null, listenerId, SPY_RET_CLASS, object); + } catch (Throwable cause) { + handleException(cause); + return Ret.RET_NONE; } finally { selfCallBarrier.exit(thread, node); } @@ -158,7 +231,14 @@ public static Ret spyMethodOnThrows(final Throwable throwable, } final SelfCallBarrier.Node node = selfCallBarrier.enter(thread); try { - return (Ret) namespaceMethodHookMap.get(namespace).ON_THROWS_METHOD.invoke(null, listenerId, SPY_RET_CLASS, throwable); + final MethodHook hook = namespaceMethodHookMap.get(namespace); + if (null == hook) { + return Ret.RET_NONE; + } + return (Ret) hook.ON_THROWS_METHOD.invoke(null, listenerId, SPY_RET_CLASS, throwable); + } catch (Throwable cause) { + handleException(cause); + return Ret.RET_NONE; } finally { selfCallBarrier.exit(thread, node); } @@ -258,8 +338,14 @@ void insert(final Node top, final Node node) { } } + int abs(int val) { + return val < 0 + ? val * -1 + : val; + } + boolean isEnter(Thread thread) { - final Node top = nodeArray[thread.hashCode() % THREAD_LOCAL_ARRAY_LENGTH]; + final Node top = nodeArray[abs(thread.hashCode()) % THREAD_LOCAL_ARRAY_LENGTH]; Node node = top; synchronized (top) { while (null != node.next) { @@ -273,7 +359,7 @@ boolean isEnter(Thread thread) { } Node enter(Thread thread) { - final Node top = nodeArray[thread.hashCode() % THREAD_LOCAL_ARRAY_LENGTH]; + final Node top = nodeArray[abs(thread.hashCode()) % THREAD_LOCAL_ARRAY_LENGTH]; final Node node = new Node(thread); synchronized (top) { insert(top, node); @@ -282,7 +368,7 @@ Node enter(Thread thread) { } void exit(Thread thread, Node node) { - final Node top = nodeArray[thread.hashCode() % THREAD_LOCAL_ARRAY_LENGTH]; + final Node top = nodeArray[abs(thread.hashCode()) % THREAD_LOCAL_ARRAY_LENGTH]; synchronized (top) { delete(node); } @@ -311,6 +397,13 @@ public MethodHook(final Method on_before_method, final Method on_call_before_method, final Method on_call_return_method, final Method on_call_throws_method) { + assert null != on_before_method; + assert null != on_return_method; + assert null != on_throws_method; + assert null != on_line_method; + assert null != on_call_before_method; + assert null != on_call_return_method; + assert null != on_call_throws_method; this.ON_BEFORE_METHOD = on_before_method; this.ON_RETURN_METHOD = on_return_method; this.ON_THROWS_METHOD = on_throws_method; diff --git a/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy$MethodHook.class b/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy$MethodHook.class deleted file mode 100644 index e23ee682..00000000 Binary files a/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy$MethodHook.class and /dev/null differ diff --git a/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy$Ret.class b/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy$Ret.class deleted file mode 100644 index 178317d5..00000000 Binary files a/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy$Ret.class and /dev/null differ diff --git a/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy$SelfCallBarrier$Node.class b/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy$SelfCallBarrier$Node.class deleted file mode 100644 index 60269c1a..00000000 Binary files a/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy$SelfCallBarrier$Node.class and /dev/null differ diff --git a/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy$SelfCallBarrier.class b/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy$SelfCallBarrier.class deleted file mode 100644 index 34170055..00000000 Binary files a/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy$SelfCallBarrier.class and /dev/null differ diff --git a/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy.class b/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy.class deleted file mode 100644 index 4303988a..00000000 Binary files a/sandbox-spy/target/classes/java/com/alibaba/jvm/sandbox/spy/Spy.class and /dev/null differ