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

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