2015-10-23 24 views
19

Voglio aggiungere una lista di array in un metodo durante la strumentazione. Ho provato come menzionato in (Javassist CannotCompileException when trying to add a line to create a Map) ma genera un'eccezione diversa con un java.lang.VerifyError.Come creare un ArrayList usando Javassist

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()); 
} 

uscita ricevuto dal comunicato stampa è,

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

Ma getta seguente eccezione,

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) 

La situazione è uguale a prima, ma perché lo fa un'eccezione diversa . Che cosa sto facendo di sbagliato .... di aiuto per favore ...

Aggiornamento 1

linee con (Ho rimosso alcune linee di stampa), 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

Sembra un errore nel codice nativo. – Thomas

+0

Cosa intendi? U significa il resto del codice? Ho pensato che il problema fosse con questa affermazione, perché se commento questa linea, la strumentazione funziona bene. Quindi penso che sia qualcosa di sbagliato in questa affermazione. – udani

+0

Il tuo codice potrebbe essere sbagliato ma l'errore si verifica qui: 'sun.instrument.InstrumentationImpl.retransformClasses0 (Metodo nativo)' cioè all'interno del codice nativo. Il JavaDoc sull'errore che si ottiene dice: "Gettato quando il" verificatore "rileva che un file di classe, benché ben formato, contiene una sorta di incoerenza interna o problema di sicurezza. - Potrebbe dipendere dalla classe che viene migliorata, forse stai cercando di inserire due volte o c'è già una variabile chiamata 'startTime',' metadata' ecc. – Thomas

risposta

6

Un VerifyError si verifica quando le comunicazioni VM, che un bytecode già compilato non è valido. Ad esempio, quando si tenta di leggere una variabile lunga utilizzando un'istruzione di caricamento per un intero o cose simili.

Quindi, nel tuo caso, il codice viene compilato, javaassist fa la sua magia, ma la VM non accetta il codice. Deve essere un bug in javassist o un bug nel suo utilizzo.

come risolvere il problema:

1) Per quanto ne so, è possibile aggiungere solo un'istruzione (non una riga) all'inizio di un metodo che utilizza insertBefore. Se si desidera aggiungerne più di uno, avvolgerli tra parentesi graffe {}, ad esempio method.insertBefore("{" + bBuilder.toString() + "}");

2) non è stato aggiunto i metadati come una variabile come avete fatto con startTime

X) Se questo o un altro errore persiste, provare a scrivere il file di classe in un file su disco (usando toClassFile si può accedere al file di classe modificato come byte[]). Quindi puoi usare strumenti come javap per guardare il codice compilato e vedere più chiaramente cosa sta succedendo.

Problemi correlati