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} 发出的命令
+ *
+ * 有这个注解的方法只能接收四类型的参数:
+ *
+ * - 命令参数: {@code Map}
+ * - 命令参数: {@code Map}
+ * - 命令参数: {@code String}
+ * - 文本输出: {@code PrintWriter}
+ *
+ *
+ * @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 extends EventListener> 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 extends EventListener> 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 extends Event> 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 @@
-
+
-