private void findAndRemoveMethod(CtClass ctClass, String methodName) throws NotFoundException { try { CtMethod ctMethod = ctClass.getDeclaredMethod(methodName); ctClass.getClassFile().getMethods().remove(ctMethod.getMethodInfo()); } catch (Exception e) { } }
public void testArrayLen() throws Exception { CtClass cc = sloader.get("test2.ArrayLenTest"); cc.addMethod(CtNewMethod.make("public int foo(){ return this.length; }", cc)); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(1, invoke(obj, "foo")); }
public T createJavassistProxy( LoadBalancer loadBalance, ConcurrentMap<String, T> map, Class ifaces) throws Exception { Class<?>[] interfaces = ifaces.getInterfaces(); if (interfaces.length == 1) { ClassPool mPool = new ClassPool(true); CtClass ctClass = mPool.get(interfaces[0].getName()); // 新建代理类 CtClass mCtc = mPool.makeClass(ifaces.getName() + "$JavassistProxy"); mCtc.setSuperclass(ctClass); for (CtMethod method : ctClass.getDeclaredMethods()) { System.out.println(method.getName()); // CtMethod m = new CtMethod(method.getReturnType(), // ,method.getParameterTypes(), mCtc); // cc.addMethod(m); // m.setBody("{ x += $1; }"); mCtc.addMethod(method); // method.setBody(""); } // mCtc.debugWriteFile("/home/liguojun"); return null; } else { return null; } }
public void testCodeGen2() throws Exception { CtClass cc = sloader.makeClass("test2.CodeGen2"); CtMethod m1 = CtNewMethod.make( "public int test() {" + " int len;" + " String s = \"foo\" + \"bar\" + 3;" + " System.out.println(s); len = s.length();" + " len = -3 + len; len = len - (7 - 2 + -1);" + " int k = 3; len += ~k - ~3;" + " return len; }", cc); cc.addMethod(m1); CtMethod m2 = CtNewMethod.make( "public int test2() {" + " double d = 0.2 - -0.1;" + " d += (0.2 + 0.3) * 1.0;" + " return (int)(d * 10); }", cc); cc.addMethod(m2); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(0, invoke(obj, "test")); assertEquals(8, invoke(obj, "test2")); }
public void testAddCatchForConstructor() throws Exception { CtClass cc = sloader.get("test2.AddCatchForConstructor"); CtConstructor m1 = cc.getDeclaredConstructors()[0]; m1.addCatch("return;", sloader.get("java.lang.Exception")); cc.writeFile(); Object obj = make(cc.getName()); }
public void testConstructorName() throws Exception { CtClass cc = sloader.get("test2.Construct"); CtConstructor[] cons = cc.getDeclaredConstructors(); assertEquals("Construct", cons[0].getName()); assertEquals("Construct", cons[1].getName()); assertEquals("<clinit>", cc.getClassInitializer().getName()); }
public void testNewArray() throws Exception { ExprEditor ed = new ExprEditor() { int dim[] = {1, 2, 2, 1, 2, 2, 3}; int cdim[] = {1, 1, 2, 1, 1, 2, 2}; int counter = 0; public void edit(NewArray expr) throws CannotCompileException { try { CtClass str = sloader.get("java.lang.String"); if (counter < 3) assertEquals(str, expr.getComponentType()); else assertEquals(CtClass.intType, expr.getComponentType()); assertEquals(dim[counter], expr.getDimension()); assertEquals(cdim[counter], expr.getCreatedDimensions()); expr.replace("{ i += $1; $_ = $proceed($$); }"); ++counter; } catch (NotFoundException e) { throw new CannotCompileException(e); } } }; CtClass cc = sloader.get("test2.NewArray"); CtMethod m1 = cc.getDeclaredMethod("foo"); m1.instrument(ed); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(48, invoke(obj, "run")); }
public void testJIRA246() throws Exception { CtClass ctClass = sloader.makeClass("test5.JIRA246Test"); ctClass.addInterface(sloader.get(test5.JIRA246.Test.class.getName())); String methodBody = "public void test() { defaultMethod(); }"; CtMethod ctMethod = CtMethod.make(methodBody, ctClass); ctClass.addMethod(ctMethod); }
public void testBadClass() throws Exception { CtClass badClass = ClassPool.getDefault().makeClass("badClass"); String src = String.join( System.getProperty("line.separator"), "public void eval () {", " if (true) {", " double t=0;", " } else {", " double t=0;", " }", " for (int i=0; i < 2; i++) {", " int a=0;", " int b=0;", " int c=0;", " int d=0;", " if (true) {", " int e = 0;", " }", " }", "}"); System.out.println(src); badClass.addMethod(CtMethod.make(src, badClass)); Class clazzz = badClass.toClass(); Object obj = clazzz.getConstructor().newInstance(); // <-- falls here }
public void testJIRA256() throws Exception { // CtClass ec = sloader.get("test5.Entity"); CtClass cc = sloader.makeClass("test5.JIRA256"); ClassFile ccFile = cc.getClassFile(); ConstPool constpool = ccFile.getConstPool(); AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag); javassist.bytecode.annotation.Annotation entityAnno = new javassist.bytecode.annotation.Annotation("test5.Entity", constpool); // = new javassist.bytecode.annotation.Annotation(constpool, ec); entityAnno.addMemberValue( "value", new javassist.bytecode.annotation.ArrayMemberValue(constpool)); attr.addAnnotation(entityAnno); ccFile.addAttribute(attr); cc.writeFile(); Object o = make(cc.getName()); assertTrue(o.getClass().getName().equals("test5.JIRA256")); java.lang.annotation.Annotation[] annotations = o.getClass().getDeclaredAnnotations(); assertEquals(1, annotations.length); }
public void testCodeGen() throws Exception { CtClass cc = sloader.get("test2.CodeGen"); CtMethod m1 = cc.getDeclaredMethod("run"); m1.insertBefore( "{ double d = true ? 1 : 0.1; " + " d = d > 0.5 ? 0.0 : - 1.0; " + " System.out.println(d); " + " String s = \"foo\"; " + " s = 1 + 2 + s + \"bar\"; " + " s += \"poi\" + 3 + seven() + seven(\":\" + ' '); " + " s += .14; " + " msg = s; " + " System.out.println(s); }"); // recursive type check is done if $proceed is used. CtMethod m2 = CtNewMethod.make( "public int test() {" + " String s = $proceed(\"int\" + (3 + 0.14)) + '.'; " + " System.out.println(s); return s.length(); }", cc, "this", "seven"); cc.addMethod(m2); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(19, invoke(obj, "run")); assertEquals(9, invoke(obj, "test")); }
public void testJIRA241() throws Exception { CtClass cc = sloader.get("test5.JIRA241"); CtMethod testMethod = cc.getDeclaredMethod("test"); testMethod.insertAfter("System.out.println(\"inserted!\");"); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(10, invoke(obj, "run")); }
public void testObjectSuper() throws Exception { CtClass cc = sloader.get("java.lang.Object"); try { cc.addMethod(CtNewMethod.make("public int foo(){ return super.hashCode(); }", cc)); fail("could access the super of java.lang.Object"); } catch (CannotCompileException e) { } }
public static CtClass getSuperclass(CtClass c) throws CompileError { try { CtClass sc = c.getSuperclass(); if (sc != null) return sc; } catch (NotFoundException e) { } throw new CompileError("cannot find the super class of " + c.getName()); }
public void testJIRA249() throws Exception { CtClass cc = sloader.get("test5.BoolTest"); CtMethod testMethod = cc.getDeclaredMethod("test"); testMethod.insertBefore("i = foo(true & true);"); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(1, invoke(obj, "run")); }
/** @param name a qualified class name. e.g. java.lang.String */ public CtField lookupField(String className, Symbol fieldName) throws CompileError { CtClass cc = lookupClass(className, false); try { return cc.getField(fieldName.get()); } catch (NotFoundException e) { } throw new CompileError("no such field: " + fieldName.get()); }
/* * Returns YES if actual parameter types matches the given signature. * * argTypes, argDims, and argClassNames represent actual parameters. * * This method does not correctly implement the Java method dispatch * algorithm. * * If some of the parameter types exactly match but others are subtypes of * the corresponding type in the signature, this method returns the number * of parameter types that do not exactly match. */ private int compareSignature(String desc, int[] argTypes, int[] argDims, String[] argClassNames) throws CompileError { int result = YES; int i = 1; int nArgs = argTypes.length; if (nArgs != Descriptor.numOfParameters(desc)) return NO; int len = desc.length(); for (int n = 0; i < len; ++n) { char c = desc.charAt(i++); if (c == ')') return (n == nArgs ? result : NO); else if (n >= nArgs) return NO; int dim = 0; while (c == '[') { ++dim; c = desc.charAt(i++); } if (argTypes[n] == NULL) { if (dim == 0 && c != 'L') return NO; if (c == 'L') i = desc.indexOf(';', i) + 1; } else if (argDims[n] != dim) { if (!(dim == 0 && c == 'L' && desc.startsWith("java/lang/Object;", i))) return NO; // if the thread reaches here, c must be 'L'. i = desc.indexOf(';', i) + 1; result++; if (i <= 0) return NO; // invalid descriptor? } else if (c == 'L') { // not compare int j = desc.indexOf(';', i); if (j < 0 || argTypes[n] != CLASS) return NO; String cname = desc.substring(i, j); if (!cname.equals(argClassNames[n])) { CtClass clazz = lookupClassByJvmName(argClassNames[n]); try { if (clazz.subtypeOf(lookupClassByJvmName(cname))) result++; else return NO; } catch (NotFoundException e) { result++; // should be NO? } } i = j + 1; } else { int t = descToType(c); int at = argTypes[n]; if (t != at) if (t == INT && (at == SHORT || at == BYTE || at == CHAR)) result++; else return NO; } } return NO; }
public void testSuperInterface() throws Exception { CtClass cc = sloader.makeClass("test2.SuperInterface3"); CtClass cc2 = sloader.get("test2.SuperInterface2"); cc.addInterface(cc2); cc.addField(new CtField(cc2, "inner", cc)); CtMethod m = CtNewMethod.make("public int getAge() { return inner.getAge(); }", cc); cc.addMethod(m); cc.writeFile(); }
private void testRemove2(CtClass cc, String fieldName) throws Exception { CtField f = cc.getField(fieldName); cc.removeField(f); try { CtField f2 = cc.getField(fieldName); fail("the removed field still exists"); } catch (NotFoundException e) { } }
public void testTypeAnno() throws Exception { CtClass cc = sloader.get("test5.TypeAnno"); cc.getClassFile().compact(); cc.writeFile(); Object obj = make(cc.getName()); TypeVariable<?> t = obj.getClass().getTypeParameters()[0]; Annotation[] annos = t.getAnnotations(); assertEquals("@test5.TypeAnnoA()", annos[0].toString()); }
private void testRemove3(CtClass cc, String methodName) throws Exception { CtMethod m = cc.getDeclaredMethod(methodName); cc.removeMethod(m); try { CtMethod m2 = cc.getDeclaredMethod(methodName); fail("the removed method still exists"); } catch (NotFoundException e) { } }
private void testRemove4(CtClass cc, String desc) throws Exception { CtConstructor c = cc.getConstructor(desc); cc.removeConstructor(c); try { CtConstructor c2 = cc.getConstructor(desc); fail("the removed method still exists"); } catch (NotFoundException e) { } }
public void testWhere() throws Exception { CtClass cc = sloader.get("test2.Where"); CtConstructor cons = cc.getClassInitializer(); cons.instrument( new ExprEditor() { public void edit(MethodCall m) throws CannotCompileException { System.out.println(m.where().getName()); } }); }
public void testAddLocalVar() throws Exception { CtClass cc = sloader.get("test2.AddLocalVar"); CtMethod m1 = cc.getDeclaredMethod("foo"); m1.addLocalVariable("i", CtClass.intType); m1.insertBefore("i = 3;"); m1.insertAfter("$_ = i + 1;"); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(4, invoke(obj, "foo")); }
/** * Reads a class file and constructs a <code>CtClass</code> object with a new name. This method is * useful if you want to generate a new class as a copy of another class (except the class name). * For example, * * <ul> * <pre> * getAndRename("Point", "Pair") * </pre> * </ul> * * returns a <code>CtClass</code> object representing <code>Pair</code> class. The definition of * <code>Pair</code> is the same as that of <code>Point</code> class except the class name since * <code>Pair</code> is defined by reading <code>Point.class</code>. * * @param orgName the original (fully-qualified) class name * @param newName the new class name */ public CtClass getAndRename(String orgName, String newName) throws NotFoundException { CtClass clazz = get0(orgName, false); if (clazz == null) throw new NotFoundException(orgName); if (clazz instanceof CtClassType) ((CtClassType) clazz).setClassPool(this); clazz.setName(newName); // indirectly calls // classNameChanged() in this class return clazz; }
public void testArrayLength() throws Exception { CtClass cc = sloader.makeClass("test2.ArrayLength"); CtMethod m2 = CtNewMethod.make( "public int f() { String[] s = new String[3]; " + "return s.length; }", cc); cc.addMethod(m2); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(3, invoke(obj, "f")); }
public void testLocalVar() throws Exception { CtClass cc = sloader.get("test2.LocalVar"); CtMethod m = cc.getDeclaredMethod("toString"); m.addLocalVariable("var", CtClass.booleanType); m.insertBefore("{var = true; }"); m.insertAfter("{if (var) hashCode(); }", false); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(3, invoke(obj, "foo")); }
public void testJIRA248() throws Exception { CtClass cc = sloader.get("test5.JIRA248"); String methodBody = "public int run() { return foo() + super.foo() + super.bar() + test5.JIRA248Intf2.super.baz(); }"; CtMethod ctMethod = CtMethod.make(methodBody, cc); cc.addMethod(ctMethod); cc.writeFile(); Object obj = make(cc.getName()); assertEquals(40271, invoke(obj, "run")); }
private void findAndRemoveMethod(CtClass ctClass, CtField ctField, String className) { try { CtMethod ctMethod = ctClass.getDeclaredMethod( ctField.getName(), new CtClass[] {ctClass.getClassPool().get(className)}); ctClass.getClassFile().getMethods().remove(ctMethod.getMethodInfo()); } catch (Exception e) { } }
public void testMethodInInner2() throws Exception { CtClass inner = sloader.get("test2.Nested3$Inner"); CtClass outer = sloader.get("test2.Nested3"); String src = "public int f() {" + " int k = 0;" + " test2.Nested3 n = new test2.Nested3(3);" + " k += n.geti();" + " n = new test2.Nested3();" + " k += n.geti();" + " n = new test2.Nested3(\"foo\");" + " k += n.geti();" + " return k; }"; outer.stopPruning(true); outer.writeFile(); try { CtMethod m = CtNewMethod.make(src, inner); fail(); } catch (RuntimeException e) { } outer.defrost(); CtMethod m = CtNewMethod.make(src, inner); inner.addMethod(m); inner.writeFile(); outer.writeFile(); Object iobj = make(inner.getName()); assertEquals(6, invoke(iobj, "f")); }