Получение странных ошибок при манипуляциях со стеком - PullRequest
1 голос
/ 30 ноября 2010

В рамках некоторых симуляций, которые я выполняю, используя инструмент под названием JIST / SWANS, я получаю некоторые странные ошибки.Этот симулятор был написан для Java 1.4, и я пытаюсь перенести его на 1.5.

То, что я пытаюсь сделать, - это скомпилировать исходный код с 1.5 SDK.Проблема заключается в том, что симулятор использует bcel для перезаписи байт-кода, чтобы JVM могла использоваться для моделирования.Когда я компилирую код в новом SDK, я получаю сообщение об ошибке, приведенное ниже.Может ли кто-нибудь указать мне правильное направление, чтобы это исправить?Я знаю, что байт-код, создаваемый 1.4 и 1.5, несколько отличается, но я понятия не имею, с чего начать.

java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.ArrayList.remove(ArrayList.java:390)
    at org.apache.bcel.verifier.structurals.OperandStack.pop(OperandStack.java:135)
    at org.apache.bcel.verifier.structurals.ExecutionVisitor.visitPUTFIELD(ExecutionVisitor.java:1048)
    at org.apache.bcel.generic.PUTFIELD.accept(PUTFIELD.java:78)
    at jist.runtime.RewriterFlow.execute(RewriterFlow.java:235)
    at jist.runtime.RewriterFlow.doFlow(RewriterFlow.java:187)
    at jist.runtime.RewriterTraversalContinuableMethods.doMethod(Rewriter.java:3059)
    at jist.runtime.ClassTraversal.processMethodGen(ClassTraversal.java:136)
    at jist.runtime.ClassTraversal.processClassGen(ClassTraversal.java:96)
    at jist.runtime.ClassTraversal.processClass(ClassTraversal.java:63)
    at jist.runtime.Rewriter.rewriteClass(Rewriter.java:621)
    at jist.runtime.Rewriter.findClass(Rewriter.java:410)
    at jist.runtime.Rewriter.loadClass(Rewriter.java:367)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
    at java.lang.Class.getDeclaredMethod(Class.java:1935)
    at jist.swans.app.AppJava.findMain(AppJava.java:86)
    at jist.swans.app.AppJava.<init>(AppJava.java:61)
    at driver.aodvtest.createNode(aodvtest.java:192)
    at driver.aodvtest.createSim(aodvtest.java:235)
    at driver.aodvtest.main(aodvtest.java:277)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at jist.runtime.Bootstrap$JavaMain.startSimulation(Bootstrap.java:163)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at jist.runtime.Controller.processEvent(Controller.java:650)
    at jist.runtime.Controller.eventLoop(Controller.java:428)
    at jist.runtime.Controller.run(Controller.java:457)
    at java.lang.Thread.run(Thread.java:619)

java.lang.NullPointerException
    at driver.aodvtest.createNode(aodvtest.java:198)
    at driver.aodvtest.createSim(aodvtest.java:235)
    at driver.aodvtest.main(aodvtest.java:277)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at jist.runtime.Bootstrap$JavaMain.startSimulation(Bootstrap.java:163)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at jist.runtime.Controller.processEvent(Controller.java:650)
    at jist.runtime.Controller.eventLoop(Controller.java:428)
    at jist.runtime.Controller.run(Controller.java:457)
    at java.lang.Thread.run(Thread.java:619)

ОБНОВЛЕНИЕ: Я сузился до этой строки, откудасоздается исключение:

private Method findMain(Class<?> c) throws NoSuchMethodException {
  return c.getDeclaredMethod("main", new Class<?>[] { String[].class });
}

В классе, который передается этой функции, есть метод main, поэтому я понятия не имею, почему он возвращает null.

ОБНОВЛЕНИЕ 2:

Существует одна функция:

createNode(..., ..., ..., ..., MyClient.class, ..., ...)

, которая передает MyClient.class функции, которая использует это в методе findMainразмещено выше.Используя отладчик, я вижу, что declaredMethods равен null, поэтому очевидно, что вызов getDeclaredMethods умирает.Класс MyClient определяется как внутренний статический класс следующим образом:

public static class MyClient {
   public static void main(String[] args[]) {

      ...

   }
}

Я не уверен, имеет ли это отношение к declaredMethods, являющемуся null, поэтому я попытался извлечь классв отдельный класс, но без удачи.

ОБНОВЛЕНИЕ 3:

Хорошо, сузили его.Следующее создает исключение даже в основном классе:

System.out.println(MyClient.class.getDeclaredMethods());

1 Ответ

1 голос
/ 30 ноября 2010

Возможно, загрузка исходного кода BCEL и установка точки останова в строке 135 этого метода

org.apache.bcel.verifier.structurals.OperandStack.pop(OperandStack.java:135)

скажет вам больше.Очевидно, что где-то есть проблема с манипулированием индексами массива.

Из того, что я вижу, BCEL больше не находится в разработке, поэтому, если ошибка существует, может быть трудно исправить ее, если вы сообщите об этом.это более современная библиотека генерации байт-кода, которая находится в стадии разработки.Вы, наверное, уже знаете это;но если у вас есть исходный код этого симулятора и он не использует BCEL слишком часто, вы можете переписать его с помощью ASM.Конечно, подобные вещи, как правило, излишни.

...