Ho problemi con l'esecuzione di un semplice programma principale con le librerie Guava.Argomento incompatibile per funzionare con la strumentazione bytecode ASM
Ho strumentato le classi per ottenere i parametri di metodi utilizzando il mio codice da qui: Java method parameters values in ASM
Il problema è che, mentre il codice funziona per i piccoli progetti (aka Torre di Hanoi), con Guava ho errori e eccezioni.
In particolare, durante il test del metodo Joiner.join, ho questo errore:
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)
E quando si esegue l'esempio utilizzando -noverify, ho un'eccezione:
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)
Il codice byte del metodo è coerente:
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
Capisco che l'errore possa essere correlato alla libreria versione ies, ma il programma java principale è stato compilato contro la libreria strumentata ed eseguito usando lo stesso jar della libreria.
Qualche idea sul perché questo sta accadendo? E come può essere risolto?
Grazie :)
EDIT
Ecco il bytecode del metodo withKeyValueSeparator prima e dopo la strumentazione
bytecode originale:
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
strumentato bytecode:
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
Ecco la piena bytecode della classe falegname:
originale: http://pastebin.com/VsccVX18
Instrumented: http://pastebin.com/xtke1a8y
Potresti aggiungere il flag '-v' al comando' javap'? Il primo stampa alcune altre informazioni utili che potrebbero aiutare. – Xyene