2015-10-23 10 views
19

instrumentation中にメソッドにarrayListを追加します。私は(Javassist CannotCompileException when trying to add a line to create a Map)で述べたように試しましたが、java.lang.VerifyErrorを使って別の例外をスローします。Javassistを使用してArrayListを作成する方法

public void createInsertBefore(String scenarioName, String className, CtMethod method, 
            String insertBefore) throws CannotCompileException { 
     method.addLocalVariable("startTime", CtClass.longType); 
     StringBuilder bBuilder = new StringBuilder(); 
     bBuilder.append("startTime = System.nanoTime();"); 
     bBuilder.append("System.out.println(startTime);"); 

     if((insertBefore!=null) && !insertBefore.isEmpty()){ 
      bBuilder.append(insertBefore); 
     } 

     bBuilder.append("java.util.List metadata = new java.util.ArrayList();"); 

     System.out.println(bBuilder.toString()); 
     method.insertBefore(bBuilder.toString()); 
} 

出力はprint文から受信し、

startTime = System.nanoTime(); 
System.out.println(startTime); 
java.util.List metadata = new java.util.ArrayList(); 

である。しかし、それは次の例外をスローし、

Exception in thread "main" java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:382) 
    at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:397) 
Caused by: java.lang.VerifyError 
    at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method) 
    at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144) 
    at org.wso2.das.javaagent.instrumentation.Agent.premain(Agent.java:57) 
    ... 6 more 
FATAL ERROR in native method: processing of -javaagent failed 
Aborted (core dumped) 

状況は以前と同じですが、なぜそれが別の例外をスローしません。私が間違って何をやっている....いくつかの助けてください...

アップデート1

行が(私はいくつかの印刷行を削除した)を追加、 のinsertBefore

startTime = System.nanoTime(); 
java.util.List metadata = new java.util.ArrayList(); 

insertAt

System.out.println("prepareStatement is running"); 
java.util.Map/*<String,String>*/ arbitraryMap = new java.util.HashMap/*String,String>*/(); 
arbitraryMap.put("query",$1);System.out.println(arbitraryMap); 

insertAfter

System.out.println(System.nanoTime()-startTime); 
+0

ネイティブコードのエラーのように見えます。 – Thomas

+0

どういう意味ですか? Uは残りのコードを意味しますか?私は問題がその声明にあると思った。なぜなら、私がその行をコメントアウトすると、計測器はうまく動作するからだ。したがって、私はそれがその声明に間違っていると思う。 – udani

+0

あなたのコードは間違っているかもしれませんが、ここでエラーが発生します: 'sun.instrument.InstrumentationImpl.retransformClasses0(ネイティブメソッド)'つまりネイティブコード内です。 JavaDocには次のようなエラーが表示されます: ''検証者がクラスファイルに整形式があっても何らかの内部的な不一致やセキュリティの問題があることが検出されたときにスローされます。 ' - それは、あなたは2回挿入しようとしています。すでに 'startTime'、' metadata'などと呼ばれる変数があります。 – Thomas

答えて

6

VerifyErrorが発生したときにVMの通知、すでにコンパイルされたバイトコードが有効ではないこと。たとえば、整数などのロード命令を使用して長い変数を読み込もうとしたときなどです。

あなたのケースでは、コードはコンパイルされますが、javaassistはその魔法を行いますが、VMはコードを受け入れません。 javassistのバグかそのバグです。

それを修正する方法

1)私の知る限りでは、あなただけのinsertBeforeを使用する方法の最初にある文(ない1行)を追加することができます。複数のものを追加したい場合は、のようなものを中括弧{}で囲んでください。あなたはstartTime

X)は、このまたは他のエラーが解決しない場合は、ディスク上のファイルにクラスファイルを書き込もうとして行ったようにあなたが変数としてメタデータを追加しませんでした

2)(あなたはtoClassFileをすることができます使用して修正されたクラスファイルにbyte[]としてアクセスします)。 javapのようなツールを使ってコンパイルされたコードを見て、何が起こっているのかをより明確に見ることができます。

関連する問題