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

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