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

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