5

Guava ライブラリを使用した単純なメイン プログラムの実行に問題があります。

ここからコードを使用してメソッドパラメーターを取得するためにクラスをインストルメント化しました: ASM の Java メソッドパラメーター値

問題は、コードが小さなプロジェクト (別名ハノイの塔) で機能する一方で、Guava ではエラーと例外が発生することです。

特に、 Joiner.join メソッドをテストすると、次のエラーが発生します。

Exception in thread "Jalen Agent" java.lang.VerifyError: (class: com/google/common/base/Joiner, method: withKeyValueSeparator signature: (Ljava/lang/String;)Lcom/google/common/base/Joiner$MapJoiner;) Incompatible argument to function
at Main.joinBench(Main.java:42)
at Main.main(Main.java:20)

-noverify を使用して例を実行すると、例外があります。

Exception in thread "Jalen Agent" java.lang.ArrayIndexOutOfBoundsException: 1
at com.google.common.base.Joiner.<init>(Joiner.java)
at com.google.common.base.Joiner.on(Joiner.java:71)
at Main.joinBench(Main.java:42)
at Main.main(Main.java:20)

メソッドのバイトコードは一貫しています。

  public static com.google.common.base.Joiner on(java.lang.String);
      Code:
         0: bipush        1
         2: anewarray     #4                  // class java/lang/Object
         5: astore_1      
         6: aload_1       
         7: bipush        0
         9: aload_0       
        10: aastore       
        11: ldc           #20                 // int 369
        13: ldc           #21                 // String com/google/common/base/Joiner
        15: ldc           #22                 // String on
        17: aload_1       
        18: invokestatic  #28                 // Method jalen/MethodStats.onMethodEntry:(ILjava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
        21: new           #2                  // class com/google/common/base/Joiner
        24: dup           
        25: aload_0       
        26: invokespecial #32                 // Method "<init>":(Ljava/lang/String;)V
        29: ldc           #20                 // int 369
        31: invokestatic  #36                 // Method jalen/MethodStats.onMethodExit:(I)V
        34: areturn

エラーがライブラリのバージョンに関連している可能性があることは理解していますが、メインの Java プログラムはインストルメント化されたライブラリに対してコンパイルされ、ライブラリの同じ jar を使用して実行されました。

なぜこれが起こっているのかについてのアイデアはありますか? そして、それはどのように解決できますか?

ありがとう :)

編集

計測前後の withKeyValueSeparator メソッドのバイトコードは次のとおりです。

元のバイトコード:

public com.google.common.base.Joiner$MapJoiner withKeyValueSeparator(java.lang.String);
Code:
   0: new           #33                 // class com/google/common/base/Joiner$MapJoiner
   3: dup           
   4: aload_0       
   5: aload_1       
   6: aconst_null   
   7: invokespecial #34                 // Method com/google/common/base/Joiner$MapJoiner."<init>":(Lcom/google/common/base/Joiner;Ljava/lang/String;Lcom/google/common/base/Joiner$1;)V
  10: areturn

インストルメント化されたバイトコード:

public com.google.common.base.Joiner$MapJoiner withKeyValueSeparator(java.lang.String);
Code:
   0: bipush        1
   2: anewarray     #4                  // class java/lang/Object
   5: astore_1      
   6: aload_1       
   7: bipush        1
   9: aload_1       
  10: aastore       
  11: ldc           #199                // int 390
  13: ldc           #21                 // String com/google/common/base/Joiner
  15: ldc           #200                // String withKeyValueSeparator
  17: aload_1       
  18: invokestatic  #28                 // Method jalen/MethodStats.onMethodEntry:(ILjava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
  21: new           #8                  // class com/google/common/base/Joiner$MapJoiner
  24: dup           
  25: aload_0       
  26: aload_1       
  27: aconst_null   
  28: invokespecial #203                // Method com/google/common/base/Joiner$MapJoiner."<init>":(Lcom/google/common/base/Joiner;Ljava/lang/String;Lcom/google/common/base/Joiner$1;)V
  31: ldc           #199                // int 390
  33: invokestatic  #36                 // Method jalen/MethodStats.onMethodExit:(I)V
  36: areturn 

Joiner クラスの完全なバイトコードは次のとおりです。

オリジナル : http://pastebin.com/VsccVX18

計装: http://pastebin.com/xtke1a8y

4

2 に答える 2

0

まず、これがライブラリのバージョンに関連している理由がわかりません。バイトコードが正しくインストルメント化されていないようです。これにより、検証が失敗し、-noverify を使用すると例外が発生します。

検証エラーについては、Joiner.withKeyValueSeparator()にエラーがあることを示しています。このメソッドのコードは、互換性のないメソッド引数を使用して別のメソッドを呼び出そうとしています。withKeyValueSeparator() メソッドのインストルメント化されたバイトコードを教えてください。(そしてできれば、装備されていない人も同様です)

-noverify で表示されるエラーは、Joiner のコンストラクターで発生します。Joiner.on() メソッドに問題はないようです。再度、Joiner のバイトコードを投稿していただけますか。方法?(計装および非計装)

于 2013-01-07T10:40:40.240 に答える