Skip to content

Commit 8b07856

Browse files
committed
修复问题 #133
1 parent 03ebfc6 commit 8b07856

File tree

7 files changed

+149
-55
lines changed

7 files changed

+149
-55
lines changed

sandbox-api/src/test/java/com/alibaba/jvm/sandbox/qatest/api/EventWatchBuilderTestCase.java

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import com.alibaba.jvm.sandbox.api.listener.ext.AdviceListener;
77
import com.alibaba.jvm.sandbox.api.listener.ext.EventWatchBuilder;
88
import com.alibaba.jvm.sandbox.qatest.api.mock.MockForBuilderModuleEventWatcher;
9-
import com.alibaba.jvm.sandbox.qatest.api.mock.MockForBuilderProgress;
109
import com.alibaba.jvm.sandbox.qatest.api.util.ApiQaArrayUtils;
1110
import org.junit.Assert;
1211
import org.junit.Test;

sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/EventEnhancer.java

+38-50
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,27 @@
22

33
import com.alibaba.jvm.sandbox.api.event.Event;
44
import com.alibaba.jvm.sandbox.core.enhance.weaver.asm.EventWeaver;
5+
import com.alibaba.jvm.sandbox.core.util.AsmUtils;
56
import com.alibaba.jvm.sandbox.core.util.ObjectIDs;
67
import org.objectweb.asm.ClassReader;
78
import org.objectweb.asm.ClassWriter;
89
import org.slf4j.Logger;
910
import org.slf4j.LoggerFactory;
1011

12+
import java.io.File;
13+
import java.io.IOException;
1114
import java.util.Set;
1215

13-
import static com.alibaba.jvm.sandbox.core.util.SandboxStringUtils.toInternalClassName;
14-
import static com.alibaba.jvm.sandbox.core.util.SandboxStringUtils.toJavaClassName;
16+
import static org.apache.commons.io.FileUtils.writeByteArrayToFile;
1517
import static org.objectweb.asm.ClassReader.EXPAND_FRAMES;
1618
import static org.objectweb.asm.ClassWriter.COMPUTE_FRAMES;
1719
import static org.objectweb.asm.ClassWriter.COMPUTE_MAXS;
1820
import static org.objectweb.asm.Opcodes.ASM7;
1921

2022
/**
2123
* 事件代码增强器
22-
* Created by [email protected] on 16/7/12.
24+
*
25+
2326
*/
2427
public class EventEnhancer implements Enhancer {
2528

@@ -46,57 +49,42 @@ private ClassWriter createClassWriter(final ClassLoader targetClassLoader,
4649
*/
4750
@Override
4851
protected String getCommonSuperClass(String type1, String type2) {
49-
Class<?> c, d;
50-
try {
51-
c = Class.forName(toJavaClassName(type1), false, targetClassLoader);
52-
d = Class.forName(toJavaClassName(type2), false, targetClassLoader);
53-
} catch (Exception e) {
54-
throw new RuntimeException(e);
55-
}
56-
if (c.isAssignableFrom(d)) {
57-
return type1;
58-
}
59-
if (d.isAssignableFrom(c)) {
60-
return type2;
61-
}
62-
if (c.isInterface() || d.isInterface()) {
63-
return "java/lang/Object";
64-
} else {
65-
do {
66-
c = c.getSuperclass();
67-
} while (!c.isAssignableFrom(d));
68-
return toInternalClassName(c.getName());
69-
}
52+
return AsmUtils.getCommonSuperClass(type1, type2, targetClassLoader);
7053
}
7154

7255
};
7356
}
7457

75-
// /*
76-
// * dump class to file
77-
// * 用于代码调试
78-
// */
79-
// private static byte[] dumpClassIfNecessary(String className, byte[] data) {
80-
// final File dumpClassFile = new File("./sandbox-class-dump/" + className + ".class");
81-
// final File classPath = new File(dumpClassFile.getParent());
82-
//
83-
// // 创建类所在的包路径
84-
// if (!classPath.mkdirs()
85-
// && !classPath.exists()) {
86-
// logger.warn("create dump classpath={} failed.", classPath);
87-
// return data;
88-
// }
89-
//
90-
// // 将类字节码写入文件
91-
// try {
92-
// writeByteArrayToFile(dumpClassFile, data);
93-
// logger.info("dump {} to {} success.", className, dumpClassFile);
94-
// } catch (IOException e) {
95-
// logger.warn("dump {} to {} failed.", className, dumpClassFile, e);
96-
// }
97-
//
98-
// return data;
99-
// }
58+
private static final boolean isDumpClass = false;
59+
60+
/*
61+
* dump class to file
62+
* 用于代码调试
63+
*/
64+
private static byte[] dumpClassIfNecessary(String className, byte[] data) {
65+
if (!isDumpClass) {
66+
return data;
67+
}
68+
final File dumpClassFile = new File("./sandbox-class-dump/" + className + ".class");
69+
final File classPath = new File(dumpClassFile.getParent());
70+
71+
// 创建类所在的包路径
72+
if (!classPath.mkdirs()
73+
&& !classPath.exists()) {
74+
logger.warn("create dump classpath={} failed.", classPath);
75+
return data;
76+
}
77+
78+
// 将类字节码写入文件
79+
try {
80+
writeByteArrayToFile(dumpClassFile, data);
81+
logger.info("dump {} to {} success.", className, dumpClassFile);
82+
} catch (IOException e) {
83+
logger.warn("dump {} to {} failed.", className, dumpClassFile, e);
84+
}
85+
86+
return data;
87+
}
10088

