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.

JvstTest4.java 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. package javassist;
  2. import java.io.DataOutputStream;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.util.Collection;
  7. import java.util.HashSet;
  8. import javassist.bytecode.*;
  9. import javassist.bytecode.annotation.*;
  10. import javassist.expr.*;
  11. public class JvstTest4 extends JvstTestRoot {
  12. public JvstTest4(String name) {
  13. super(name);
  14. }
  15. public void testInsertLocalVars() throws Exception {
  16. CtClass cc = sloader.get("test4.LocalVars");
  17. CtMethod m1 = cc.getDeclaredMethod("run");
  18. m1.getMethodInfo().getCodeAttribute().insertLocalVar(2, 20);
  19. m1.getMethodInfo().rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile());
  20. CtMethod m2 = cc.getDeclaredMethod("run2");
  21. m2.getMethodInfo().getCodeAttribute().insertLocalVar(2, 0x101);
  22. m2.getMethodInfo().rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile());
  23. cc.writeFile();
  24. Object obj = make(cc.getName());
  25. assertEquals(10, invoke(obj, "run"));
  26. assertEquals(10, invoke(obj, "run2"));
  27. }
  28. public void testCodeConv() throws Exception {
  29. CtClass cc = sloader.get("test4.CodeConv");
  30. CtMethod m1 = cc.getDeclaredMethod("m1");
  31. CtMethod m2 = cc.getDeclaredMethod("m2");
  32. CtMethod m3 = cc.getDeclaredMethod("m3");
  33. CodeConverter conv = new CodeConverter();
  34. conv.insertAfterMethod(m1, m3);
  35. conv.insertBeforeMethod(m2, m3);
  36. cc.instrument(conv);
  37. cc.writeFile();
  38. Object obj = make(cc.getName());
  39. assertEquals(111033, invoke(obj, "run"));
  40. }
  41. public void testCodeConv2() throws Exception {
  42. CtClass cc = sloader.get("test4.CodeConv2");
  43. CtField f = cc.getDeclaredField("field");
  44. CtField f2 = cc.getDeclaredField("sf");
  45. CtMethod run = cc.getDeclaredMethod("run");
  46. CodeConverter conv = new CodeConverter();
  47. conv.replaceFieldRead(f, cc, "read");
  48. conv.replaceFieldWrite(f, cc, "write");
  49. conv.replaceFieldRead(f2, cc, "read");
  50. conv.replaceFieldWrite(f2, cc, "write");
  51. run.instrument(conv);
  52. cc.writeFile();
  53. Object obj = make(cc.getName());
  54. assertEquals(14001600, invoke(obj, "run"));
  55. }
  56. public void testInsGap() throws Exception {
  57. CtClass cc = sloader.get("test4.GapSwitch");
  58. ExprEditor ed = new ExprEditor() {
  59. public void edit(MethodCall c) throws CannotCompileException {
  60. c.replace("{ value++; $_ = $proceed($$); }");
  61. }
  62. };
  63. CtMethod m1 = cc.getDeclaredMethod("run");
  64. m1.instrument(ed);
  65. CtMethod m2 = cc.getDeclaredMethod("run2");
  66. m2.instrument(ed);
  67. final CtMethod m3 = cc.getDeclaredMethod("run3");
  68. m3.instrument(new ExprEditor() {
  69. public void edit(MethodCall c) throws CannotCompileException {
  70. CodeIterator it = m3.getMethodInfo().getCodeAttribute().iterator();
  71. try {
  72. it.insertGap(c.indexOfBytecode(), 5000);
  73. } catch (BadBytecode e) {
  74. throw new CannotCompileException(e);
  75. }
  76. }
  77. });
  78. // m3.getMethodInfo2().rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2());
  79. cc.writeFile();
  80. Object obj = make(cc.getName());
  81. assertEquals(1010, invoke(obj, "run"));
  82. assertEquals(1100, invoke(obj, "run2"));
  83. assertEquals(12222, invoke(obj, "run3"));
  84. }
  85. public void testAnnotationCheck() throws Exception {
  86. CtClass cc = sloader.get("test4.Anno");
  87. CtMethod m1 = cc.getDeclaredMethod("foo");
  88. CtField f = cc.getDeclaredField("value");
  89. assertTrue(cc.hasAnnotation(test4.Anno1.class));
  90. assertFalse(cc.hasAnnotation(java.lang.annotation.Documented.class));
  91. assertEquals("empty", ((test4.Anno1)cc.getAnnotation(test4.Anno1.class)).value());
  92. assertNull(cc.getAnnotation(Deprecated.class));
  93. assertTrue(m1.hasAnnotation(test4.Anno1.class));
  94. assertFalse(m1.hasAnnotation(java.lang.annotation.Documented.class));
  95. assertTrue(m1.getAnnotation(test4.Anno1.class) != null);
  96. assertNull(m1.getAnnotation(Deprecated.class));
  97. assertTrue(f.hasAnnotation(test4.Anno1.class));
  98. assertFalse(f.hasAnnotation(java.lang.annotation.Documented.class));
  99. assertTrue(f.getAnnotation(test4.Anno1.class) != null);
  100. assertNull(f.getAnnotation(Deprecated.class));
  101. }
  102. public void testRename() throws Exception {
  103. CtClass cc = sloader.get("test4.Rename");
  104. cc.setName("test4.Rename2");
  105. cc.rebuildClassFile();
  106. cc.writeFile();
  107. CtClass cc2 = sloader.get("test4.IRename");
  108. cc2.replaceClassName("test4.Rename", "test4.Rename2");
  109. cc2.rebuildClassFile();
  110. cc2.writeFile();
  111. Object obj = make(cc.getName());
  112. assertEquals("test4.Rename2", obj.getClass().getName());
  113. assertEquals(14, invoke(obj, "run"));
  114. }
  115. public void testRename2() throws Exception {
  116. CtClass cc = sloader.get("test4.Signature");
  117. cc.setName("test4.Sig");
  118. cc.rebuildClassFile();
  119. cc.writeFile();
  120. Object obj = make(cc.getName());
  121. assertEquals(3, invoke(obj, "run"));
  122. }
  123. public void testJIRA93() throws Exception {
  124. ClassPool cp = ClassPool.getDefault();
  125. CtClass cc = sloader.getCtClass("test4.JIRA93");
  126. CtMethod m = cc.getDeclaredMethod("foo");
  127. m.addLocalVariable("bar", CtClass.longType);
  128. // The original bug report includes the next line.
  129. // But this is not a bug.
  130. //m.insertAfter("bar;", true);
  131. // Instead, the following code is OK.
  132. m.insertBefore("bar = 0;");
  133. m.insertAfter("bar;", false);
  134. cc.writeFile();
  135. Object obj = make(cc.getName());
  136. }
  137. public void testNewRemover() throws Exception {
  138. CtClass cc = sloader.get("test4.NewRemover");
  139. CtMethod mth = cc.getDeclaredMethod("make");
  140. mth.getMethodInfo().rebuildStackMap(cc.getClassPool());
  141. mth.getMethodInfo().rebuildStackMapForME(cc.getClassPool());
  142. //cc.debugWriteFile("debug");
  143. CodeConverter conv = new CodeConverter();
  144. conv.replaceNew(cc, cc, "make2");
  145. mth.instrument(conv);
  146. cc.writeFile();
  147. Object obj = make(cc.getName());
  148. assertEquals(10, invoke(obj, "run"));
  149. }
  150. public void testClassFileWriter() throws Exception {
  151. ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0);
  152. ClassFileWriter.ConstPoolWriter cpw = cfw.getConstPool();
  153. ClassFileWriter.FieldWriter fw = cfw.getFieldWriter();
  154. fw.add(AccessFlag.PUBLIC, "value", "J", null);
  155. fw.add(AccessFlag.PROTECTED | AccessFlag.STATIC, "value2", "Ljava/lang/String;", null);
  156. ClassFileWriter.MethodWriter mw = cfw.getMethodWriter();
  157. mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, null);
  158. mw.add(Opcode.ALOAD_0);
  159. mw.addInvoke(Opcode.INVOKESPECIAL, "java/lang/Object", MethodInfo.nameInit, "()V");
  160. mw.add(Opcode.RETURN);
  161. mw.codeEnd(1, 1);
  162. mw.end(null, null);
  163. mw.begin(AccessFlag.PUBLIC, "move", "(II)V", null, null);
  164. mw.add(Opcode.ALOAD_0);
  165. mw.addInvoke(Opcode.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
  166. mw.add(Opcode.POP);
  167. mw.add(Opcode.RETURN);
  168. mw.add(Opcode.POP);
  169. mw.add(Opcode.RETURN);
  170. mw.codeEnd(1, 3);
  171. mw.addCatch(0, 4, 6, cpw.addClassInfo("java/lang/Exception"));
  172. mw.addCatch(0, 4, 6, cpw.addClassInfo("java/lang/Throwable"));
  173. mw.end(null, null);
  174. String[] exceptions = { "java/lang/Exception", "java/lang/NullPointerException" };
  175. mw.begin(AccessFlag.PUBLIC, "move2", "()V", exceptions, null);
  176. mw.add(Opcode.RETURN);
  177. mw.codeEnd(0, 1);
  178. StackMapTable.Writer stack = new StackMapTable.Writer(32);
  179. stack.sameFrame(1);
  180. mw.end(stack, null);
  181. mw.begin(AccessFlag.PUBLIC, "foo", "()I", null, null);
  182. mw.add(Opcode.ICONST_2);
  183. mw.add(Opcode.IRETURN);
  184. mw.codeEnd(1, 1);
  185. mw.end(null, null);
  186. byte[] out = cfw.end(AccessFlag.PUBLIC, cpw.addClassInfo("test4/WrittenFile"),
  187. cpw.addClassInfo("java/lang/Object"),
  188. null, null);
  189. FileOutputStream fos = new FileOutputStream("test4/WrittenFile.class");
  190. fos.write(out);
  191. fos.close();
  192. Object obj = make("test4.WrittenFile");
  193. assertNotNull(obj);
  194. assertEquals(2, invoke(obj, "foo"));
  195. }
  196. public void testClassFileWriter2() throws Exception {
  197. ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0);
  198. ClassFileWriter.ConstPoolWriter cpw = cfw.getConstPool();
  199. ClassFileWriter.FieldWriter fw = cfw.getFieldWriter();
  200. fw.add(AccessFlag.PUBLIC | AccessFlag.STATIC, "value", "I", null);
  201. ClassFileWriter.MethodWriter mw = cfw.getMethodWriter();
  202. mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, null);
  203. mw.add(Opcode.ALOAD_0);
  204. mw.addInvoke(Opcode.INVOKESPECIAL, "java/lang/Object", MethodInfo.nameInit, "()V");
  205. mw.add(Opcode.RETURN);
  206. mw.codeEnd(1, 1);
  207. mw.end(null, null);
  208. String[] exceptions = { "java/lang/Exception" };
  209. mw.begin(AccessFlag.PUBLIC | AccessFlag.ABSTRACT, "move", "(II)V", exceptions, null);
  210. mw.end(null, null);
  211. int thisClass = cpw.addClassInfo("test4/WrittenFile2");
  212. int superClass = cpw.addClassInfo("java/lang/Object");
  213. cfw.end(new DataOutputStream(new FileOutputStream("test4/WrittenFile2.class")),
  214. AccessFlag.PUBLIC | AccessFlag.ABSTRACT, thisClass, superClass,
  215. null, null);
  216. File f = new File("test4/WrittenFile2.class");
  217. byte[] file = new byte[(int)f.length()];
  218. FileInputStream fis = new FileInputStream(f);
  219. fis.read(file);
  220. fis.close();
  221. byte[] out = cfw.end(AccessFlag.PUBLIC | AccessFlag.ABSTRACT, thisClass,
  222. superClass, null, null);
  223. assertEquals(out.length, file.length);
  224. for (int i = 0; i < out.length; i++)
  225. assertEquals(out[i], file[i]);
  226. CtClass sub = dloader.makeClass("test4.WrittenFile2sub", dloader.get("test4.WrittenFile2"));
  227. sub.addMethod(CtMethod.make("public void move(int i, int j) {}", sub));
  228. sub.addMethod(CtMethod.make("public int foo() { move(0, 1); return 1; }", sub));
  229. sub.writeFile();
  230. Object obj = make("test4.WrittenFile2sub");
  231. assertEquals(1, invoke(obj, "foo"));
  232. }
  233. public void testClassFileWriter3() throws Exception {
  234. ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0);
  235. ClassFileWriter.ConstPoolWriter cpw = cfw.getConstPool();
  236. int superClass = cpw.addClassInfo("java/lang/Object");
  237. final int syntheticTag = cpw.addUtf8Info("Synthetic");
  238. ClassFileWriter.AttributeWriter attribute = new ClassFileWriter.AttributeWriter() {
  239. public void write(DataOutputStream out) throws java.io.IOException {
  240. out.writeShort(syntheticTag);
  241. out.writeInt(0);
  242. }
  243. public int size() {
  244. return 1;
  245. }
  246. };
  247. ClassFileWriter.FieldWriter fw = cfw.getFieldWriter();
  248. fw.add(AccessFlag.PUBLIC, "value", "J", null);
  249. fw.add(AccessFlag.PROTECTED | AccessFlag.STATIC, "value2", "Ljava/lang/String;", attribute);
  250. ClassFileWriter.MethodWriter mw = cfw.getMethodWriter();
  251. mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, attribute);
  252. mw.add(Opcode.ALOAD_0);
  253. mw.add(Opcode.INVOKESPECIAL);
  254. mw.add16(cpw.addMethodrefInfo(superClass, cpw.addNameAndTypeInfo(MethodInfo.nameInit, "()V")));
  255. // mw.addInvoke(Opcode.INVOKESPECIAL, "java/lang/Object", MethodInfo.nameInit, "()V");
  256. mw.add(Opcode.RETURN);
  257. mw.codeEnd(1, 1);
  258. mw.end(null, null);
  259. mw.begin(AccessFlag.PUBLIC, "foo", "()I", null, attribute);
  260. mw.add(Opcode.ICONST_2);
  261. mw.add(Opcode.IRETURN);
  262. mw.codeEnd(1, 1);
  263. mw.end(null, null);
  264. int thisClass = cpw.addClassInfo("test4/WrittenFile3");
  265. cfw.end(new DataOutputStream(new FileOutputStream("test4/WrittenFile3.class")),
  266. AccessFlag.PUBLIC, thisClass, superClass,
  267. null, attribute);
  268. File f = new File("test4/WrittenFile3.class");
  269. byte[] file = new byte[(int)f.length()];
  270. FileInputStream fis = new FileInputStream(f);
  271. fis.read(file);
  272. fis.close();
  273. byte[] out = cfw.end(AccessFlag.PUBLIC, thisClass, superClass,
  274. null, attribute);
  275. assertEquals(out.length, file.length);
  276. for (int i = 0; i < out.length; i++)
  277. assertEquals(out[i], file[i]);
  278. Object obj = make("test4.WrittenFile3");
  279. assertNotNull(obj);
  280. assertEquals(2, invoke(obj, "foo"));
  281. }
  282. public void testCtArray() throws Exception {
  283. CtClass cc = sloader.get("int");
  284. assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers());
  285. cc = sloader.get("int[]");
  286. assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers());
  287. cc = sloader.get("java.lang.String[]");
  288. assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers());
  289. CtClass[] intfs = cc.getInterfaces();
  290. assertEquals(Cloneable.class.getName(), intfs[0].getName());
  291. assertEquals(java.io.Serializable.class.getName(), intfs[1].getName());
  292. cc = sloader.get("test4.CtArrayTest[]");
  293. assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers());
  294. }
  295. public void testAnalysisType() throws Exception {
  296. testAnalysisType2(sloader.get("int[]"), 1);
  297. testAnalysisType2(sloader.get("java.lang.String[][]"), 2);
  298. sloader.makeClass("A");
  299. testAnalysisType2(sloader.getCtClass("A"), 0);
  300. testAnalysisType2(sloader.getCtClass("A[]"), 1);
  301. testAnalysisType2(sloader.getCtClass("A[][]"), 2);
  302. }
  303. private void testAnalysisType2(CtClass cc, int size) throws Exception {
  304. javassist.bytecode.analysis.Type t = javassist.bytecode.analysis.Type.get(cc);
  305. assertEquals(cc.getName(), size, t.getDimensions());
  306. }
  307. public void testArrayType() throws Exception {
  308. CtClass at = sloader.get("java.lang.Object[]");
  309. CtClass[] intfs = at.getInterfaces();
  310. assertEquals(intfs.length, 2);
  311. assertEquals(intfs[0].getName(), java.lang.Cloneable.class.getName());
  312. assertEquals(intfs[1].getName(), java.io.Serializable.class.getName());
  313. assertTrue(at.subtypeOf(sloader.get(java.lang.Object.class.getName())));
  314. assertTrue(at.subtypeOf(intfs[0]));
  315. assertTrue(at.subtypeOf(intfs[1]));
  316. assertTrue(at.subtypeOf(intfs[1]));
  317. CtClass subt = sloader.get(java.text.CharacterIterator.class.getName());
  318. assertFalse(at.subtypeOf(subt));
  319. }
  320. public void testGetFieldDesc() throws Exception {
  321. CtClass cc = sloader.get("test4.GetFieldDesc");
  322. cc.getDeclaredField("f", "I");
  323. cc.getField("s", "Ljava/lang/String;");
  324. CtClass cc2 = sloader.get("test4.GetFieldDescSub");
  325. assertEquals(cc2.getField("s", "Ljava/lang/String;").getDeclaringClass().getName(),
  326. "test4.GetFieldDesc");
  327. assertEquals(cc2.getField("s", "I").getDeclaringClass().getName(),
  328. "test4.GetFieldDescSub");
  329. }
  330. public void testMakeMethod() throws CannotCompileException {
  331. CtClass ctClass = sloader.makeClass("test4.MakeMethod2");
  332. CtNewMethod.make("public String foox(){return test4.MakeMethod.foo();}", ctClass);
  333. CtNewMethod.make("public String foo(){return test4.MakeMethod.foo();}", ctClass);
  334. }
  335. public void testVarArgs() throws Exception {
  336. CtClass cc = sloader.get("test4.VarArgs");
  337. CtMethod m = CtMethod.make("public int foo(int i, String[] args) { return args.length; }", cc);
  338. m.setModifiers(m.getModifiers() | Modifier.VARARGS);
  339. cc.addMethod(m);
  340. m = CtMethod.make("public int run() { return goo(7, new int[] { 1, 2, 3 }); }", cc);
  341. cc.addMethod(m);
  342. cc.writeFile();
  343. Object obj = make(cc.getName());
  344. assertEquals(3, invoke(obj, "run"));
  345. }
  346. public void testGetAllRef() throws Exception {
  347. CtClass cc = sloader.get("test4.GetAllRef");
  348. ClassFile cf = cc.getClassFile();
  349. AttributeInfo ainfo
  350. = cf.getAttribute(AnnotationsAttribute.visibleTag);
  351. ClassMap map = new ClassMap();
  352. map.put("test4.GetAllRefAnno", "test4.GetAllRefAnno2");
  353. map.put("test4.GetAllRefEnum", "test4.GetAllRefEnum2");
  354. map.put("java.lang.String", "java.lang.StringBuilder");
  355. cf.addAttribute(ainfo.copy(cf.getConstPool(), map));
  356. cc.writeFile();
  357. cc.detach();
  358. cc = dloader.get(cc.getName());
  359. test4.GetAllRefAnno2 anno
  360. = (test4.GetAllRefAnno2)cc.getAnnotation(test4.GetAllRefAnno2.class);
  361. assertEquals(test4.GetAllRefEnum2.A, anno.getA());
  362. assertEquals(StringBuilder.class, anno.getC());
  363. }
  364. public void testGetAllRefB() throws Exception {
  365. CtClass cc = sloader.get("test4.GetAllRefB");
  366. ClassMap map = new ClassMap();
  367. map.put("test4.GetAllRefAnno", "test4.GetAllRefAnno2");
  368. map.put("test4.GetAllRefEnum", "test4.GetAllRefEnum2");
  369. map.put("java.lang.String", "java.lang.StringBuilder");
  370. cc.replaceClassName(map);
  371. //cc.replaceClassName("test4.GetAllRefAnno", "test4.GetAllRefAnno2");
  372. cc.writeFile();
  373. cc = dloader.get(cc.getName());
  374. test4.GetAllRefAnno2 anno
  375. = (test4.GetAllRefAnno2)cc.getAnnotation(test4.GetAllRefAnno2.class);
  376. assertEquals(test4.GetAllRefEnum2.A, anno.getA());
  377. assertEquals(StringBuilder.class, anno.getC());
  378. /*
  379. AnnotationsAttribute aainfo = (AnnotationsAttribute)
  380. cc.getClassFile().getAttribute(AnnotationsAttribute.visibleTag);
  381. Annotation[] a = aainfo.getAnnotations();
  382. System.err.println(a[0].getTypeName());
  383. System.err.println(a[0]);
  384. */
  385. }
  386. public void testGetAllRefC() throws Exception {
  387. CtClass cc = sloader.get("test4.GetAllRefC");
  388. HashSet set = new HashSet();
  389. set.add("java.lang.Object");
  390. set.add("java.lang.String");
  391. set.add("test4.GetAllRefC");
  392. set.add("test4.GetAllRefAnno");
  393. set.add("test4.GetAllRefEnum");
  394. set.add("test4.GetAllRefAnnoC");
  395. set.add("test4.GetAllRefAnnoC2");
  396. set.add("test4.GetAllRefAnnoC3");
  397. set.add("test4.GetAllRefAnnoC4");
  398. java.util.Collection<String> refs
  399. = (java.util.Collection<String>)cc.getRefClasses();
  400. assertEquals(set.size(), refs.size());
  401. for (String s: refs) {
  402. assertTrue(set.contains(s));
  403. }
  404. }
  405. public void testGetAllRefInner() throws Exception {
  406. HashSet set = new HashSet();
  407. set.add("java.lang.Object");
  408. set.add("test4.GetAllRefInnerTest");
  409. set.add("test4.GetAllRefInnerTest$1");
  410. set.add("test4.GetAllRefInnerTest$2");
  411. CtClass cc = sloader.get("test4.GetAllRefInnerTest");
  412. int size = 0;
  413. for (Object s: cc.getRefClasses()) {
  414. assertTrue((String)s, set.contains(s));
  415. ++size;
  416. }
  417. assertEquals(set.size(), size);
  418. }
  419. public void testNestedClass() throws Exception {
  420. CtClass cc = sloader.get("test4.NestedClass$1");
  421. CtClass[] tab = cc.getNestedClasses();
  422. assertEquals(1, tab.length);
  423. assertEquals("test4.NestedClass$1$1", tab[0].getName());
  424. cc = sloader.get("test4.NestedClass$1$1");
  425. tab = cc.getNestedClasses();
  426. assertEquals(0, tab.length);
  427. cc = sloader.get("test4.NestedClass");
  428. tab = cc.getNestedClasses();
  429. for (CtClass c: tab) {
  430. System.err.println(c.getName());
  431. }
  432. // Eclipse compiler sets tab.length to 4 but javac sets to 3.
  433. assertTrue(tab.length == 4 || tab.length == 3);
  434. for (CtClass c: tab) {
  435. String name = c.getName();
  436. assertTrue(name.equals("test4.NestedClass$N")
  437. || name.equals("test4.NestedClass$S")
  438. || name.equals("test4.NestedClass$1")
  439. || name.equals("test4.NestedClass$1In"));
  440. }
  441. cc = sloader.get("test4.NestedClass$1In");
  442. tab = cc.getNestedClasses();
  443. assertEquals(0, tab.length);
  444. }
  445. public void testGetClasses() throws Exception {
  446. CtClass cc = sloader.get("test4.NestedClass");
  447. CtClass[] tab = cc.getDeclaredClasses();
  448. // Eclipse compiler sets tab.length to 4 but javac sets to 3.
  449. assertTrue(tab.length == 4 || tab.length == 3);
  450. for (CtClass c: tab) {
  451. String name = c.getName();
  452. assertTrue(name.equals("test4.NestedClass$N")
  453. || name.equals("test4.NestedClass$S")
  454. || name.equals("test4.NestedClass$1")
  455. || name.equals("test4.NestedClass$1In"));
  456. }
  457. cc = sloader.get("test4.NestedClass$1In");
  458. tab = cc.getDeclaredClasses();
  459. assertEquals(0, tab.length);
  460. }
  461. public void testImportPac() throws Exception {
  462. CtClass cc = sloader.makeClass("test4.TestImpP");
  463. sloader.importPackage("test4.NewImportPac");
  464. try {
  465. cc.addMethod(CtNewMethod.make(
  466. "public int foo(){ " +
  467. " ImportPac obj = new ImportPac();" +
  468. " return obj.getClass().getName().length(); }", cc));
  469. fail("ImportPac was found");
  470. }
  471. catch (CannotCompileException e) {}
  472. cc.addMethod(CtNewMethod.make(
  473. "public int bar(){ " +
  474. " NewImportPac obj = new NewImportPac();" +
  475. " return obj.getClass().getName().length(); }", cc));
  476. sloader.clearImportedPackages();
  477. }
  478. public void testLength() throws Exception {
  479. CtClass cc = sloader.makeClass("test4.LengthTest");
  480. cc.addMethod(CtNewMethod.make(
  481. "public int len(String s){ " +
  482. " return s.length(); }", cc));
  483. cc.addField(CtField.make("int length = 100;", cc));
  484. cc.addConstructor(CtNewConstructor.defaultConstructor(cc));
  485. cc.addMethod(CtNewMethod.make(
  486. "public int run(){ " +
  487. " test4.LengthTest t = new test4.LengthTest();" +
  488. " return len(\"foo\") + t.length + test4.length.m(); }", cc));
  489. try {
  490. cc.addMethod(CtNewMethod.make(
  491. "public int run(){ " +
  492. " return test4no.length.m(); }", cc));
  493. fail("test4no was found!");
  494. }
  495. catch (CannotCompileException e) {
  496. System.out.println(e);
  497. }
  498. cc.writeFile();
  499. Object obj = make(cc.getName());
  500. assertEquals(110, invoke(obj, "run"));
  501. }
  502. public void testAaload() throws Exception {
  503. CtClass clazz = sloader.get("test4.Aaload");
  504. CtMethod method = clazz.getMethod("narf", "()V");
  505. method.instrument(new ExprEditor() {
  506. @Override
  507. public void edit(MethodCall call) throws CannotCompileException {
  508. String name = call.getMethodName();
  509. if (name.equals("addActionListener"))
  510. call.replace("$0." + name + "($$);");
  511. }
  512. });
  513. }
  514. public void testPackage() throws Throwable { // JASSIST-147
  515. String packageName = "test4.pack";
  516. ClassPool pool = ClassPool.getDefault();
  517. pool.makePackage(pool.getClassLoader(), packageName);
  518. pool.makePackage(pool.getClassLoader(), packageName);
  519. CtClass ctcl = pool.makeClass("test4.pack.Clazz");
  520. Class cl = ctcl.toClass();
  521. Object obj = cl.newInstance();
  522. assertEquals(packageName, obj.getClass().getPackage().getName());
  523. }
  524. public static final String BASE_PATH="../";
  525. public static final String JAVASSIST_JAR=BASE_PATH+"javassist.jar";
  526. public static final String CLASSES_FOLDER=BASE_PATH+"build/classes";
  527. public static final String TEST_CLASSES_FOLDER=BASE_PATH+"build/test-classes";
  528. public static class Inner1 {
  529. public static int get() {
  530. return 0;
  531. }
  532. }
  533. public void testJIRA150() throws Exception {
  534. ClassPool pool = new ClassPool(true);
  535. for(int paths=0; paths<50; paths++) {
  536. pool.appendClassPath(JAVASSIST_JAR);
  537. pool.appendClassPath(CLASSES_FOLDER);
  538. pool.appendClassPath(TEST_CLASSES_FOLDER);
  539. }
  540. CtClass cc = pool.get("Jassist150$Inner1");
  541. CtMethod ccGet = cc.getDeclaredMethod("get");
  542. long startTime = System.currentTimeMillis();
  543. for(int replace=0; replace<1000; replace++) {
  544. ccGet.setBody(
  545. "{ int n1 = java.lang.Integer#valueOf(1); " +
  546. " int n2 = java.lang.Integer#valueOf(2); " +
  547. " int n3 = java.lang.Integer#valueOf(3); " +
  548. " int n4 = java.lang.Integer#valueOf(4); " +
  549. " int n5 = java.lang.Integer#valueOf(5); " +
  550. " return n1+n2+n3+n4+n5; }");
  551. }
  552. long endTime = System.currentTimeMillis();
  553. for(int replace=0; replace<1000; replace++) {
  554. ccGet.setBody(
  555. "{ int n1 = java.lang.Integer.valueOf(1); " +
  556. " int n2 = java.lang.Integer.valueOf(2); " +
  557. " int n3 = java.lang.Integer.valueOf(3); " +
  558. " int n4 = java.lang.Integer.valueOf(4); " +
  559. " int n5 = java.lang.Integer.valueOf(5); " +
  560. " return n1+n2+n3+n4+n5; }");
  561. }
  562. long endTime2 = System.currentTimeMillis();
  563. for(int replace=0; replace<1000; replace++) {
  564. ccGet.setBody(
  565. "{ int n1 = Integer.valueOf(1); " +
  566. " int n2 = Integer.valueOf(2); " +
  567. " int n3 = Integer.valueOf(3); " +
  568. " int n4 = Integer.valueOf(4); " +
  569. " int n5 = Integer.valueOf(5); " +
  570. " return n1+n2+n3+n4+n5; }");
  571. }
  572. long endTime3 = System.currentTimeMillis();
  573. long t1 = endTime - startTime;
  574. long t2 = endTime2 - endTime;
  575. long t3 = endTime3 - endTime2;
  576. System.out.println("JIRA150: " + t1 + ", " + t2 + ", " + t3);
  577. assertTrue(t2 < t1 * 2);
  578. assertTrue(t3 < t1 * 2);
  579. }
  580. public void testJIRA150b() throws Exception {
  581. int N = 100;
  582. for (int k = 0; k < N; k++) {
  583. ClassPool pool = new ClassPool(true);
  584. for(int paths=0; paths<50; paths++) {
  585. pool.appendClassPath(JAVASSIST_JAR);
  586. pool.appendClassPath(CLASSES_FOLDER);
  587. pool.appendClassPath(TEST_CLASSES_FOLDER);
  588. }
  589. CtClass cc = pool.get("Jassist150$Inner1");
  590. CtMethod ccGet = cc.getDeclaredMethod("get");
  591. for(int replace=0; replace < 5; replace++) {
  592. ccGet.setBody(
  593. "{ int n1 = java.lang.Integer#valueOf(1); " +
  594. " int n2 = java.lang.Integer#valueOf(2); " +
  595. " int n3 = java.lang.Integer#valueOf(3); " +
  596. " int n4 = java.lang.Integer#valueOf(4); " +
  597. " int n5 = java.lang.Integer#valueOf(5); " +
  598. " return n1+n2+n3+n4+n5; }");
  599. }
  600. }
  601. System.gc();
  602. int size = javassist.compiler.MemberResolver.getInvalidMapSize();
  603. System.out.println("JIRA150b " + size);
  604. assertTrue(size < N - 10);
  605. }
  606. }