You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

JvstTest.java 42KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136
  1. package javassist;
  2. import junit.framework.*;
  3. import java.io.FileInputStream;
  4. import java.lang.reflect.Method;
  5. import javassist.bytecode.*;
  6. import javassist.expr.*;
  7. import javassist.runtime.*;
  8. public class JvstTest extends JvstTestRoot {
  9. static {
  10. //javassist.bytecode.MethodInfo.doPreverify = true;
  11. }
  12. public JvstTest(String name) {
  13. super(name);
  14. }
  15. public void testConfig() {
  16. // is the value of PATH correct?
  17. assertTrue("not found " + PATH, new java.io.File(PATH).exists());
  18. }
  19. public void testLoader() throws Exception {
  20. Loader loader = new Loader(sloader);
  21. loader.delegateLoadingOf("test1.");
  22. assertEquals(loader.loadClass("test1.Cflow").getClassLoader(),
  23. loader.getParent());
  24. assertEquals(loader.loadClass("javassist.Loader").getClassLoader(),
  25. loader.getParent());
  26. assertEquals(loader.loadClass("javassist.CtClass").getClassLoader(),
  27. loader);
  28. }
  29. public void testDefreeze() throws Exception {
  30. CtClass cc = sloader.get("test1.Freeze");
  31. cc.stopPruning(true);
  32. cc.addInterface(sloader.get("java.io.Serializable"));
  33. assertTrue(!cc.isFrozen());
  34. cc.writeFile();
  35. assertTrue(cc.isFrozen());
  36. cc.defrost();
  37. assertTrue(!cc.isFrozen());
  38. }
  39. public void testClassPath() throws Exception {
  40. ClassPool pool = new ClassPool(null);
  41. ClassPath cp1 = pool.appendClassPath("d1");
  42. ClassPath cp2 = pool.appendClassPath("d2");
  43. ClassPath cp3 = pool.appendClassPath("d3");
  44. ClassPath cp4 = pool.appendClassPath("d4");
  45. print(pool.toString());
  46. pool.removeClassPath(cp3);
  47. print(pool.toString());
  48. pool.removeClassPath(cp4);
  49. print(pool.toString());
  50. pool.removeClassPath(cp2);
  51. print(pool.toString());
  52. pool.removeClassPath(cp1);
  53. assertTrue("[class path: ]".equals(pool.toString()));
  54. }
  55. public void testSubtype() throws Exception {
  56. CtClass cc = sloader.get("test1.Subtype");
  57. assertTrue(cc.subtypeOf(cc));
  58. assertTrue(cc.subtypeOf(sloader.get("test1.SubtypeA")));
  59. assertTrue(cc.subtypeOf(sloader.get("test1.SubtypeB")));
  60. assertTrue(cc.subtypeOf(sloader.get("test1.SubtypeC")));
  61. assertTrue(cc.subtypeOf(sloader.get("java.lang.Object")));
  62. assertTrue(!cc.subtypeOf(sloader.get("java.lang.String")));
  63. }
  64. public void testClassPoolGet() throws Exception {
  65. ClassPool pool = ClassPool.getDefault();
  66. CtClass cc = pool.makeClass("test1.Point");
  67. CtClass cc1 = pool.get("test1.Point"); // cc1 is identical to cc.
  68. cc.setName("test1.Pair");
  69. CtClass cc2 = pool.get("test1.Pair"); // cc2 is identical to cc.
  70. CtClass cc3 = pool.get("test1.Point"); // cc3 is not identical to cc.
  71. assertTrue(cc == cc1);
  72. assertTrue(cc == cc2);
  73. assertTrue(cc != cc3);
  74. assertEquals("test1.Pair", cc.getName());
  75. assertEquals("test1.Point", cc3.getName());
  76. }
  77. public static long testFieldInitHash;
  78. /* test CodeIterator.insertExGap().
  79. * The result of this test is checked again by JvstTest3#testFieldInitAgain().
  80. */
  81. public void testFieldInit() throws Exception {
  82. CtClass cc = sloader.get("test1.FieldInit");
  83. CtField f1 = new CtField(CtClass.intType, "f1", cc);
  84. cc.addField(f1, CtField.Initializer.byCall(cc, "get"));
  85. CtField f2 = CtField.make("public int f2 = 3;", cc);
  86. cc.addField(f2);
  87. CtField f3 = CtField.make("public int f3;", cc);
  88. cc.addField(f3);
  89. testFieldInitHash = f1.hashCode();
  90. cc.writeFile();
  91. Object obj = make(cc.getName());
  92. int value = obj.getClass().getField("counter").getInt(obj);
  93. assertEquals(1, value);
  94. int value2 = obj.getClass().getField("f2").getInt(obj);
  95. assertEquals(3, value2);
  96. int value3 = obj.getClass().getField("f3").getInt(obj);
  97. assertEquals(0, value3);
  98. }
  99. /* test CodeIterator.insertExGap().
  100. */
  101. public void testFieldInit2() throws Exception {
  102. CtClass cc = sloader.get("test1.FieldInit2");
  103. CtField f = new CtField(CtClass.intType, "f1", cc);
  104. cc.addField(f, CtField.Initializer.byCall(cc, "get"));
  105. cc.writeFile();
  106. try {
  107. Object obj = make(cc.getName());
  108. fail();
  109. }
  110. catch (Exception e) {
  111. print("testFieldInit2: catch");
  112. }
  113. }
  114. public static CtMethod testCalleeBeforeMethod;
  115. public static long testCalleeBeforeMethod2;
  116. /* The test result is checked again by JvstTest3#testCalleeBeforeAgain().
  117. */
  118. public void testCalleeBefore() throws Exception {
  119. CtClass cc = sloader.get("test1.CalleeBefore");
  120. CtMethod m1 = cc.getDeclaredMethod("m1");
  121. m1.insertBefore("{ int k = 1; p = k; }");
  122. CtMethod m2 = cc.getDeclaredMethod("m2");
  123. testCalleeBeforeMethod = m1;
  124. testCalleeBeforeMethod2 = m2.getMethodInfo2().hashCode();
  125. m2.insertBefore("{ int k = 3; q = k; }");
  126. CtConstructor[] cons = cc.getDeclaredConstructors();
  127. for (int i = 0; i < cons.length; ++i) {
  128. MethodInfo minfo = cons[i].getMethodInfo();
  129. CodeAttribute ca = minfo.getCodeAttribute();
  130. CodeIterator iterator = ca.iterator();
  131. if (cons[i].getParameterTypes().length == 0) {
  132. assertTrue(iterator.skipThisConstructor() >= 0);
  133. assertTrue(iterator.skipSuperConstructor() < 0);
  134. assertTrue(iterator.skipConstructor() >= 0);
  135. }
  136. else {
  137. assertTrue(iterator.skipThisConstructor() < 0);
  138. assertTrue(iterator.skipSuperConstructor() >= 0);
  139. assertTrue(iterator.skipConstructor() >= 0);
  140. }
  141. cons[i].insertBeforeBody("{ int k = 1; counter += k; }");
  142. }
  143. cc.writeFile();
  144. Object obj = make(cc.getName());
  145. assertEquals(0, invoke(obj, "getr"));
  146. assertEquals(17, invoke(obj, "test"));
  147. }
  148. public void testCalleeAfter() throws Exception {
  149. CtClass cc = sloader.get("test1.CalleeAfter");
  150. CtMethod m1 = cc.getDeclaredMethod("m1");
  151. m1.insertAfter("{ int k = 1; $_ = $_ + k; }", false);
  152. CtMethod m2 = cc.getDeclaredMethod("m2");
  153. m2.insertAfter("{ char k = 1; $_ = $_ + k; }", false);
  154. CtConstructor[] cons = cc.getDeclaredConstructors();
  155. cons[0].insertAfter("{ ++p; $_ = ($r)null; }", false);
  156. cc.writeFile();
  157. Object obj = make(cc.getName());
  158. assertEquals(15, invoke(obj, "test"));
  159. }
  160. public void testCalleeAfter2() throws Exception {
  161. CtClass cc = sloader.get("test1.CalleeAfter2");
  162. CtMethod m1 = cc.getDeclaredMethod("m1");
  163. m1.insertAfter("$_ = 7; $_ = ($r)k1(0);", false);
  164. CtMethod m2 = cc.getDeclaredMethod("m2");
  165. m2.insertAfter("$_ = ($r)k2(0);", false);
  166. CtMethod m3 = cc.getDeclaredMethod("m3");
  167. m3.insertAfter("$_ = ($r)k3(0);", false);
  168. CtMethod m4 = cc.getDeclaredMethod("m4");
  169. try {
  170. m4.insertAfter("$_ = ($r)1;", false);
  171. assertTrue(false);
  172. }
  173. catch (CannotCompileException e) {
  174. }
  175. CtMethod m5 = cc.getDeclaredMethod("m5");
  176. m5.insertAfter("$_ = ($r)k5(0);", false);
  177. cc.writeFile();
  178. Object obj = make(cc.getName());
  179. assertEquals(17, invoke(obj, "test"));
  180. }
  181. public void testCalleeAfter3() throws Exception {
  182. CtClass cc = sloader.get("test1.CalleeAfter3");
  183. CtMethod m1 = cc.getDeclaredMethod("m1");
  184. m1.insertAfter("value++;", true);
  185. CtMethod m2 = cc.getDeclaredMethod("m2");
  186. m2.insertAfter("value++;", true);
  187. CtMethod m3 = cc.getDeclaredMethod("m3");
  188. m3.insertAfter("value++;", true);
  189. CtMethod m4 = cc.getDeclaredMethod("m4");
  190. m4.insertAfter("value++;", true);
  191. cc.writeFile();
  192. Object obj = make(cc.getName());
  193. assertEquals(22, invoke(obj, "test"));
  194. }
  195. public void testCalleeCatch() throws Exception {
  196. CtClass cc = sloader.get("test1.CalleeCatch");
  197. CtMethod m1 = cc.getDeclaredMethod("m1");
  198. m1.addCatch("{ System.out.println($e); return p; }",
  199. sloader.get("java.lang.Exception"));
  200. cc.writeFile();
  201. Object obj = make(cc.getName());
  202. assertEquals(3, invoke(obj, "test"));
  203. }
  204. public void testSuperclass() throws Exception {
  205. CtClass cc = sloader.get("java.lang.Object");
  206. assertEquals(null, cc.getSuperclass());
  207. }
  208. public void testProceed() throws Exception {
  209. CtClass cc = sloader.get("test1.Proceed");
  210. CtMethod m1 = CtNewMethod.make(
  211. "public int m1() { return $proceed(3); }",
  212. cc, "this", "k1");
  213. CtMethod m2 = CtNewMethod.make(
  214. "public int m2() { return $proceed(3); }",
  215. cc, "another", "k2");
  216. CtMethod m3 = CtNewMethod.make(
  217. "public int q(int i) { return p($1 + 1, $$); }", cc);
  218. cc.addMethod(m1);
  219. cc.addMethod(m2);
  220. cc.addMethod(m3);
  221. CtMethod m4 = CtNewMethod.make(
  222. "public int q2() { return q(4); }", cc);
  223. cc.addMethod(m4);
  224. cc.writeFile();
  225. Object obj = make(cc.getName());
  226. assertEquals(3, invoke(obj, "m1"));
  227. assertEquals(4, invoke(obj, "m2"));
  228. assertEquals(9, invoke(obj, "q2"));
  229. }
  230. public void testProceed2() throws Exception {
  231. CtClass cc = sloader.get("test1.Proceed2");
  232. CtMethod m1 = cc.getDeclaredMethod("k1");
  233. m1.instrument(new ExprEditor() {
  234. public void edit(MethodCall m) throws CannotCompileException {
  235. m.replace("{ $_ = $proceed($$); }");
  236. }
  237. public void edit(NewExpr m) throws CannotCompileException {
  238. m.replace("{ $_ = $proceed($$); }");
  239. }
  240. public void edit(FieldAccess m) throws CannotCompileException {
  241. m.replace("{ $_ = $proceed($$); }");
  242. }
  243. public void edit(Instanceof i) throws CannotCompileException {
  244. i.replace("{ $_ = $proceed($$); }");
  245. }
  246. public void edit(Cast c) throws CannotCompileException {
  247. c.replace("{ $_ = $proceed($$); }");
  248. }
  249. });
  250. CtMethod m2 = cc.getDeclaredMethod("k2");
  251. m2.instrument(new ExprEditor() {
  252. public void edit(MethodCall m) throws CannotCompileException {
  253. m.replace("{ $proceed(); }");
  254. }
  255. public void edit(NewExpr m) throws CannotCompileException {
  256. m.replace("{ $_ = $proceed(); }");
  257. }
  258. public void edit(FieldAccess m) throws CannotCompileException {
  259. if (m.isReader())
  260. m.replace("{ $_ = $proceed(); }");
  261. else
  262. m.replace("{ $proceed($$); }");
  263. }
  264. });
  265. cc.writeFile();
  266. Object obj = make(cc.getName());
  267. assertEquals(2, invoke(obj, "k1"));
  268. }
  269. public void testProceed3() throws Exception {
  270. CtClass cc = sloader.get("test1.Proceed3");
  271. CtMethod m1 = cc.getDeclaredMethod("p");
  272. CtMethod m2 = CtNewMethod.copy(m1, cc, null);
  273. m1.setName(m1.getName() + "_orig");
  274. m2.setBody("{ return $proceed($1 + 1); }", "this", m1.getName());
  275. cc.addMethod(m2);
  276. cc.writeFile();
  277. Object obj = make(cc.getName());
  278. assertEquals(4, invoke(obj, "k1"));
  279. }
  280. public void testSetBody() throws Exception {
  281. CtClass cc = sloader.get("test1.SetBody");
  282. CtMethod m1 = cc.getDeclaredMethod("m1");
  283. m1.setBody("{ int i = $1 * $2; return i; }");
  284. CtMethod m2 = cc.getDeclaredMethod("m2");
  285. m2.setBody("System.out.println(\"setbody: \" + $1);");
  286. CtMethod m3 = cc.getDeclaredMethod("m3");
  287. try {
  288. m3.setBody("value = 1; System.out.println(\"setbody: \" + $1);");
  289. fail();
  290. }
  291. catch (CannotCompileException e) {
  292. // System.err.println(e);
  293. }
  294. CtConstructor cons
  295. = new CtConstructor(new CtClass[] { CtClass.intType }, cc);
  296. cons.setBody(null);
  297. cc.addConstructor(cons);
  298. cc.writeFile();
  299. Object obj = make(cc.getName());
  300. assertEquals(12, invoke(obj, "run"));
  301. }
  302. public void testSetStaticConsBody() throws Exception {
  303. CtClass cc = sloader.get("test1.StaticConsBody");
  304. CtConstructor cons = cc.getClassInitializer();
  305. cons.setBody(null);
  306. cons = cc.getConstructors()[0];
  307. cons.setBody(null);
  308. cc.writeFile();
  309. Object obj = make(cc.getName());
  310. assertEquals(0, invoke(obj, "run"));
  311. }
  312. public void testSetConsBody() throws Exception {
  313. CtClass superClazz = sloader.get("java.io.File");
  314. CtClass cc = sloader.makeClass("test1.SetConsBody");
  315. cc.setSuperclass(superClazz);
  316. CtConstructor constructor = new CtConstructor(new CtClass[0], cc);
  317. constructor.setBody("super(\"MyFile\");");
  318. cc.addConstructor(constructor);
  319. constructor = new CtConstructor(new CtClass[] { CtClass.intType },
  320. cc);
  321. constructor.setBody("{ super(\"MyFile\"); }");
  322. cc.addConstructor(constructor);
  323. cc.addMethod(CtNewMethod.make(CtClass.voidType, "m1",
  324. null, null, null, cc));
  325. cc.addMethod(CtNewMethod.make(CtClass.intType, "m2",
  326. null, null, null, cc));
  327. cc.addMethod(CtNewMethod.make(CtClass.byteType, "m3",
  328. null, null, null, cc));
  329. cc.addMethod(CtNewMethod.make(CtClass.longType, "m4",
  330. null, null, null, cc));
  331. cc.addMethod(CtNewMethod.make(CtClass.floatType, "m5",
  332. null, null, null, cc));
  333. cc.addMethod(CtNewMethod.make(CtClass.doubleType, "m6",
  334. null, null, null, cc));
  335. cc.addMethod(CtNewMethod.make(sloader.get("int[]"), "m7",
  336. null, null, null, cc));
  337. cc.addMethod(CtNewMethod.make(
  338. "public int run() {"
  339. + " return (int)(m2() + m3() + m4() + m5() + m6() + 3); }", cc));
  340. cc.writeFile();
  341. Object obj = make(cc.getName());
  342. assertEquals(3, invoke(obj, "run"));
  343. }
  344. public void testEmptyBody() throws Exception {
  345. String[] methods = { "m1", "m2", "m3", "m4" };
  346. boolean[] results = { true, false, false, false, true };
  347. boolean[] cResults = { true, true, false, false, false, true };
  348. CtClass cc = sloader.get("test1.EmptyBody");
  349. for (int i = 0; i < methods.length; ++i) {
  350. CtMethod m = cc.getDeclaredMethod(methods[i]);
  351. assertEquals(results[i], m.isEmpty());
  352. }
  353. CtConstructor[] cons = cc.getDeclaredConstructors();
  354. for (int j = 0; j < cons.length; ++j)
  355. assertEquals(cResults[j], cons[j].isEmpty());
  356. }
  357. public void testExprEditor() throws Exception {
  358. CtClass cc = sloader.get("test1.ExprEdit");
  359. CtMethod m1 = cc.getDeclaredMethod("k0");
  360. m1.instrument(new ExprEditor() {
  361. public void edit(MethodCall m) throws CannotCompileException {
  362. if (m.getClassName().equals("test1.ExprEdit")) {
  363. String name = m.getMethodName();
  364. if (name.equals("k1") || name.equals("k2")) {
  365. try {
  366. CtMethod cm = m.getMethod();
  367. print(cm.getParameterTypes()[0].getName());
  368. print(cm.getReturnType().getName());
  369. }
  370. catch (NotFoundException e) {
  371. throw new CannotCompileException(e);
  372. }
  373. m.replace("{ ++$1; $_ = $proceed($$); }");
  374. }
  375. else if (name.equals("k3"))
  376. m.replace("{ ++$1; $proceed($$); }");
  377. }
  378. }
  379. });
  380. cc.writeFile();
  381. Object obj = make(cc.getName());
  382. assertEquals(12, invoke(obj, "k0"));
  383. }
  384. public void testExprEditor2() throws Exception {
  385. CtClass cc = sloader.get("test1.ExprEdit2");
  386. CtMethod m1 = cc.getDeclaredMethod("k1");
  387. m1.instrument(new ExprEditor() {
  388. public void edit(FieldAccess m) throws CannotCompileException {
  389. if (m.getClassName().equals("test1.ExprEdit2")) {
  390. String name = m.getFieldName();
  391. try {
  392. CtField cf = m.getField();
  393. print(cf.getType().getName());
  394. print("file: " + m.getFileName());
  395. print("line: " + m.getLineNumber());
  396. }
  397. catch (NotFoundException e) {
  398. throw new CannotCompileException(e);
  399. }
  400. if (name.equals("df"))
  401. if (m.isReader())
  402. m.replace("{ $_ = $proceed() + 1; }");
  403. else
  404. m.replace("{ $proceed($1 + 1); }");
  405. else if (name.equals("sf"))
  406. if (m.isReader())
  407. m.replace("{ $_ = $proceed() + 2; }");
  408. else
  409. m.replace("{ $proceed($1 + 2); }");
  410. }
  411. }
  412. });
  413. cc.writeFile();
  414. Object obj = make(cc.getName());
  415. assertEquals(16, invoke(obj, "k1"));
  416. }
  417. public void testExprEditor3() throws Exception {
  418. CtClass cc = sloader.get("test1.ExprEdit3");
  419. CtMethod m1 = cc.getDeclaredMethod("k1");
  420. m1.instrument(new ExprEditor() {
  421. public void edit(NewExpr m) throws CannotCompileException {
  422. System.out.println("new " + m.getClassName());
  423. try {
  424. CtConstructor cc = m.getConstructor();
  425. print(cc.getParameterTypes()[0].getName());
  426. }
  427. catch (NotFoundException e) {
  428. throw new CannotCompileException(e);
  429. }
  430. if (m.getClassName().equals("test1.ExprEdit3")) {
  431. m.replace("{ ++$2; $_ = $proceed($$); }");
  432. }
  433. }
  434. });
  435. cc.writeFile();
  436. Object obj = make(cc.getName());
  437. assertEquals(4, invoke(obj, "k1"));
  438. }
  439. public void testExprEditor4() throws Exception {
  440. CtClass cc = sloader.get("test1.ExprEdit4");
  441. CtMethod m1 = cc.getDeclaredMethod("k1");
  442. m1.instrument(new ExprEditor() {
  443. public void edit(NewExpr m) throws CannotCompileException {
  444. System.out.println("new " + m.getClassName());
  445. if (m.getClassName().equals("test1.ExprEdit4"))
  446. m.replace("$_ = null;");
  447. }
  448. public void edit(MethodCall m) throws CannotCompileException {
  449. if (m.getClassName().equals("test1.ExprEdit4"))
  450. m.replace("{}");
  451. }
  452. });
  453. cc.writeFile();
  454. Object obj = make(cc.getName());
  455. assertEquals(1, invoke(obj, "k1"));
  456. }
  457. public void testExprEditor5() throws Exception {
  458. CtClass cc = sloader.get("test1.ExprEdit5");
  459. CtMethod m1 = cc.getDeclaredMethod("k1");
  460. m1.instrument(new ExprEditor() {
  461. public void edit(NewExpr m) throws CannotCompileException {
  462. m.replace("{ $_ = $proceed($$, \"test\"); }");
  463. }
  464. });
  465. cc.writeFile();
  466. Object obj = make(cc.getName());
  467. assertEquals(1, invoke(obj, "k1"));
  468. }
  469. public void testExprEditor6() throws Exception {
  470. CtClass cc = sloader.get("test1.ExprEdit6");
  471. cc.instrument(new ExprEditor() {
  472. public void edit(MethodCall m) throws CannotCompileException {
  473. assertTrue(m.where().getName().equals("k1"));
  474. m.replace("$_ = 3;");
  475. }
  476. });
  477. cc.writeFile();
  478. Object obj = make(cc.getName());
  479. assertEquals(3, invoke(obj, "k1"));
  480. }
  481. public void testExprEditor7() throws Exception {
  482. CtClass cc = sloader.get("test1.ExprEdit7");
  483. cc.instrument(new ExprEditor() {
  484. public void edit(Instanceof i) throws CannotCompileException {
  485. i.replace("{ this.c1 = $type; $_ = !$proceed($1); }");
  486. }
  487. public void edit(Cast c) throws CannotCompileException {
  488. c.replace("{ this.c2 = $type; $_ = ($r)$1; }");
  489. }
  490. });
  491. cc.writeFile();
  492. Object obj = make(cc.getName());
  493. assertEquals(7, invoke(obj, "k1"));
  494. }
  495. public void testExprEditor8() throws Exception {
  496. CtClass cc = sloader.get("test1.ExprEdit8");
  497. cc.instrument(new ExprEditor() {
  498. public void edit(ConstructorCall c) throws CannotCompileException {
  499. assertTrue(c.isSuper());
  500. c.replace("{ $_ = $proceed($$); value = 7; }");
  501. }
  502. });
  503. cc.writeFile();
  504. Object obj = make(cc.getName());
  505. assertEquals(7, invoke(obj, "k1"));
  506. }
  507. public void testCflow() throws Exception {
  508. CtClass cc = sloader.get("test1.Cflow");
  509. CtMethod m1 = cc.getDeclaredMethod("k1");
  510. m1.useCflow("cflow1");
  511. m1.insertBefore("System.out.println(\"$cflow1: \" + $cflow(cflow1));");
  512. m1.insertAfter("System.out.println(\"*$cflow1: \" + $cflow(cflow1));",
  513. true);
  514. CtMethod m2 = cc.getDeclaredMethod("k2");
  515. m2.useCflow("test1.t.cflow2");
  516. m2.insertBefore(
  517. "System.out.println(\"$cflow2: \" + $cflow(test1.t.cflow2));");
  518. CtMethod m3 = cc.getDeclaredMethod("fact");
  519. m3.useCflow("fact");
  520. m3.insertBefore("if ($cflow(fact) == 0)"
  521. + " System.out.println(\"fact \" + $1);");
  522. cc.writeFile();
  523. Object obj = make(cc.getName());
  524. assertEquals(1, invoke(obj, "run"));
  525. assertEquals(120, invoke(obj, "run2"));
  526. }
  527. public void testSigType() throws Exception {
  528. CtClass cc = sloader.get("test1.SigType");
  529. CtMethod m1 = cc.getDeclaredMethod("k1");
  530. m1.insertBefore("{ Class[] p = $sig; $1 += p.length; }");
  531. m1.insertAfter("System.out.println(\"testSigType: \""
  532. + " + $type.getName());", false);
  533. CtMethod m2 = cc.getDeclaredMethod("k2");
  534. m2.instrument(new ExprEditor() {
  535. public void edit(FieldAccess m) throws CannotCompileException {
  536. m.replace("{ $_ = $proceed($$) + $type.getName().length(); }");
  537. }
  538. public void edit(MethodCall m) throws CannotCompileException {
  539. m.replace("{ $_ = $proceed($$) + $sig.length; }");
  540. }
  541. });
  542. cc.writeFile();
  543. Object obj = make(cc.getName());
  544. assertEquals(19, invoke(obj, "run"));
  545. }
  546. public void testDollarClass() throws Exception {
  547. CtClass cc = sloader.get("test1.DollarClass");
  548. CtMethod m1 = cc.getDeclaredMethod("k1");
  549. m1.insertBefore("{ $1 += $class.getName().length(); }");
  550. CtMethod m2 = cc.getDeclaredMethod("k2");
  551. m2.instrument(new ExprEditor() {
  552. public void edit(MethodCall m) throws CannotCompileException {
  553. m.replace("{ $_ = $class.getName().length(); }");
  554. }
  555. });
  556. m2.insertBefore("{ $1 += $class.getName().length(); }");
  557. cc.writeFile();
  558. Object obj = make(cc.getName());
  559. assertEquals(58, invoke(obj, "run"));
  560. }
  561. public void testHandler() throws Exception {
  562. CtClass cc = sloader.get("test1.Handler");
  563. CtMethod m1 = cc.getDeclaredMethod("m1");
  564. m1.instrument(new ExprEditor() {
  565. public void edit(Handler h) throws CannotCompileException {
  566. try {
  567. print(h.getType().getName());
  568. h.insertBefore(
  569. "{ p = (($r)$1).getClass().getName().length()"
  570. + "+ $type.getName().length(); }");
  571. }
  572. catch (NotFoundException e) {
  573. throw new CannotCompileException(e);
  574. }
  575. }
  576. });
  577. cc.writeFile();
  578. Object obj = make(cc.getName());
  579. assertEquals(("java.lang.IndexOutOfBoundsException".length()
  580. + "java.lang.ClassNotFoundException".length())
  581. * 2 + 1,
  582. invoke(obj, "test"));
  583. }
  584. public void testInterface() throws Exception {
  585. String className = "test1.NewInterface";
  586. ClassPool pool = ClassPool.getDefault();
  587. CtClass targetCtClass = pool.get(className);
  588. CtClass ctInterface
  589. = pool.makeInterface(className + "2");
  590. CtMethod[] ctMethods = targetCtClass.getDeclaredMethods();
  591. for (int i = 0;i < ctMethods.length; i++) {
  592. String code = Modifier.toString(ctMethods[i].getModifiers())
  593. + " " + ctMethods[i].getReturnType().getName()
  594. + " " + ctMethods[i].getName() + "();";
  595. System.out.println(code);
  596. CtMethod m = CtNewMethod.make(code, ctInterface);
  597. ctInterface.addMethod(m);
  598. }
  599. targetCtClass.addInterface(ctInterface);
  600. targetCtClass.stopPruning(true);
  601. targetCtClass.writeFile();
  602. ctInterface.stopPruning(true);
  603. ctInterface.writeFile();
  604. ctInterface.toClass();
  605. targetCtClass.toClass();
  606. }
  607. public void testDispatch() throws Exception {
  608. CtClass cc = sloader.get("test1.Dispatch");
  609. CtMethod m1 = cc.getDeclaredMethod("run");
  610. m1.insertAfter("$_ += f(new Object[1]);");
  611. cc.writeFile();
  612. Object obj = make(cc.getName());
  613. assertEquals(7, invoke(obj, "run"));
  614. }
  615. public void testMakeClass()throws Exception {
  616. CtClass cc = sloader.makeClass(
  617. new FileInputStream(PATH + "test1/MakeClass.class"));
  618. assertEquals("test1.MakeClass", cc.getName());
  619. assertEquals(cc, sloader.get(cc.getName()));
  620. cc.toBytecode();
  621. assertTrue(cc.isFrozen());
  622. try {
  623. cc = sloader.makeClass(
  624. new FileInputStream(PATH + "test1/MakeClass.class"));
  625. assertTrue(false);
  626. }
  627. catch (RuntimeException e) {
  628. print(e.getMessage());
  629. }
  630. }
  631. public void testMakeMethod() throws Exception {
  632. CtClass cc = sloader.makeClass("test1.MakeMethod");
  633. cc.addField(new CtField(CtClass.intType, "i", cc));
  634. String cons_body = "{ i = 3; }";
  635. CtConstructor cons = CtNewConstructor.make(null, null,
  636. cons_body, cc);
  637. cc.addConstructor(cons);
  638. CtMethod m = CtNewMethod.make(CtClass.intType, "run", null, null,
  639. "{ return i; }", cc);
  640. cc.addMethod(m);
  641. cc.writeFile();
  642. Object obj = make(cc.getName());
  643. assertEquals(3, invoke(obj, "run"));
  644. }
  645. public void testDesc() throws Exception {
  646. Class[] sig;
  647. assertEquals(int.class, Desc.getType("I"));
  648. assertEquals(String.class, Desc.getType("Ljava/lang/String;"));
  649. assertEquals(String[].class, Desc.getType("[Ljava/lang/String;"));
  650. assertEquals(int[].class, Desc.getType("[I"));
  651. sig = Desc.getParams("()V");
  652. assertEquals(0, sig.length);
  653. sig = Desc.getParams("(I)V");
  654. assertEquals(int.class, sig[0]);
  655. assertEquals(1, sig.length);
  656. sig = Desc.getParams("(IJ)V");
  657. assertEquals(long.class, sig[1]);
  658. assertEquals(2, sig.length);
  659. sig = Desc.getParams("(Ljava/lang/String;)V");
  660. assertEquals(String.class, sig[0]);
  661. assertEquals(1, sig.length);
  662. sig = Desc.getParams("([Ljava/lang/String;I)V");
  663. assertEquals(String[].class, sig[0]);
  664. assertEquals(2, sig.length);
  665. sig = Desc.getParams("(Ljava/lang/String;[Ljava/lang/String;)V");
  666. assertEquals(String[].class, sig[1]);
  667. assertEquals(2, sig.length);
  668. }
  669. public void testCast() throws Exception {
  670. CtClass cc = sloader.makeClass("test1.CastTest");
  671. StringBuffer src = new StringBuffer();
  672. src.append("public void test(java.lang.String[] strValues)\n");
  673. src.append("{\n");
  674. src.append("\tObject[] values = new Object[2];");
  675. src.append("\tvalues[0] = strValues;");
  676. src.append("\tvalues[1] = strValues;");
  677. src.append("\tstrValues = (String[])values[0];");
  678. src.append("}\n");
  679. CtMethod m = CtNewMethod.make(src.toString(), cc);
  680. }
  681. static final long svUID = 6006955401253799668L;
  682. public void testSerialVUID() throws Exception {
  683. CtClass cc = sloader.get("test1.MySerializableClass");
  684. assertEquals(svUID, SerialVersionUID.calculateDefault(cc));
  685. SerialVersionUID.setSerialVersionUID(cc);
  686. cc.writeFile();
  687. }
  688. public void testInvokeInt() throws Exception {
  689. CtClass cc = sloader.get("test1.InvokeInt");
  690. CtMethod m1 = cc.getDeclaredMethod("check");
  691. m1.instrument(new ExprEditor() {
  692. public void edit(MethodCall m) throws CannotCompileException {
  693. m.replace("$_ = $proceed($$) + k(1);");
  694. }
  695. });
  696. cc.writeFile();
  697. Object obj = make(cc.getName());
  698. assertEquals(6, invoke(obj, "run"));
  699. }
  700. public void testSubtypeOf() throws Exception {
  701. testSubtypeOf2("java.lang.Object", "int", false);
  702. testSubtypeOf2("int[]", "java.lang.Object", true);
  703. testSubtypeOf2("int[]", "java.lang.Cloneable", true);
  704. testSubtypeOf2("java.lang.Object", "int[]", false);
  705. testSubtypeOf2("java.lang.Integer", "java.lang.Number", true);
  706. testSubtypeOf2("java.lang.Number", "java.lang.Integer", false);
  707. testSubtypeOf2("java.lang.Integer[]", "java.lang.Number[]", true);
  708. testSubtypeOf2("java.lang.Number[]", "java.lang.Integer[]", false);
  709. testSubtypeOf2("java.lang.Integer", "java.io.Serializable", true);
  710. testSubtypeOf2("java.lang.Integer", "java.lang.Object", true);
  711. }
  712. private void testSubtypeOf2(String s, String t, boolean b)
  713. throws Exception
  714. {
  715. assertTrue(sloader.get(s).subtypeOf(sloader.get(t)) == b);
  716. }
  717. public void testMakeInterface() throws Exception {
  718. CtClass cc = sloader.makeInterface("test1.MkInterface");
  719. CtMethod m = CtNewMethod.make("public abstract void ready();", cc);
  720. cc.addMethod(m);
  721. cc.writeFile();
  722. // cloader.loadClass(cc.getName());
  723. java.io.File genDir = new java.io.File(".");
  724. java.net.URLClassLoader ucl = new java.net.URLClassLoader(
  725. new java.net.URL[] { genDir.toURL() }, null);
  726. Class intf = ucl.loadClass("test1.MkInterface");
  727. }
  728. public void testCodeConv() throws Exception {
  729. CtClass cc = sloader.get("test1.CodeConv");
  730. CtClass pc = sloader.get("test1.CodeConvP");
  731. CodeConverter conv = new CodeConverter();
  732. conv.replaceFieldRead(pc.getDeclaredField("a1"), cc, "getA1");
  733. conv.replaceFieldRead(pc.getDeclaredField("a2"), cc, "getA2");
  734. conv.redirectFieldAccess(pc.getDeclaredField("a3"), cc, "a4");
  735. conv.replaceFieldWrite(pc.getDeclaredField("b1"), cc, "putB1");
  736. cc.instrument(conv);
  737. cc.writeFile();
  738. Object obj = make(cc.getName());
  739. assertEquals(51, invoke(obj, "run"));
  740. }
  741. public void testTryCatch() throws Exception {
  742. CtClass cc = sloader.get("test1.TryCatch");
  743. CtMethod m1 = cc.getDeclaredMethod("m1");
  744. m1.instrument(new ExprEditor() {
  745. public void edit(MethodCall m) throws CannotCompileException {
  746. m.replace(
  747. "try { doit(); }"
  748. + "catch(NullPointerException e){ init(); doit(); }");
  749. }
  750. });
  751. final String src =
  752. "try { doit(); }"
  753. + "catch(NullPointerException e){ init(); doit(); return a; }";
  754. CtMethod p1 = cc.getDeclaredMethod("p1");
  755. p1.insertAfter(src, true);
  756. cc.writeFile();
  757. Object obj = make(cc.getName());
  758. assertEquals(4, invoke(obj, "run"));
  759. Object obj2 = make(cc.getName());
  760. assertEquals(4, invoke(obj2, "p1"));
  761. }
  762. private CtClass[] throwablesList = null;
  763. public void testGetThrowables() throws Exception {
  764. CtClass cc = sloader.get("test1.GetThrowables");
  765. CtMethod m1 = cc.getDeclaredMethod("run");
  766. m1.instrument(new ExprEditor() {
  767. public void edit(MethodCall m) throws CannotCompileException {
  768. throwablesList = m.mayThrow();
  769. }
  770. });
  771. System.out.println(throwablesList[0].getName());
  772. System.out.println(throwablesList[1].getName());
  773. assertEquals(2, throwablesList.length);
  774. }
  775. public void testArrayAccess() throws Exception {
  776. CtClass cc = sloader.get("test1.ArrayAccess");
  777. CtMethod m1 = cc.getDeclaredMethod("test");
  778. m1.insertBefore("{ ia[0] += 1; iaa[1] = iaa[0]; }");
  779. cc.writeFile();
  780. Object obj = make(cc.getName());
  781. assertEquals(8, invoke(obj, "test"));
  782. }
  783. public void testClinit() throws Exception {
  784. CtClass cc = sloader.get("test1.Clinit");
  785. CtConstructor clinit = cc.getClassInitializer();
  786. assertTrue(clinit != null);
  787. try {
  788. clinit.insertBeforeBody(";");
  789. assertTrue(false);
  790. }
  791. catch (CannotCompileException e) {
  792. print(e.toString());
  793. assertEquals("class initializer", e.getReason());
  794. }
  795. CtConstructor[] init = cc.getConstructors();
  796. assertEquals(1, init.length);
  797. clinit.insertAfter("j += 1;");
  798. cc.writeFile();
  799. Object obj = make(cc.getName());
  800. assertEquals(457, invoke(obj, "run"));
  801. }
  802. public void testClinit2() throws Exception {
  803. CtClass cc = sloader.get("test1.Clinit2");
  804. CtConstructor clinit = cc.makeClassInitializer();
  805. clinit.insertAfter("j = 7;");
  806. cc.writeFile();
  807. Object obj = make(cc.getName());
  808. assertEquals(7, invoke(obj, "run"));
  809. }
  810. // by yamazaki
  811. public void testCondExpr() throws Exception {
  812. CtClass cc = sloader.makeClass("test1.CondExpr");
  813. CtMethod methodM = new CtMethod(CtClass.intType, "m",
  814. new CtClass[]{ CtClass.intType }, cc);
  815. methodM.setModifiers(methodM.getModifiers() | Modifier.STATIC);
  816. methodM.setBody("{if($1 <= 0) return 1; else return 0;}");
  817. cc.addMethod(methodM);
  818. cc.writeFile();
  819. Object obj = make(cc.getName());
  820. assertEquals(0, invoke(obj, "m", 3));
  821. }
  822. // by yamazaki
  823. public void testCondExpr2() throws Exception {
  824. CtClass cc = sloader.makeClass("test1.CondExpr2");
  825. CtMethod methodM = new CtMethod(CtClass.intType, "m",
  826. new CtClass[]{ CtClass.intType }, cc);
  827. methodM.setModifiers(methodM.getModifiers() | Modifier.STATIC);
  828. methodM.setBody("{return ($1 <= 0) ? 1 : (m($1 - 1) * $1);}");
  829. cc.addMethod(methodM);
  830. cc.writeFile();
  831. Object obj = make(cc.getName());
  832. assertEquals(6, invoke(obj, "m", 3));
  833. }
  834. // by yamazaki
  835. public void testCondExpr3() throws Exception {
  836. CtClass cc = sloader.makeClass("test1.CondExpr3");
  837. CtMethod methodM = CtNewMethod.make(
  838. "public abstract int m(int i);", cc);
  839. CtMethod methodN = CtNewMethod.make(
  840. "public abstract int n(int i);", cc);
  841. cc.addMethod(methodM);
  842. cc.addMethod(methodN);
  843. methodM.setBody("{return ($1 <= 0) ? 1 : (n($1 - 1) * $1);}");
  844. methodN.setBody("{return m($1);}");
  845. cc.setModifiers(cc.getModifiers() & ~Modifier.ABSTRACT);
  846. cc.writeFile();
  847. Object obj = make(cc.getName());
  848. assertEquals(6, invoke(obj, "m", 3));
  849. }
  850. public void testDelegator() throws Exception {
  851. CtClass cc = sloader.get("test1.Delegator");
  852. assertEquals("test1.SuperDelegator", cc.getSuperclass().getName());
  853. CtMethod f = sloader.getMethod("test1.SuperDelegator", "f");
  854. CtMethod g = sloader.getMethod("test1.SuperDelegator", "g");
  855. cc.addMethod(CtNewMethod.delegator(f, cc));
  856. cc.addMethod(CtNewMethod.delegator(g, cc));
  857. cc.writeFile();
  858. Object obj = make(cc.getName());
  859. assertEquals(15, invoke(obj, "run"));
  860. }
  861. public void testSetName() throws Exception {
  862. CtClass cc = sloader.get("test1.SetName");
  863. CtMethod m0 = cc.getDeclaredMethod("foo");
  864. cc.setName("test1.SetName2");
  865. assertEquals(cc, sloader.get("test1.SetName2"));
  866. assertEquals("foo(Ltest1/SetName2;)", m0.getStringRep());
  867. CtClass cc2 = sloader.makeClass("test1.SetName3");
  868. CtMethod m = CtNewMethod.make(
  869. "public int m(test1.SetName2 obj) { return ((test1.SetName2)obj).i; }",
  870. cc2);
  871. cc2.addMethod(m);
  872. cc.writeFile();
  873. cc2.writeFile();
  874. }
  875. public void testFieldModifier() throws Exception {
  876. CtClass cc = sloader.get("test1.FieldMod");
  877. CtField f = cc.getField("text");
  878. f.setModifiers(Modifier.PUBLIC);
  879. f = cc.getField("i");
  880. f.setName("j");
  881. cc.writeFile();
  882. Object obj = make(cc.getName());
  883. assertEquals(java.lang.reflect.Modifier.PUBLIC,
  884. obj.getClass().getField("text").getModifiers());
  885. assertTrue(obj.getClass().getField("j") != null);
  886. }
  887. public void testToString() throws Exception {
  888. System.out.println(sloader.get("test1.FieldMod"));
  889. System.out.println(sloader.get("java.lang.Object"));
  890. }
  891. public void testPackage() throws Exception {
  892. Object obj = new Loader().loadClass("test1.Pac").newInstance();
  893. assertEquals(1, invoke(obj, "run"));
  894. }
  895. public void testHoward() throws Exception {
  896. String head =
  897. "public Object lookup() throws java.rmi.RemoteException ";
  898. String src =
  899. "{ if (_remote != null) return _remote;"
  900. + " test1.HowardHome h = (test1.HowardHome)lookup(\"Howard\");"
  901. + " try { _remote = h.create(); }"
  902. + " catch (java.io.IOException e) { throw new java.rmi.RemoteException(e.getMessage(), e); }"
  903. + " return _remote; }";
  904. String src2 =
  905. "public void lookup2() {"
  906. + " try {}"
  907. + " catch (java.io.IOException e) { throw new Exception(e); }"
  908. + "}";
  909. CtClass cc = sloader.get("test1.Howard");
  910. CtMethod m = CtNewMethod.make(head + src, cc);
  911. cc.addMethod(m);
  912. try {
  913. CtMethod m2 = CtNewMethod.make(src2, cc);
  914. cc.addMethod(m2);
  915. assertTrue(false);
  916. }
  917. catch (CannotCompileException e) {}
  918. m = new CtMethod(sloader.get("java.lang.Object"),
  919. "lookup3", null, cc);
  920. m.setBody(src);
  921. m.setModifiers(Modifier.PUBLIC);
  922. m.setExceptionTypes(new CtClass[] {
  923. sloader.get("java.rmi.RemoteException") });
  924. cc.addMethod(m);
  925. cc.writeFile();
  926. Object target = make(cc.getName());
  927. Method mth = target.getClass().getMethod("lookup", new Class[0]);
  928. Object res = mth.invoke(target, new Object[0]);
  929. assertEquals("howard4", res);
  930. mth = target.getClass().getMethod("lookup3", new Class[0]);
  931. res = mth.invoke(target, new Object[0]);
  932. assertEquals("howard4", res);
  933. }
  934. public void testLoop() throws Exception {
  935. CtClass cc = sloader.makeClass("test1.Loop");
  936. CtMethod m = CtNewMethod.make(
  937. "public int run(int i) { int k = 0;"
  938. + "while (true) { if (k++ > 10) return i; } }",
  939. cc);
  940. cc.addMethod(m);
  941. cc.writeFile();
  942. Object obj = make(cc.getName());
  943. assertEquals(3, invoke(obj, "run", 3));
  944. }
  945. public static Test suite() {
  946. TestSuite suite = new TestSuite("Javassist Tests");
  947. suite.addTestSuite(JvstTest.class);
  948. suite.addTestSuite(JvstTest2.class);
  949. suite.addTestSuite(JvstTest3.class);
  950. suite.addTestSuite(JvstTest4.class);
  951. suite.addTestSuite(JvstTest5.class);
  952. suite.addTestSuite(LoaderTestByRandall.class);
  953. suite.addTestSuite(javassist.bytecode.BytecodeTest.class);
  954. suite.addTestSuite(javassist.bytecode.StackMapTest.class);
  955. suite.addTestSuite(javassist.compiler.CompTest.class);
  956. suite.addTestSuite(javassist.SetterTest.class);
  957. suite.addTestSuite(javassist.bytecode.InsertGap0.class);
  958. suite.addTestSuite(javassist.tools.reflect.LoaderTest.class);
  959. suite.addTestSuite(testproxy.ProxyTester.class);
  960. suite.addTestSuite(testproxy.ProxyFactoryPerformanceTest.class); // remove?
  961. suite.addTestSuite(javassist.proxyfactory.ProxyFactoryTest.class);
  962. suite.addTestSuite(javassist.proxyfactory.Tester.class);
  963. suite.addTestSuite(test.javassist.proxy.ProxySerializationTest.class);
  964. suite.addTestSuite(test.javassist.convert.ArrayAccessReplaceTest.class);
  965. suite.addTestSuite(test.javassist.proxy.JASSIST113RegressionTest.class);
  966. suite.addTestSuite(test.javassist.proxy.JBPAPP9257Test.class);
  967. suite.addTestSuite(test.javassist.proxy.ProxyCacheGCTest.class); // remvoe?
  968. suite.addTestSuite(test.javassist.proxy.ProxyFactoryCompatibilityTest.class);
  969. suite.addTestSuite(test.javassist.proxy.ProxySerializationTest.class);
  970. suite.addTestSuite(test.javassist.proxy.ProxySimpleTest.class);
  971. suite.addTestSuite(test.javassist.bytecode.analysis.AnalyzerTest.class);
  972. suite.addTestSuite(test.javassist.convert.ArrayAccessReplaceTest.class);
  973. suite.addTestSuite(test.javassist.bytecode.analysis.DomTreeTest.class);
  974. return suite;
  975. }
  976. }