2017-03-02 1315 views
2

參考:http://jboss-javassist.github.io/javassist/tutorial/tutorial2.html

method.insertBefore("{ System.out.println($1);}"); 

這種說法給了我以下錯誤:

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 

此外,當我使用出現了同樣的錯誤任何參數(傳遞給參數)或任何局部變量而不是'$ 1'。這已在this問題中涵蓋,但我並不真正瞭解那裏的解決方案。

還有this其他帖子同樣的問題,但沒有答案。

請幫忙。謝謝

回答

2

好的,這是我如何解決這個問題。我忽略了很少的錯誤,以及我學到的一些東西。我分享這個,因爲我無法找到任何地方直接解決問題的內容。 參考this答案,this文章:

insertBeforeinsertAfter類似的方法,不能訪問任何局部變量,但可以通過他們的名字訪問方法的方法參數。如果嘗試訪問本地變量,則會發生no such field錯誤。

這些方法無法訪問在它們中聲明的任何參數作爲檢測過程。 ctmethod.insertBefore("{int i = 4; int j = 9;}") ctmethod.insertBefore("i = 5;"); ctMethod.insertAfter("j = 9;");

  • 上面的代碼將給出no such field: j(and i)錯誤
  • insertBeforeinsertAfter,期望單個語句,或一個單一的代碼塊如上面代碼段的第一行來完成。
  • 如果在ctmethod.addcatch()中也使用變量,則會出現此錯誤no such field
  • ctmethod.addLocalVariable()有助於宣稱可以通過insertBefore()訪問的變量,等等。然而,.addCatch()仍然會給no such field錯誤,如果您嘗試使用變量使用宣佈.addLocalVariable()
  • 我得到no such field: $1由於我的愚蠢的錯誤。我正在迭代類中的許多方法,所以錯誤是由於這些方法中的一些有零參數$1,$2.. and $args正如this doc中所解釋的那樣工作良好。

P.S.當我遇到他們時,我會添加更多提示,歡迎任何更正。