Referring to : http://jboss-javassist.github.io/javassist/tutorial/tutorial2.html
method.insertBefore("{ System.out.println($1);}");
This statement gives me following error:
Exception: javassist.CannotCompileException: [source error] no such field: $1
javassist.CannotCompileException: [source error] no such field: $1
at javassist.CtBehavior.insertBefore(CtBehavior.java:774)
at javassist.CtBehavior.insertBefore(CtBehavior.java:734)
at com.here.debugHelper.DurationTransformer.transform(DurationTransformer.java:124)
at sun.instrument.TransformerManager.transform(Unknown Source)
at sun.instrument.InstrumentationImpl.transform(Unknown Source)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.here.debugHelper.TestInstrumentation.main(TestInstrumentation.java:10)
Caused by: compile error: no such field: $1
at javassist.compiler.TypeChecker.fieldAccess(TypeChecker.java:845)
at javassist.compiler.TypeChecker.atFieldRead(TypeChecker.java:803)
at javassist.compiler.TypeChecker.atMember(TypeChecker.java:988)
at javassist.compiler.JvstTypeChecker.atMember(JvstTypeChecker.java:66)
at javassist.compiler.ast.Member.accept(Member.java:39)
at javassist.compiler.JvstTypeChecker.atMethodArgs(JvstTypeChecker.java:221)
at javassist.compiler.TypeChecker.atMethodCallCore(TypeChecker.java:735)
at javassist.compiler.TypeChecker.atCallExpr(TypeChecker.java:695)
at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:157)
at javassist.compiler.ast.CallExpr.accept(CallExpr.java:46)
at javassist.compiler.CodeGen.doTypeCheck(CodeGen.java:242)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:330)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:50)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:351)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:50)
at javassist.compiler.Javac.compileStmnt(Javac.java:567)
at javassist.CtBehavior.insertBefore(CtBehavior.java:754)
... 17 more
Moreover,the same error appears when I use any parameter(passed to the parameter) or any local variable instead of '$1'. This has been covered in this question, but I don't really understand the solution there.
There is this other post with same question but no answer.
Please help. Thank you
Alright, this is how I worked around the problem. There were few mistakes that I was overlooking and some things that I learnt. I am sharing this since I could not find the content directly addressing the issue anywhere. Referring to this answer and this article:
The insertBefore
, insertAfter
and other such methods cannot access any local variable but can access method parameter of the method by their names. no such field
error occurs if attempt is made to access local variable.
These methods cannot access any parameter declared within them as a process of instrumentation.
ctmethod.insertBefore("{int i = 4; int j = 9;}")
ctmethod.insertBefore("i = 5;");
ctMethod.insertAfter("j = 9;");
no such field: j(and i)
errorinsertBefore
, insertAfter
, expect a single statement, or a single block of code as done in first line of above code snippet.no such field
appears in case when variables are used in ctmethod.addcatch()
too.ctmethod.addLocalVariable()
helps in declaring a variable that can be accessed by insertBefore()
, etc. However, .addCatch()
will still give no such field
error if you try to use variable declared using .addLocalVariable()
no such field: $1
due to my silly mistake. I was going iterating through a number of method in a class, so the error was due to the fact that some of those methods had zero arguments. $1,$2.. and $args
work well as explained in this doc.P.S. I will add further tips as I come across them and any corrections are welcomed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With