42 }
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get("org.jboss.security.SimplePrincipal");
CtConstructor ctc = cc.getConstructors()[0];
ctc.setBody("{name=\"modify name\";this.name = name;}");
SimplePrincipal sp=(SimplePrincipal)cc.toClass().getConstructor(String.class).newInstance("name");
System.out.println(sp.getName());
SimplePrincipal pp=new SimplePrincipal("ww");
System.out.println(pp.getName());
输出
modify name
modify name
应该是整个classloader的simpleprincipal都被改了
为了保证只有当前的SimplePrincipal被修改
ClassPool cp = ClassPool.getDefault();
CtMethod m=CtNewMethod.make("public void modifyName(String name);", cc);CtClass cc = cp.get("org.jboss.security.SimplePrincipal");
CtMethod m=CtNewMethod.make("public void modifyName(String name);", cc);
m.setBody("{this.name= $1;}");
cc.addMethod(m);
Object sp=cc.toClass().getConstructor(String.class).newInstance("name");
Method mm=sp.getClass().getDeclaredMethod("modifyName",String.class);
mm.invoke(sp, "hello");
System.out.println(((SimplePrincipal)sp).getName());
SimplePrincipal pp=new SimplePrincipal("ww");
System.out.println(pp.getName());
这里的setBody中的$1是指第一个参数(javaassist的规则)
输出
hello
ww
如果想修改己有方法的内容
CtMethod cm = ... ; cm.instrument( new ExprEditor() { public void edit(MethodCall m) throws CannotCompileException { if (m.getClassName().equals("Point") && m.getMethodName().equals("move")) m.replace("{ $1 = 0; $_ = $proceed($$); }"); } });
exprEditor没有细细研究,以后有机会研究再更新吧
attempted duplicate class definition for name
这个错误是因为同一个classloader加载了两次SimplePrincipal
因为javaassist是在运行期前修改的字节码