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

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. }