Подтвердить что ты не робот

Как сделать ArrayList с помощью Javassist

Я хочу добавить arrayList в метод во время инструментария. Я попробовал это, как упоминалось в (Javassist CannotCompileException при попытке добавить строку для создания Карты), но она выдает другое исключение с помощью java.lang.VerifyError.

    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)

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

Обновление 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);
4b9b3361

Ответ 1

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

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

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

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

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

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