10189
@Override
10290
public byte[] toByteCodeArray(final ClassLoader targetClassLoader,
@@ -119,7 +107,7 @@ public byte[] toByteCodeArray(final ClassLoader targetClassLoader,
119107
),
120108
EXPAND_FRAMES
121109
);
122-
return cw.toByteArray();
110+
return dumpClassIfNecessary(cr.getClassName(), cw.toByteArray());
123111
}
124112

125113
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.alibaba.jvm.sandbox.core.util;
2+
3+
import com.alibaba.jvm.sandbox.core.util.matcher.structure.ClassStructure;
4+
import com.alibaba.jvm.sandbox.core.util.matcher.structure.ClassStructureFactory;
5+
import org.apache.commons.io.IOUtils;
6+
7+
import java.io.InputStream;
8+
9+
import static com.alibaba.jvm.sandbox.core.util.SandboxStringUtils.toInternalClassName;
10+
11+
/**
12+
* ASM工具集
13+
*
14+
15+
*/
16+
public class AsmUtils {
17+
18+
/**
19+
* {@see org.objectweb.asm.ClassWriter#getCommonSuperClass(String, String)}
20+
*/
21+
public static String getCommonSuperClass(String type1, String type2, ClassLoader loader) {
22+
return getCommonSuperClassImplByAsm(type1, type2, loader);
23+
}
24+
25+
// implements by ASM
26+
private static String getCommonSuperClassImplByAsm(String type1, String type2, ClassLoader targetClassLoader) {
27+
InputStream inputStreamOfType1 = null, inputStreamOfType2 = null;
28+
try {
29+
inputStreamOfType1 = targetClassLoader.getResourceAsStream(type1 + ".class");
30+
if (null == inputStreamOfType1) {
31+
return "java/lang/Object";
32+
}
33+
inputStreamOfType2 = targetClassLoader.getResourceAsStream(type2 + ".class");
34+
if (null == inputStreamOfType2) {
35+
return "java/lang/Object";
36+
}
37+
final ClassStructure classStructureOfType1 = ClassStructureFactory.createClassStructure(inputStreamOfType1, targetClassLoader);
38+
final ClassStructure classStructureOfType2 = ClassStructureFactory.createClassStructure(inputStreamOfType2, targetClassLoader);
39+
if (classStructureOfType2.getFamilyTypeClassStructures().contains(classStructureOfType1)) {
40+
return type1;
41+
}
42+
if (classStructureOfType1.getFamilyTypeClassStructures().contains(classStructureOfType2)) {
43+
return type2;
44+
}
45+
if (classStructureOfType1.getAccess().isInterface()
46+
|| classStructureOfType2.getAccess().isInterface()) {
47+
return "java/lang/Object";
48+
}
49+
ClassStructure classStructure = classStructureOfType1;
50+
do {
51+
classStructure = classStructure.getSuperClassStructure();
52+
if (null == classStructure) {
53+
return "java/lang/Object";
54+
}
55+
} while (!classStructureOfType2.getFamilyTypeClassStructures().contains(classStructure));
56+
return toInternalClassName(classStructure.getJavaClassName());
57+
} finally {
58+
IOUtils.closeQuietly(inputStreamOfType1);
59+
IOUtils.closeQuietly(inputStreamOfType2);
60+
}
61+
}
62+
63+
}

sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/enhance/target/MyCalculator.java

+9
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,13 @@ public MyCalculator(String tCaseName) {
77
.toUpperCase());
88
}
99

10+
public MyCalculator() {
11+
super();
12+
}
13+
14+
@Override
15+
public int sum(int... numArray) {
16+
return super.sum(numArray);
17+
}
18+
1019
}

sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/issues/Issues130.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import static com.alibaba.jvm.sandbox.api.event.Event.Type.CALL_BEFORE;
1010
import static com.alibaba.jvm.sandbox.api.event.Event.Type.LINE;
1111
import static com.alibaba.jvm.sandbox.qatest.core.util.CalculatorHelper.*;
12-
import static com.alibaba.jvm.sandbox.qatest.core.util.CalculatorHelper.newInstance;
1312
import static org.junit.Assert.assertEquals;
1413

1514
/**
@@ -35,8 +34,9 @@ public void onEvent(Event event) throws Throwable {
3534
)
3635
.loadClass(CALCULATOR_CLASS_NAME);
3736

37+
final Object objectOfCal = newInstance(calculatorClass);
3838
for (int i = 0; i < 1000000; i++) {
39-
assertEquals(30, sum(newInstance(calculatorClass), 10, 20));
39+
assertEquals(30, sum(objectOfCal, 10, 20));
4040
}
4141
}
4242

@@ -58,8 +58,9 @@ public void onEvent(Event event) throws Throwable {
5858
)
5959
.loadClass(CALCULATOR_CLASS_NAME);
6060

61+
final Object objectOfCal = newInstance(calculatorClass);
6162
for (int i = 0; i < 1000000; i++) {
62-
assertEquals(30, sum(newInstance(calculatorClass), 10, 20));
63+
assertEquals(30, sum(objectOfCal, 10, 20));
6364
}
6465
}
6566

@@ -81,8 +82,9 @@ public void onEvent(Event event) throws Throwable {
8182
)
8283
.loadClass(CALCULATOR_CLASS_NAME);
8384

85+
final Object objectOfCal = newInstance(calculatorClass);
8486
for (int i = 0; i < 1000000; i++) {
85-
assertEquals(30, sum(newInstance(calculatorClass), 10, 20));
87+
assertEquals(30, sum(objectOfCal, 10, 20));
8688
}
8789
}
8890

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.alibaba.jvm.sandbox.qatest.core.issues;
2+
3+
import org.junit.Assert;
4+
import org.junit.Test;
5+
6+
import java.io.InputStream;
7+
8+
import static com.alibaba.jvm.sandbox.core.util.AsmUtils.getCommonSuperClass;
9+
10+
public class Issues133 {
11+
12+
@Test
13+
public void test() {
14+
final ClassLoader loader = getClass().getClassLoader();
15+
Assert.assertEquals("java/io/InputStream", getCommonSuperClass("java/io/FileInputStream", "javax/servlet/ServletInputStream", loader));
16+
Assert.assertEquals("java/lang/Exception", getCommonSuperClass("java/io/IOException", "javax/servlet/ServletException", loader));
17+
Assert.assertEquals("javax/servlet/ServletResponse", getCommonSuperClass("javax/servlet/ServletResponse", "javax/servlet/http/HttpServletResponse", loader));
18+
Assert.assertEquals("javax/servlet/ServletResponse", getCommonSuperClass("javax/servlet/http/HttpServletResponse", "javax/servlet/ServletResponse", loader));
19+
Assert.assertEquals("java/lang/Object", getCommonSuperClass("java/lang/Throwable", "java/io/FileInputStream", loader));
20+
}
21+
22+
}

sandbox-core/src/test/java/com/alibaba/jvm/sandbox/qatest/core/util/CalculatorHelper.java

+11
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.alibaba.jvm.sandbox.api.filter.NameRegexFilter;
99
import com.alibaba.jvm.sandbox.core.util.UnCaughtException;
1010
import com.alibaba.jvm.sandbox.qatest.core.enhance.target.Calculator;
11+
import com.alibaba.jvm.sandbox.qatest.core.enhance.target.MyCalculator;
1112

1213
import java.lang.reflect.InvocationTargetException;
1314
import java.util.Stack;
@@ -22,6 +23,7 @@
2223
public class CalculatorHelper {
2324

2425
public static final String CALCULATOR_CLASS_NAME = getJavaClassName(Calculator.class);
26+
public static final String MY_CALCULATOR_CLASS_NAME = getJavaClassName(MyCalculator.class);
2527

2628
/**
2729
* 拦截sum()方法过滤器
@@ -68,6 +70,15 @@ public class CalculatorHelper {
6870
"<init>"
6971
);
7072

73+
/**
74+
* 拦截sum()方法过滤器
75+
*/
76+
public static final Filter MY_CALCULATOR_SUM_FILTER
77+
= new NameRegexFilter(
78+
"^com\\.alibaba\\.jvm.sandbox\\.qatest\\.core\\.enhance\\.target\\.MyCalculator$",
79+
"^sum$"
80+
);
81+
7182
public static final Filter CALCULATOR_INIT_FILTER_WITH_TEST_CASE
7283
= new Filter() {
7384
@Override

0 commit comments

Comments
 (0)