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 46KB

11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  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.HashSet;
  7. import org.junit.FixMethodOrder;
  8. import org.junit.runners.MethodSorters;
  9. import javassist.bytecode.*;
  10. import javassist.bytecode.annotation.Annotation;
  11. import javassist.expr.*;
  12. @SuppressWarnings({"rawtypes","unchecked","unused"})
  13. @FixMethodOrder(MethodSorters.NAME_ASCENDING)
  14. public class JvstTest4 extends JvstTestRoot {
  15. public JvstTest4(String name) {
  16. super(name);
  17. }
  18. public void testInsertLocalVars() throws Exception {
  19. CtClass cc = sloader.get("test4.LocalVars");
  20. CtMethod m1 = cc.getDeclaredMethod("run");
  21. m1.getMethodInfo().getCodeAttribute().insertLocalVar(2, 20);
  22. m1.getMethodInfo().rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile());
  23. CtMethod m2 = cc.getDeclaredMethod("run2");
  24. m2.getMethodInfo().getCodeAttribute().insertLocalVar(2, 0x101);
  25. m2.getMethodInfo().rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile());
  26. cc.writeFile();
  27. Object obj = make(cc.getName());
  28. assertEquals(10, invoke(obj, "run"));
  29. assertEquals(10, invoke(obj, "run2"));
  30. }
  31. public void testCodeConv() throws Exception {
  32. CtClass cc = sloader.get("test4.CodeConv");
  33. CtMethod m1 = cc.getDeclaredMethod("m1");
  34. CtMethod m2 = cc.getDeclaredMethod("m2");
  35. CtMethod m3 = cc.getDeclaredMethod("m3");
  36. CodeConverter conv = new CodeConverter();
  37. conv.insertAfterMethod(m1, m3);
  38. conv.insertBeforeMethod(m2, m3);
  39. cc.instrument(conv);
  40. cc.writeFile();
  41. Object obj = make(cc.getName());
  42. assertEquals(111033, invoke(obj, "run"));
  43. }
  44. public void testCodeConv2() throws Exception {
  45. CtClass cc = sloader.get("test4.CodeConv2");
  46. CtField f = cc.getDeclaredField("field");
  47. CtField f2 = cc.getDeclaredField("sf");
  48. CtMethod run = cc.getDeclaredMethod("run");
  49. CodeConverter conv = new CodeConverter();
  50. conv.replaceFieldRead(f, cc, "read");
  51. conv.replaceFieldWrite(f, cc, "write");
  52. conv.replaceFieldRead(f2, cc, "read");
  53. conv.replaceFieldWrite(f2, cc, "write");
  54. run.instrument(conv);
  55. cc.writeFile();
  56. Object obj = make(cc.getName());
  57. assertEquals(14001600, invoke(obj, "run"));
  58. }
  59. public void testInsGap() throws Exception {
  60. CtClass cc = sloader.get("test4.GapSwitch");
  61. ExprEditor ed = new ExprEditor() {
  62. public void edit(MethodCall c) throws CannotCompileException {
  63. c.replace("{ value++; $_ = $proceed($$); }");
  64. }
  65. };
  66. CtMethod m1 = cc.getDeclaredMethod("run");
  67. m1.instrument(ed);
  68. CtMethod m2 = cc.getDeclaredMethod("run2");
  69. m2.instrument(ed);
  70. final CtMethod m3 = cc.getDeclaredMethod("run3");
  71. m3.instrument(new ExprEditor() {
  72. public void edit(MethodCall c) throws CannotCompileException {
  73. CodeIterator it = m3.getMethodInfo().getCodeAttribute().iterator();
  74. try {
  75. it.insertGap(c.indexOfBytecode(), 5000);
  76. } catch (BadBytecode e) {
  77. throw new CannotCompileException(e);
  78. }
  79. }
  80. });
  81. m3.getMethodInfo().rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile());
  82. cc.writeFile();
  83. Object obj = make(cc.getName());
  84. assertEquals(1010, invoke(obj, "run"));
  85. assertEquals(1100, invoke(obj, "run2"));
  86. assertEquals(12222, invoke(obj, "run3"));
  87. }
  88. public void testAnnotationCheck() throws Exception {
  89. CtClass cc = sloader.get("test4.Anno");
  90. CtMethod m1 = cc.getDeclaredMethod("foo");
  91. CtField f = cc.getDeclaredField("value");
  92. assertTrue(cc.hasAnnotation(test4.Anno1.class));
  93. assertFalse(cc.hasAnnotation(java.lang.annotation.Documented.class));
  94. assertTrue(cc.hasAnnotation(test4.Anno1.class.getName()));
  95. assertFalse(cc.hasAnnotation(java.lang.annotation.Documented.class.getName()));
  96. assertEquals("empty", ((test4.Anno1)cc.getAnnotation(test4.Anno1.class)).value());
  97. assertNull(cc.getAnnotation(Deprecated.class));
  98. assertTrue(m1.hasAnnotation(test4.Anno1.class));
  99. assertFalse(m1.hasAnnotation(java.lang.annotation.Documented.class));
  100. assertTrue(m1.getAnnotation(test4.Anno1.class) != null);
  101. assertNull(m1.getAnnotation(Deprecated.class));
  102. assertTrue(f.hasAnnotation(test4.Anno1.class));
  103. assertFalse(f.hasAnnotation(java.lang.annotation.Documented.class));
  104. assertTrue(f.getAnnotation(test4.Anno1.class) != null);
  105. assertNull(f.getAnnotation(Deprecated.class));
  106. }
  107. public void testRename() throws Exception {
  108. CtClass cc = sloader.get("test4.Rename");
  109. cc.setName("test4.Rename2");
  110. cc.rebuildClassFile();
  111. cc.writeFile();
  112. CtClass cc2 = sloader.get("test4.IRename");
  113. cc2.replaceClassName("test4.Rename", "test4.Rename2");
  114. cc2.rebuildClassFile();
  115. cc2.writeFile();
  116. Object obj = make(cc.getName());
  117. assertEquals("test4.Rename2", obj.getClass().getName());
  118. assertEquals(14, invoke(obj, "run"));
  119. }
  120. public void testRename2() throws Exception {
  121. CtClass cc = sloader.get("test4.Signature");
  122. cc.setName("test4.Sig");
  123. cc.rebuildClassFile();
  124. cc.writeFile();
  125. Object obj = make(cc.getName());
  126. assertEquals(3, invoke(obj, "run"));
  127. }
  128. public void testJIRA93() throws Exception {
  129. ClassPool cp = ClassPool.getDefault();
  130. CtClass cc = sloader.getCtClass("test4.JIRA93");
  131. CtMethod m = cc.getDeclaredMethod("foo");
  132. m.addLocalVariable("bar", CtClass.longType);
  133. // The original bug report includes the next line.
  134. // But this is not a bug.
  135. //m.insertAfter("bar;", true);
  136. // Instead, the following code is OK.
  137. m.insertBefore("bar = 0;");
  138. m.insertAfter("bar;", false);
  139. cc.writeFile();
  140. Object obj = make(cc.getName());
  141. }
  142. public void testNewRemover() throws Exception {
  143. CtClass cc = sloader.get("test4.NewRemover");
  144. CtMethod mth = cc.getDeclaredMethod("make");
  145. mth.getMethodInfo().rebuildStackMap(cc.getClassPool());
  146. mth.getMethodInfo().rebuildStackMapForME(cc.getClassPool());
  147. //cc.debugWriteFile("debug");
  148. CodeConverter conv = new CodeConverter();
  149. conv.replaceNew(cc, cc, "make2");
  150. mth.instrument(conv);
  151. cc.writeFile();
  152. Object obj = make(cc.getName());
  153. assertEquals(10, invoke(obj, "run"));
  154. }
  155. public void testClassFileWriter() throws Exception {
  156. ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0);
  157. ClassFileWriter.ConstPoolWriter cpw = cfw.getConstPool();
  158. ClassFileWriter.FieldWriter fw = cfw.getFieldWriter();
  159. fw.add(AccessFlag.PUBLIC, "value", "J", null);
  160. fw.add(AccessFlag.PROTECTED | AccessFlag.STATIC, "value2", "Ljava/lang/String;", null);
  161. ClassFileWriter.MethodWriter mw = cfw.getMethodWriter();
  162. mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, null);
  163. assertEquals(0, mw.size());
  164. mw.add(Opcode.ALOAD_0);
  165. assertEquals(1, mw.size());
  166. mw.addInvoke(Opcode.INVOKESPECIAL, "java/lang/Object", MethodInfo.nameInit, "()V");
  167. mw.add(Opcode.RETURN);
  168. mw.codeEnd(1, 1);
  169. mw.end(null, null);
  170. mw.begin(AccessFlag.PUBLIC, "move", "(II)V", null, null);
  171. assertEquals(0, mw.size());
  172. mw.add(Opcode.ALOAD_0);
  173. mw.addInvoke(Opcode.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
  174. assertEquals(4, mw.size());
  175. mw.add(Opcode.POP);
  176. mw.add(Opcode.RETURN);
  177. mw.add(Opcode.POP);
  178. mw.add(Opcode.RETURN);
  179. mw.codeEnd(1, 3);
  180. mw.addCatch(0, 4, 6, cpw.addClassInfo("java/lang/Exception"));
  181. mw.addCatch(0, 4, 6, cpw.addClassInfo("java/lang/Throwable"));
  182. mw.end(null, null);
  183. String[] exceptions = { "java/lang/Exception", "java/lang/NullPointerException" };
  184. mw.begin(AccessFlag.PUBLIC, "move2", "()V", exceptions, null);
  185. mw.add(Opcode.RETURN);
  186. mw.codeEnd(0, 1);
  187. StackMapTable.Writer stack = new StackMapTable.Writer(32);
  188. stack.sameFrame(1);
  189. mw.end(stack, null);
  190. mw.begin(AccessFlag.PUBLIC, "foo", "()I", null, null);
  191. mw.add(Opcode.ICONST_2);
  192. mw.add(Opcode.IRETURN);
  193. mw.codeEnd(1, 1);
  194. mw.end(null, null);
  195. byte[] out = cfw.end(AccessFlag.PUBLIC, cpw.addClassInfo("test4/WrittenFile"),
  196. cpw.addClassInfo("java/lang/Object"),
  197. null, null);
  198. FileOutputStream fos = new FileOutputStream("test4/WrittenFile.class");
  199. fos.write(out);
  200. fos.close();
  201. Object obj = make("test4.WrittenFile");
  202. assertNotNull(obj);
  203. assertEquals(2, invoke(obj, "foo"));
  204. }
  205. public void testClassFileWriter2() throws Exception {
  206. ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0);
  207. ClassFileWriter.ConstPoolWriter cpw = cfw.getConstPool();
  208. ClassFileWriter.FieldWriter fw = cfw.getFieldWriter();
  209. fw.add(AccessFlag.PUBLIC | AccessFlag.STATIC, "value", "I", null);
  210. ClassFileWriter.MethodWriter mw = cfw.getMethodWriter();
  211. mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, null);
  212. mw.add(Opcode.ALOAD_0);
  213. mw.addInvoke(Opcode.INVOKESPECIAL, "java/lang/Object", MethodInfo.nameInit, "()V");
  214. mw.add(Opcode.RETURN);
  215. mw.codeEnd(1, 1);
  216. mw.end(null, null);
  217. String[] exceptions = { "java/lang/Exception" };
  218. mw.begin(AccessFlag.PUBLIC | AccessFlag.ABSTRACT, "move", "(II)V", exceptions, null);
  219. mw.end(null, null);
  220. int thisClass = cpw.addClassInfo("test4/WrittenFile2");
  221. int superClass = cpw.addClassInfo("java/lang/Object");
  222. cfw.end(new DataOutputStream(new FileOutputStream("test4/WrittenFile2.class")),
  223. AccessFlag.PUBLIC | AccessFlag.ABSTRACT, thisClass, superClass,
  224. null, null);
  225. File f = new File("test4/WrittenFile2.class");
  226. byte[] file = new byte[(int)f.length()];
  227. FileInputStream fis = new FileInputStream(f);
  228. fis.read(file);
  229. fis.close();
  230. byte[] out = cfw.end(AccessFlag.PUBLIC | AccessFlag.ABSTRACT, thisClass,
  231. superClass, null, null);
  232. assertEquals(out.length, file.length);
  233. for (int i = 0; i < out.length; i++)
  234. assertEquals(out[i], file[i]);
  235. CtClass sub = dloader.makeClass("test4.WrittenFile2sub", dloader.get("test4.WrittenFile2"));
  236. sub.addMethod(CtMethod.make("public void move(int i, int j) {}", sub));
  237. sub.addMethod(CtMethod.make("public int foo() { move(0, 1); return 1; }", sub));
  238. sub.writeFile();
  239. Object obj = make("test4.WrittenFile2sub");
  240. assertEquals(1, invoke(obj, "foo"));
  241. }
  242. public void testClassFileWriter3() throws Exception {
  243. ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0);
  244. ClassFileWriter.ConstPoolWriter cpw = cfw.getConstPool();
  245. int superClass = cpw.addClassInfo("java/lang/Object");
  246. final int syntheticTag = cpw.addUtf8Info("Synthetic");
  247. ClassFileWriter.AttributeWriter attribute = new ClassFileWriter.AttributeWriter() {
  248. public void write(DataOutputStream out) throws java.io.IOException {
  249. out.writeShort(syntheticTag);
  250. out.writeInt(0);
  251. }
  252. public int size() {
  253. return 1;
  254. }
  255. };
  256. ClassFileWriter.FieldWriter fw = cfw.getFieldWriter();
  257. fw.add(AccessFlag.PUBLIC, "value", "J", null);
  258. fw.add(AccessFlag.PROTECTED | AccessFlag.STATIC, "value2", "Ljava/lang/String;", attribute);
  259. ClassFileWriter.MethodWriter mw = cfw.getMethodWriter();
  260. mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, attribute);
  261. mw.add(Opcode.ALOAD_0);
  262. mw.add(Opcode.INVOKESPECIAL);
  263. mw.add16(cpw.addMethodrefInfo(superClass, cpw.addNameAndTypeInfo(MethodInfo.nameInit, "()V")));
  264. // mw.addInvoke(Opcode.INVOKESPECIAL, "java/lang/Object", MethodInfo.nameInit, "()V");
  265. mw.add(Opcode.RETURN);
  266. mw.codeEnd(1, 1);
  267. mw.end(null, null);
  268. mw.begin(AccessFlag.PUBLIC, "foo", "()I", null, attribute);
  269. mw.add(Opcode.ICONST_2);
  270. mw.add(Opcode.IRETURN);
  271. mw.codeEnd(1, 1);
  272. mw.end(null, null);
  273. int thisClass = cpw.addClassInfo("test4/WrittenFile3");
  274. cfw.end(new DataOutputStream(new FileOutputStream("test4/WrittenFile3.class")),
  275. AccessFlag.PUBLIC, thisClass, superClass,
  276. null, attribute);
  277. File f = new File("test4/WrittenFile3.class");
  278. byte[] file = new byte[(int)f.length()];
  279. FileInputStream fis = new FileInputStream(f);
  280. fis.read(file);
  281. fis.close();
  282. byte[] out = cfw.end(AccessFlag.PUBLIC, thisClass, superClass,
  283. null, attribute);
  284. assertEquals(out.length, file.length);
  285. for (int i = 0; i < out.length; i++)
  286. assertEquals(out[i], file[i]);
  287. Object obj = make("test4.WrittenFile3");
  288. assertNotNull(obj);
  289. assertEquals(2, invoke(obj, "foo"));
  290. }
  291. public void testCtArray() throws Exception {
  292. CtClass cc = sloader.get("int");
  293. assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers());
  294. cc = sloader.get("int[]");
  295. assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers());
  296. cc = sloader.get("java.lang.String[]");
  297. assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers());
  298. CtClass[] intfs = cc.getInterfaces();
  299. assertEquals(Cloneable.class.getName(), intfs[0].getName());
  300. assertEquals(java.io.Serializable.class.getName(), intfs[1].getName());
  301. cc = sloader.get("test4.CtArrayTest[]");
  302. assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers());
  303. }
  304. public void testAnalysisType() throws Exception {
  305. testAnalysisType2(sloader.get("int[]"), 1);
  306. testAnalysisType2(sloader.get("java.lang.String[][]"), 2);
  307. sloader.makeClass("A");
  308. testAnalysisType2(sloader.getCtClass("A"), 0);
  309. testAnalysisType2(sloader.getCtClass("A[]"), 1);
  310. testAnalysisType2(sloader.getCtClass("A[][]"), 2);
  311. }
  312. private void testAnalysisType2(CtClass cc, int size) throws Exception {
  313. javassist.bytecode.analysis.Type t = javassist.bytecode.analysis.Type.get(cc);
  314. assertEquals(cc.getName(), size, t.getDimensions());
  315. }
  316. public void testArrayType() throws Exception {
  317. CtClass at = sloader.get("java.lang.Object[]");
  318. CtClass[] intfs = at.getInterfaces();
  319. assertEquals(intfs.length, 2);
  320. assertEquals(intfs[0].getName(), java.lang.Cloneable.class.getName());
  321. assertEquals(intfs[1].getName(), java.io.Serializable.class.getName());
  322. assertTrue(at.subtypeOf(sloader.get(java.lang.Object.class.getName())));
  323. assertTrue(at.subtypeOf(intfs[0]));
  324. assertTrue(at.subtypeOf(intfs[1]));
  325. assertTrue(at.subtypeOf(intfs[1]));
  326. CtClass subt = sloader.get(java.text.CharacterIterator.class.getName());
  327. assertFalse(at.subtypeOf(subt));
  328. }
  329. public void testGetFieldDesc() throws Exception {
  330. CtClass cc = sloader.get("test4.GetFieldDesc");
  331. cc.getDeclaredField("f", "I");
  332. cc.getField("s", "Ljava/lang/String;");
  333. CtClass cc2 = sloader.get("test4.GetFieldDescSub");
  334. assertEquals(cc2.getField("s", "Ljava/lang/String;").getDeclaringClass().getName(),
  335. "test4.GetFieldDesc");
  336. assertEquals(cc2.getField("s", "I").getDeclaringClass().getName(),
  337. "test4.GetFieldDescSub");
  338. }
  339. public void testMakeMethod() throws CannotCompileException {
  340. CtClass ctClass = sloader.makeClass("test4.MakeMethod2");
  341. CtNewMethod.make("public String foox(){return test4.MakeMethod.foo();}", ctClass);
  342. CtNewMethod.make("public String foo(){return test4.MakeMethod.foo();}", ctClass);
  343. }
  344. public void testVarArgs() throws Exception {
  345. CtClass cc = sloader.get("test4.VarArgs");
  346. CtMethod m = CtMethod.make("public int foo(int i, String[] args) { return args.length; }", cc);
  347. m.setModifiers(m.getModifiers() | Modifier.VARARGS);
  348. cc.addMethod(m);
  349. m = CtMethod.make("public int run() { return goo(7, new int[] { 1, 2, 3 }); }", cc);
  350. cc.addMethod(m);
  351. cc.writeFile();
  352. Object obj = make(cc.getName());
  353. assertEquals(3, invoke(obj, "run"));
  354. }
  355. public void testGetAllRef() throws Exception {
  356. CtClass cc = sloader.get("test4.GetAllRef");
  357. ClassFile cf = cc.getClassFile();
  358. AttributeInfo ainfo
  359. = cf.getAttribute(AnnotationsAttribute.visibleTag);
  360. ClassMap map = new ClassMap();
  361. map.put("test4.GetAllRefAnno", "test4.GetAllRefAnno2");
  362. map.put("test4.GetAllRefEnum", "test4.GetAllRefEnum2");
  363. map.put("java.lang.String", "java.lang.StringBuilder");
  364. cf.addAttribute(ainfo.copy(cf.getConstPool(), map));
  365. cc.writeFile();
  366. cc.detach();
  367. cc = dloader.get(cc.getName());
  368. test4.GetAllRefAnno2 anno
  369. = (test4.GetAllRefAnno2)cc.getAnnotation(test4.GetAllRefAnno2.class);
  370. assertEquals(test4.GetAllRefEnum2.A, anno.getA());
  371. assertEquals(StringBuilder.class, anno.getC());
  372. }
  373. public void testGetAllRefB() throws Exception {
  374. CtClass cc = sloader.get("test4.GetAllRefB");
  375. ClassMap map = new ClassMap();
  376. map.put("test4.GetAllRefAnno", "test4.GetAllRefAnno2");
  377. map.put("test4.GetAllRefEnum", "test4.GetAllRefEnum2");
  378. map.put("java.lang.String", "java.lang.StringBuilder");
  379. cc.replaceClassName(map);
  380. //cc.replaceClassName("test4.GetAllRefAnno", "test4.GetAllRefAnno2");
  381. cc.writeFile();
  382. cc = dloader.get(cc.getName());
  383. test4.GetAllRefAnno2 anno
  384. = (test4.GetAllRefAnno2)cc.getAnnotation(test4.GetAllRefAnno2.class);
  385. assertEquals(test4.GetAllRefEnum2.A, anno.getA());
  386. assertEquals(StringBuilder.class, anno.getC());
  387. /*
  388. AnnotationsAttribute aainfo = (AnnotationsAttribute)
  389. cc.getClassFile().getAttribute(AnnotationsAttribute.visibleTag);
  390. Annotation[] a = aainfo.getAnnotations();
  391. System.err.println(a[0].getTypeName());
  392. System.err.println(a[0]);
  393. */
  394. }
  395. public void testGetAllRefC() throws Exception {
  396. CtClass cc = sloader.get("test4.GetAllRefC");
  397. HashSet set = new HashSet();
  398. set.add("java.lang.Object");
  399. set.add("java.lang.String");
  400. set.add("test4.GetAllRefC");
  401. set.add("test4.GetAllRefAnno");
  402. set.add("test4.GetAllRefEnum");
  403. set.add("test4.GetAllRefAnnoC");
  404. set.add("test4.GetAllRefAnnoC2");
  405. set.add("test4.GetAllRefAnnoC3");
  406. set.add("test4.GetAllRefAnnoC4");
  407. java.util.Collection<String> refs
  408. = (java.util.Collection<String>)cc.getRefClasses();
  409. assertEquals(set.size(), refs.size());
  410. for (String s: refs) {
  411. assertTrue(set.contains(s));
  412. }
  413. }
  414. public void testGetAllRefInner() throws Exception {
  415. HashSet set = new HashSet();
  416. set.add("java.lang.Object");
  417. set.add("test4.GetAllRefInnerTest");
  418. set.add("test4.GetAllRefInnerTest$1");
  419. set.add("test4.GetAllRefInnerTest$2");
  420. CtClass cc = sloader.get("test4.GetAllRefInnerTest");
  421. int size = 0;
  422. for (Object s: cc.getRefClasses()) {
  423. assertTrue((String)s, set.contains(s));
  424. ++size;
  425. }
  426. assertEquals(set.size(), size);
  427. }
  428. public void testNestedClass() throws Exception {
  429. CtClass cc = sloader.get("test4.NestedClass$1");
  430. CtClass[] tab = cc.getNestedClasses();
  431. assertEquals(1, tab.length);
  432. assertEquals("test4.NestedClass$1$1", tab[0].getName());
  433. cc = sloader.get("test4.NestedClass$1$1");
  434. tab = cc.getNestedClasses();
  435. assertEquals(0, tab.length);
  436. cc = sloader.get("test4.NestedClass");
  437. tab = cc.getNestedClasses();
  438. for (CtClass c: tab) {
  439. System.err.println(c.getName());
  440. }
  441. // Eclipse compiler sets tab.length to 4 but javac sets to 3.
  442. assertTrue(tab.length == 4 || tab.length == 3);
  443. for (CtClass c: tab) {
  444. String name = c.getName();
  445. assertTrue(name.equals("test4.NestedClass$N")
  446. || name.equals("test4.NestedClass$S")
  447. || name.equals("test4.NestedClass$1")
  448. || name.equals("test4.NestedClass$1In"));
  449. }
  450. cc = sloader.get("test4.NestedClass$1In");
  451. tab = cc.getNestedClasses();
  452. assertEquals(0, tab.length);
  453. }
  454. public void testGetClasses() throws Exception {
  455. CtClass cc = sloader.get("test4.NestedClass");
  456. CtClass[] tab = cc.getDeclaredClasses();
  457. // Eclipse compiler sets tab.length to 4 but javac sets to 3.
  458. assertTrue(tab.length == 4 || tab.length == 3);
  459. for (CtClass c: tab) {
  460. String name = c.getName();
  461. assertTrue(name.equals("test4.NestedClass$N")
  462. || name.equals("test4.NestedClass$S")
  463. || name.equals("test4.NestedClass$1")
  464. || name.equals("test4.NestedClass$1In"));
  465. }
  466. cc = sloader.get("test4.NestedClass$1In");
  467. tab = cc.getDeclaredClasses();
  468. assertEquals(0, tab.length);
  469. }
  470. public void testImportPac() throws Exception {
  471. CtClass cc = sloader.makeClass("test4.TestImpP");
  472. sloader.importPackage("test4.NewImportPac");
  473. try {
  474. cc.addMethod(CtNewMethod.make(
  475. "public int foo(){ " +
  476. " ImportPac obj = new ImportPac();" +
  477. " return obj.getClass().getName().length(); }", cc));
  478. fail("ImportPac was found");
  479. }
  480. catch (CannotCompileException e) {}
  481. cc.addMethod(CtNewMethod.make(
  482. "public int bar(){ " +
  483. " NewImportPac obj = new NewImportPac();" +
  484. " return obj.getClass().getName().length(); }", cc));
  485. sloader.clearImportedPackages();
  486. }
  487. public void testLength() throws Exception {
  488. CtClass cc = sloader.makeClass("test4.LengthTest");
  489. cc.addMethod(CtNewMethod.make(
  490. "public int len(String s){ " +
  491. " return s.length(); }", cc));
  492. cc.addField(CtField.make("int length = 100;", cc));
  493. cc.addConstructor(CtNewConstructor.defaultConstructor(cc));
  494. cc.addMethod(CtNewMethod.make(
  495. "public int run(){ " +
  496. " test4.LengthTest t = new test4.LengthTest();" +
  497. " return len(\"foo\") + t.length + test4.length.m(); }", cc));
  498. try {
  499. cc.addMethod(CtNewMethod.make(
  500. "public int run(){ " +
  501. " return test4no.length.m(); }", cc));
  502. fail("test4no was found!");
  503. }
  504. catch (CannotCompileException e) {
  505. System.out.println(e);
  506. }
  507. cc.writeFile();
  508. Object obj = make(cc.getName());
  509. assertEquals(110, invoke(obj, "run"));
  510. }
  511. public void testAaload() throws Exception {
  512. CtClass clazz = sloader.get("test4.Aaload");
  513. CtMethod method = clazz.getMethod("narf", "()V");
  514. method.instrument(new ExprEditor() {
  515. @Override
  516. public void edit(MethodCall call) throws CannotCompileException {
  517. String name = call.getMethodName();
  518. if (name.equals("addActionListener"))
  519. call.replace("$0." + name + "($$);");
  520. }
  521. });
  522. }
  523. @SuppressWarnings("deprecation")
  524. public void testMakePackage() throws Exception {
  525. if (ClassFile.MAJOR_VERSION >= ClassFile.JAVA_9) {
  526. ClassPool pool = ClassPool.getDefault();
  527. try {
  528. pool.makePackage(pool.getClassLoader(), "test4.pack2");
  529. fail("makePackage() ran");
  530. }
  531. catch (CannotCompileException e) {}
  532. }
  533. }
  534. @SuppressWarnings("deprecation")
  535. public void testPackage() throws Throwable { // JASSIST-147
  536. String packageName = "test4.pack";
  537. ClassPool pool = ClassPool.getDefault();
  538. try {
  539. pool.makePackage(pool.getClassLoader(), packageName);
  540. pool.makePackage(pool.getClassLoader(), packageName);
  541. }
  542. catch (CannotCompileException e) {
  543. if (ClassFile.MAJOR_VERSION >= ClassFile.JAVA_9)
  544. return; // makePackage() does not work in Java 9.
  545. }
  546. CtClass ctcl = pool.makeClass("test4.pack.Clazz");
  547. Class cl = ctcl.toClass();
  548. Object obj = cl.getConstructor().newInstance();
  549. assertEquals(packageName, obj.getClass().getPackage().getName());
  550. }
  551. public static final String BASE_PATH = "../../";
  552. public static final String JAVASSIST_JAR = BASE_PATH + "javassist.jar";
  553. public static final String CLASSES_FOLDER = BASE_PATH + "build/classes";
  554. public static final String TEST_CLASSES_FOLDER = BASE_PATH + "build/test-classes";
  555. public static class Inner1 {
  556. public static int get() {
  557. return 0;
  558. }
  559. }
  560. public void testJIRA150() throws Exception {
  561. ClassPool pool = new ClassPool(true);
  562. for(int paths=0; paths<50; paths++) {
  563. pool.appendClassPath(JAVASSIST_JAR);
  564. pool.appendClassPath(CLASSES_FOLDER);
  565. pool.appendClassPath(TEST_CLASSES_FOLDER);
  566. }
  567. CtClass cc = pool.get("Jassist150$Inner1");
  568. CtMethod ccGet = cc.getDeclaredMethod("get");
  569. long startTime = System.currentTimeMillis();
  570. for(int replace=0; replace<1000; replace++) {
  571. ccGet.setBody(
  572. "{ int n1 = java.lang.Integer#valueOf(1); " +
  573. " int n2 = java.lang.Integer#valueOf(2); " +
  574. " int n3 = java.lang.Integer#valueOf(3); " +
  575. " int n4 = java.lang.Integer#valueOf(4); " +
  576. " int n5 = java.lang.Integer#valueOf(5); " +
  577. " return n1+n2+n3+n4+n5; }");
  578. }
  579. long endTime = System.currentTimeMillis();
  580. for(int replace=0; replace<1000; replace++) {
  581. ccGet.setBody(
  582. "{ int n1 = java.lang.Integer.valueOf(1); " +
  583. " int n2 = java.lang.Integer.valueOf(2); " +
  584. " int n3 = java.lang.Integer.valueOf(3); " +
  585. " int n4 = java.lang.Integer.valueOf(4); " +
  586. " int n5 = java.lang.Integer.valueOf(5); " +
  587. " return n1+n2+n3+n4+n5; }");
  588. }
  589. long endTime2 = System.currentTimeMillis();
  590. for(int replace=0; replace<1000; replace++) {
  591. ccGet.setBody(
  592. "{ int n1 = Integer.valueOf(1); " +
  593. " int n2 = Integer.valueOf(2); " +
  594. " int n3 = Integer.valueOf(3); " +
  595. " int n4 = Integer.valueOf(4); " +
  596. " int n5 = Integer.valueOf(5); " +
  597. " return n1+n2+n3+n4+n5; }");
  598. }
  599. long endTime3 = System.currentTimeMillis();
  600. long t1 = endTime - startTime;
  601. long t2 = endTime2 - endTime;
  602. long t3 = endTime3 - endTime2;
  603. System.out.println("JIRA150: " + t1 + ", " + t2 + ", " + t3);
  604. assertTrue("performance test (the next try may succeed): " + t2 + " < 6 * " + t1,
  605. t2 < t1 * 6);
  606. assertTrue("performance test (the next try may succeed): " + t3 + " < 3 * " + t1,
  607. t3 < t1 * 3);
  608. }
  609. public void testJIRA150b() throws Exception {
  610. int origSize = javassist.compiler.MemberResolver.getInvalidMapSize();
  611. int N = 100;
  612. for (int k = 0; k < N; k++) {
  613. ClassPool pool = new ClassPool(true);
  614. for(int paths=0; paths<50; paths++) {
  615. pool.appendClassPath(JAVASSIST_JAR);
  616. pool.appendClassPath(CLASSES_FOLDER);
  617. pool.appendClassPath(TEST_CLASSES_FOLDER);
  618. }
  619. CtClass cc = pool.get("Jassist150$Inner1");
  620. CtMethod ccGet = cc.getDeclaredMethod("get");
  621. for(int replace=0; replace < 5; replace++) {
  622. ccGet.setBody(
  623. "{ int n1 = java.lang.Integer#valueOf(1); " +
  624. " int n2 = java.lang.Integer#valueOf(2); " +
  625. " int n3 = java.lang.Integer#valueOf(3); " +
  626. " int n4 = java.lang.Integer#valueOf(4); " +
  627. " int n5 = java.lang.Integer#valueOf(5); " +
  628. " return n1+n2+n3+n4+n5; }");
  629. }
  630. pool = null;
  631. }
  632. // try to run garbage collection.
  633. int[][] mem = new int[100][];
  634. int[] large;
  635. for (int i = 0; i < 100; i++) {
  636. large = new int[1000000];
  637. large[large.length - 2] = 9 + i;
  638. mem[i] = large;
  639. }
  640. System.gc();
  641. System.gc();
  642. int size = javassist.compiler.MemberResolver.getInvalidMapSize();
  643. System.out.println("JIRA150b " + size + " " + mem[mem.length - 1][mem[0].length - 2]);
  644. // Now this seems obsolete.
  645. // assertTrue("JIRA150b size: " + origSize + " " + size, size < origSize + N);
  646. }
  647. public void testJIRA152() throws Exception {
  648. CtClass cc = sloader.get("test4.JIRA152");
  649. CtMethod mth = cc.getDeclaredMethod("buildColumnOverride");
  650. //CtMethod mth = cc.getDeclaredMethod("tested");
  651. mth.instrument(new ExprEditor() {
  652. public void edit(MethodCall c) throws CannotCompileException {
  653. c.replace("try{ $_ = $proceed($$); } catch (Throwable t) { throw t; }");
  654. }
  655. });
  656. cc.writeFile();
  657. Object obj = make(cc.getName());
  658. assertEquals(1, invoke(obj, "test"));
  659. }
  660. public void testJIRA151() {
  661. // try it using classloader of TestDescForName Desc.useContextClassLoader = false;
  662. assertTrue(javassist.runtime.Desc.getClazz("[Ljava.lang.String;") != null);
  663. //Thread.currentThread().setContextClassLoader(TestDescForName.class.getClassLoader());
  664. boolean old = javassist.runtime.Desc.useContextClassLoader;
  665. javassist.runtime.Desc.useContextClassLoader = true;
  666. assertTrue(javassist.runtime.Desc.getClazz("[Ljava.lang.String;") != null);
  667. javassist.runtime.Desc.useContextClassLoader = old;
  668. }
  669. public void testJIRA166() throws Exception {
  670. CtClass cc = sloader.get("test4.JIRA166");
  671. cc.instrument(new ExprEditor() {
  672. public void edit(FieldAccess fa) throws CannotCompileException {
  673. if (fa.isReader() && fa.getFieldName().equals("length"))
  674. fa.replace("length = self().length + \"!\"; $_ = ($r) this.length.substring(1);");
  675. }
  676. });
  677. cc.writeFile();
  678. Object obj = make(cc.getName());
  679. assertEquals(1, invoke(obj, "run"));
  680. }
  681. public void testGenericSignature() throws Exception {
  682. CtClass cc = sloader.makeClass("test4.GenSig");
  683. CtClass objClass = sloader.get(CtClass.javaLangObject);
  684. SignatureAttribute.ClassSignature cs
  685. = new SignatureAttribute.ClassSignature(
  686. new SignatureAttribute.TypeParameter[] {
  687. new SignatureAttribute.TypeParameter("T") });
  688. cc.setGenericSignature(cs.encode()); // <T:Ljava/lang/Object;>Ljava/lang/Object;
  689. CtField f = new CtField(objClass, "value", cc);
  690. SignatureAttribute.TypeVariable tvar = new SignatureAttribute.TypeVariable("T");
  691. f.setGenericSignature(tvar.encode()); // TT;
  692. cc.addField(f);
  693. CtMethod m = CtNewMethod.make("public Object get(){return value;}", cc);
  694. SignatureAttribute.MethodSignature ms
  695. = new SignatureAttribute.MethodSignature(null, null, tvar, null);
  696. m.setGenericSignature(ms.encode()); // ()TT;
  697. cc.addMethod(m);
  698. CtMethod m2 = CtNewMethod.make("public void set(Object v){value = v;}", cc);
  699. SignatureAttribute.MethodSignature ms2
  700. = new SignatureAttribute.MethodSignature(null, new SignatureAttribute.Type[] { tvar },
  701. new SignatureAttribute.BaseType("void"), null);
  702. m2.setGenericSignature(ms2.encode()); // (TT;)V;
  703. cc.addMethod(m2);
  704. cc.writeFile();
  705. Object obj = make(cc.getName());
  706. Class clazz = obj.getClass();
  707. assertEquals("T", clazz.getTypeParameters()[0].getName());
  708. assertEquals("T", ((java.lang.reflect.TypeVariable)clazz.getDeclaredField("value").getGenericType()).getName());
  709. java.lang.reflect.Method rm = clazz.getDeclaredMethod("get", new Class[0]);
  710. assertEquals("T", ((java.lang.reflect.TypeVariable)rm.getGenericReturnType()).getName());
  711. java.lang.reflect.Method rm2 = clazz.getDeclaredMethod("set", new Class[] { Object.class });
  712. assertEquals("T", ((java.lang.reflect.TypeVariable)rm2.getGenericParameterTypes()[0]).getName());
  713. }
  714. public void testJIRA171() throws Exception {
  715. SignatureAttribute.MethodSignature ms
  716. = SignatureAttribute.toMethodSignature("(Ljava/lang/Object;Lorg/apache/hadoop/io/Text;"
  717. + "Lorg/apache/hadoop/mapreduce/Mapper<Ljava/lang/Object;Lorg/apache/hadoop/io/Text;"
  718. + "Lorg/apache/hadoop/io/Text;Lorg/apache/hadoop/io/IntWritable;>.Context;)V");
  719. String s = ms.toString();
  720. System.out.println(s);
  721. assertEquals("<> (java.lang.Object, org.apache.hadoop.io.Text, "
  722. + "org.apache.hadoop.mapreduce.Mapper<java.lang.Object, org.apache.hadoop.io.Text, "
  723. + "org.apache.hadoop.io.Text, org.apache.hadoop.io.IntWritable>.Context) void", s);
  724. }
  725. public void testAfter() throws Exception {
  726. CtClass cc = sloader.get("test4.AfterTest");
  727. CtMethod m1 = cc.getDeclaredMethod("m1");
  728. m1.insertAfter("print();");
  729. CtMethod m2 = cc.getDeclaredMethod("m2");
  730. m2.insertAfter("print();");
  731. CtMethod m3 = cc.getDeclaredMethod("m3");
  732. m3.insertAfter("print();");
  733. CtMethod m4 = cc.getDeclaredMethod("m4");
  734. m4.insertAfter("print();");
  735. CtMethod mm1 = cc.getDeclaredMethod("mm1");
  736. mm1.insertAfter("print();", true);
  737. CtMethod mm2 = cc.getDeclaredMethod("mm2");
  738. mm2.insertAfter("print();", true);
  739. CtMethod mm3 = cc.getDeclaredMethod("mm3");
  740. mm3.insertAfter("print();", true);
  741. CtMethod mm4 = cc.getDeclaredMethod("mm4");
  742. mm4.insertAfter("print();", true);
  743. cc.writeFile();
  744. Object obj = make(cc.getName());
  745. assertEquals(131, invoke(obj, "test1"));
  746. assertEquals(112, invoke(obj, "test2"));
  747. assertEquals(10, invoke(obj, "test3"));
  748. assertEquals(100, invoke(obj, "test4"));
  749. assertEquals(131, invoke(obj, "test11"));
  750. assertEquals(112, invoke(obj, "test22"));
  751. assertEquals(10, invoke(obj, "test33"));
  752. assertEquals(100, invoke(obj, "test44"));
  753. }
  754. public void testJIRA186() throws Exception {
  755. CtClass cc = sloader.get("test4.JIRA186");
  756. cc.getDeclaredMethod("test").insertBefore("{" +
  757. " java.util.List l = new java.util.ArrayList();" +
  758. " l.add(this.toString());" +
  759. "}");
  760. cc.writeFile();
  761. Object obj = make(cc.getName());
  762. assertEquals(1, invoke(obj, "test"));
  763. }
  764. // JASSIST-190
  765. public void testMultipleCatch() throws Exception {
  766. CtClass cc = sloader.get("test4.MultiCatch");
  767. CtMethod m1 = cc.getDeclaredMethod("m1");
  768. m1.insertAfter("print();");
  769. cc.writeFile();
  770. Object obj = make(cc.getName());
  771. assertEquals(12, invoke(obj, "test1"));
  772. }
  773. // JASSIST-185
  774. public void testLocalVariableTypeTable() throws Exception {
  775. CtClass cc = sloader.get("test4.Lvtt");
  776. CtMethod m = cc.getDeclaredMethod("run");
  777. m.addParameter(CtClass.intType);
  778. cc.writeFile();
  779. Object obj = make(cc.getName());
  780. }
  781. // JASSISt-181
  782. public void testAnnotationWithGenerics() throws Exception {
  783. CtClass cc0 = sloader.get("test4.JIRA181b");
  784. CtField field0 = cc0.getField("aField");
  785. String s0 = field0.getAnnotation(test4.JIRA181b.Condition.class).toString();
  786. assertEquals("@test4.JIRA181b$Condition(condition=java.lang.String.class)", s0);
  787. CtField field01 = cc0.getField("aField2");
  788. String s01 = field01.getAnnotation(test4.JIRA181b.Condition.class).toString();
  789. assertEquals("@test4.JIRA181b$Condition(condition=void.class)", s01);
  790. CtClass cc = sloader.get("test4.JIRA181");
  791. CtField field = cc.getField("aField");
  792. String s = field.getAnnotation(test4.JIRA181.Condition.class).toString();
  793. if (ClassFile.MAJOR_VERSION < ClassFile.JAVA_9)
  794. assertEquals("@test4.JIRA181$Condition(condition=test4.JIRA181<T>.B.class)", s);
  795. else
  796. assertEquals("@test4.JIRA181$Condition(condition=test4.JIRA181.B.class)", s);
  797. CtField field2 = cc.getField("aField2");
  798. String s2 = field2.getAnnotation(test4.JIRA181.Condition2.class).toString();
  799. if (ClassFile.MAJOR_VERSION < ClassFile.JAVA_9)
  800. assertEquals("@test4.JIRA181$Condition2(condition=test4.JIRA181<T>.B[].class)", s2);
  801. else
  802. assertEquals("@test4.JIRA181$Condition2(condition=test4.JIRA181.B[].class)", s2);
  803. }
  804. public void testJIRA195() throws Exception {
  805. CtClass cc = sloader.get("test4.JIRA195");
  806. CtMethod mth = cc.getDeclaredMethod("test");
  807. mth.getMethodInfo().rebuildStackMap(cc.getClassPool());
  808. cc.writeFile();
  809. Object obj = make(cc.getName());
  810. assertEquals(4, invoke(obj, "run"));
  811. }
  812. public void testJIRA188() throws Exception {
  813. CtClass cc = sloader.makeClass("test4.JIRA188");
  814. CtField f = new CtField(CtClass.intType, "f", cc);
  815. f.setModifiers(Modifier.PRIVATE);
  816. cc.addField(f);
  817. cc.addMethod(CtNewMethod.make(
  818. "public int getf(test4.JIRA188 p){ return p.f; }", cc));
  819. cc.detach();
  820. // System.gc();
  821. try {
  822. cc = sloader.get("test4.JIRA188");
  823. fail("test4.JIRA188 found");
  824. }
  825. catch (NotFoundException e) {}
  826. cc = sloader.makeClass("test4.JIRA188");
  827. cc.addField(new CtField(CtClass.intType, "g", cc));
  828. cc.addMethod(CtNewMethod.make(
  829. "public int getf(test4.JIRA188 p){ return p.g; }", cc));
  830. }
  831. public void testJIRA158() throws Exception {
  832. CtClass cc = sloader.get("test4.JIRA158");
  833. cc.addMethod(CtMethod.make("public int run() { return obj.foo(jj, dd) + obj.bar(j, d); }", cc));
  834. cc.writeFile();
  835. Object obj = make(cc.getName());
  836. assertEquals(15, invoke(obj, "run"));
  837. }
  838. public void testJIRA207() throws Exception {
  839. CtClass cc = sloader.get("test4.JIRA207");
  840. CtMethod cm = cc.getDeclaredMethod("foo");
  841. cm.insertBefore("throw new Exception();");
  842. CtMethod cm2 = cc.getDeclaredMethod("run2");
  843. cm2.insertBefore("throw new Exception();");
  844. cc.writeFile();
  845. Object obj = make(cc.getName());
  846. try {
  847. invoke(obj, "run2");
  848. fail("run2");
  849. }
  850. catch (Exception e) {}
  851. }
  852. public void testJIRA212() throws Exception {
  853. CtClass cc = sloader.get("test4.JIRA212");
  854. for (final CtBehavior behavior : cc.getDeclaredBehaviors()) {
  855. behavior.instrument(new ExprEditor() {
  856. public void edit(FieldAccess fieldAccess) throws CannotCompileException {
  857. String fieldName = fieldAccess.getFieldName().substring(0,1).toUpperCase() + fieldAccess.getFieldName().substring(1);
  858. if (fieldAccess.isReader()) {
  859. // Rewrite read access
  860. fieldAccess.replace("$_ = $0.get" + fieldName + "();");
  861. } else if (fieldAccess.isWriter()) {
  862. // Rewrite write access
  863. fieldAccess.replace("$0.set" + fieldName + "($1);");
  864. }
  865. }});
  866. }
  867. cc.writeFile();
  868. Object obj = make(cc.getName());
  869. }
  870. public void testWhileTrueKO() throws Exception {
  871. final ClassPool pool = ClassPool.getDefault();
  872. final CtClass cc = pool.makeClass("test4.TestWhileTrueKO");
  873. String source = "public void testWhile() { while(true) { break; } }";
  874. cc.addMethod(CtMethod.make(source, cc));
  875. cc.writeFile();
  876. make(cc.getName());
  877. }
  878. public void testWhileTrueOK() throws Exception {
  879. final ClassPool pool = ClassPool.getDefault();
  880. final CtClass cc = pool.makeClass("test4.TestWhileTrueOK");
  881. String source = "public void testWhile() { while(0==0) { break; }}";
  882. cc.addMethod(CtMethod.make(source, cc));
  883. cc.writeFile();
  884. make(cc.getName());
  885. }
  886. // JIRA JASSIST-224
  887. public void testMethodParameters() throws Exception {
  888. Class rc = test4.MethodParamTest.class;
  889. java.lang.reflect.Method m = rc.getDeclaredMethods()[0];
  890. java.lang.reflect.Parameter[] params = m.getParameters();
  891. assertEquals("i", params[0].getName());
  892. assertEquals("s", params[1].getName());
  893. CtClass cc = sloader.get("test4.MethodParamTest");
  894. ClassFile cf = cc.getClassFile2();
  895. ConstPool cp = cf.getConstPool();
  896. MethodInfo minfo = cf.getMethod("test");
  897. MethodParametersAttribute attr
  898. = (MethodParametersAttribute)minfo.getAttribute(MethodParametersAttribute.tag);
  899. assertEquals(2, attr.size());
  900. assertEquals("i", cp.getUtf8Info(attr.name(0)));
  901. assertEquals("s", cp.getUtf8Info(attr.name(1)));
  902. attr = (MethodParametersAttribute)attr.copy(cp, null);
  903. assertEquals(2, attr.size());
  904. assertEquals("i", cp.getUtf8Info(attr.name(0)));
  905. assertEquals("s", cp.getUtf8Info(attr.name(1)));
  906. }
  907. // JIRA JASSIST-220
  908. public void testStaticInterfaceMethods() throws Exception {
  909. CtClass cc = sloader.get("test4.JIRA220");
  910. cc.getMethod("foo", "()V").instrument(new ExprEditor() {
  911. @Override
  912. public void edit(MethodCall m) throws CannotCompileException {
  913. try {
  914. m.getClassName();
  915. } catch (Exception e) {
  916. fail(e.getMessage());
  917. }
  918. }
  919. });
  920. }
  921. // JIRA-230
  922. public void testDeadcode() throws Exception {
  923. CtClass newClass = sloader.makeClass("test4.TestDeadcode");
  924. addDeadCode(newClass, "public void evaluate(){if (false) {int i = 0;}}");
  925. addDeadCode(newClass, "public void evaluate2(){if (false == true) {int i = 0;}}");
  926. addDeadCode(newClass, "public void evaluate3(){if (true) {} else {} int i = 0; if (false) {} else {} i++; }");
  927. addDeadCode(newClass, "public void evaluate4(){ for (;false;); int i = false ? 1 : 0; while (true) { return; }}");
  928. addDeadCode(newClass, "public void evaluate5(){ boolean b = !false; b = false && b; b = true && true;"
  929. + " b = true || b; b = b || false; }");
  930. addDeadCode(newClass, "public boolean evaluate6(){ return !false; }");
  931. addDeadCode(newClass, "public boolean evaluate7(){ return !true; }");
  932. newClass.debugWriteFile();
  933. Class<?> cClass = newClass.toClass(test4.DefineClassCapability.class);
  934. Object o = cClass.getConstructor().newInstance();
  935. java.lang.reflect.Method m = cClass.getMethod("evaluate");
  936. m.invoke(o);
  937. m = cClass.getMethod("evaluate2");
  938. m.invoke(o);
  939. m = cClass.getMethod("evaluate3");
  940. m.invoke(o);
  941. m = cClass.getMethod("evaluate4");
  942. m.invoke(o);
  943. m = cClass.getMethod("evaluate6");
  944. assertTrue((boolean)m.invoke(o));
  945. m = cClass.getMethod("evaluate7");
  946. assertFalse((boolean)m.invoke(o));
  947. m = cClass.getMethod("evaluate5");
  948. m.invoke(o);
  949. }
  950. private void addDeadCode(CtClass cc, String meth) throws Exception {
  951. CtMethod m = CtNewMethod.make(meth, cc);
  952. cc.addMethod(m);
  953. }
  954. public void testAnnArg() throws Exception {
  955. CtClass cc = sloader.get("test4.AnnoArg");
  956. CtMethod m = cc.getDeclaredMethod("foo");
  957. test4.AnnoArg.AnnoArgAt a = (test4.AnnoArg.AnnoArgAt)m.getAnnotations()[0];
  958. assertEquals("test4.AnnoArg$B", a.value().getName());
  959. System.out.println(a.value().getName());
  960. }
  961. public void testDeclaredMethods() throws Exception {
  962. CtClass cc = sloader.get("test4.DeclMethodsList");
  963. CtMethod[] meth = cc.getDeclaredMethods("foo");
  964. assertEquals(2, meth.length);
  965. assertEquals("()V", meth[0].getSignature());
  966. assertEquals("(I)I", meth[1].getSignature());
  967. meth = cc.getDeclaredMethods("bar");
  968. assertEquals(1, meth.length);
  969. assertEquals("()V", meth[0].getSignature());
  970. meth = cc.getDeclaredMethods("baz");
  971. assertEquals(0, meth.length);
  972. }
  973. public void testAnnotationLoader() throws Exception {
  974. CtClass anno = sloader.makeAnnotation("test4.AnnoLoadAnno");
  975. anno.debugWriteFile();
  976. CtClass cc = sloader.get("test4.AnnoLoad");
  977. CtMethod m = cc.getDeclaredMethod("foo");
  978. ClassFile cf = cc.getClassFile();
  979. ConstPool cp = cf.getConstPool();
  980. AnnotationsAttribute attr
  981. = new AnnotationsAttribute(cp, AnnotationsAttribute.visibleTag);
  982. Annotation a = new Annotation(anno.getName(), cp);
  983. a.addMemberValue("value", new javassist.bytecode.annotation.StringMemberValue("file/path", cp));
  984. attr.setAnnotation(a);
  985. m.getMethodInfo().addAttribute(attr);
  986. cc.writeFile();
  987. anno.toClass(test4.DefineClassCapability.class);
  988. Class<?> rc = ((java.lang.annotation.Annotation)m.getAnnotations()[0]).annotationType();
  989. assertEquals(anno.getName(), rc.getName());
  990. }
  991. }