2015-10-23 3 views
19

Я хочу добавить arrayList в метод во время инструментария. Я попробовал это, как упоминалось в (Javassist CannotCompileException when trying to add a line to create a Map), но это вызывает другое исключение с помощью java.lang.VerifyError.Как сделать ArrayList с помощью 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()); 
} 

Выход, полученные от оператора печати,

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) 

Ситуация такая же, как и раньше, но почему это бросить другое исключение , Что я делаю не так .... помощь пожалуйста ...

Update 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 (Native Method)' i.e, он находится внутри собственного кода. JavaDoc о полученной ошибке говорит: «Брось, когда« верификатор »обнаруживает, что файл класса, хотя и хорошо сформированный, содержит какую-то внутреннюю несогласованность или проблему безопасности.» - это может зависеть от класса, который увеличивается, возможно вы пытаетесь вставить дважды или уже есть переменная, называемая «startTime», «метаданные» и т. д. – Thomas

ответ

6

VerifyError происходит, когда замечает В.М., что уже скомпилирован байт-код не действителен. Например, когда вы пытаетесь прочитать длинную переменную, используя инструкцию загрузки для целого числа или подобные вещи.

Итак, в вашем случае код компилируется, javaassist делает свою магию, но виртуальная машина не принимает код. Это должно быть либо ошибка в javassist, либо ошибка в ее использовании.

Как это исправить:

1) Насколько я знаю, вы можете добавить только одно заявление (не одна линия) в начале метода с использованием insertBefore. Если вы хотите добавить более одного, оберните их в скобки {}, что-то вроде method.insertBefore("{" + bBuilder.toString() + "}");

2) Вы не добавили метаданные в качестве переменной, как вы делали с startTime

X) Если та или иная ошибка все еще сохраняется, попробуйте записать файл класса в файл на диске (с помощью toClassFile вы можете доступ к модифицированному файлу класса как byte[]). Затем вы можете использовать инструменты, такие как javap, для просмотра скомпилированного кода и более четко видеть, что происходит.

 Смежные вопросы

  • Нет связанных вопросов^_^