Java 在堆栈操作中获得奇怪的错误

Java 在堆栈操作中获得奇怪的错误,java,debugging,bytecode,bcel,Java,Debugging,Bytecode,Bcel,作为我使用JIST/SWANS工具运行的一些模拟的一部分,我得到了一些奇怪的错误。这个模拟器是为Java1.4编写的,我正在尝试将它移植到1.5 我试图做的是用1.5SDK编译原始代码。问题是模拟器使用重写字节码,以便JVM可以用于模拟。当我在新SDK下编译代码时,我得到下面给出的错误。有人能给我指出解决这个问题的正确方向吗?我知道1.4和1.5产生的字节码有些不同,但我不知道从哪里开始寻找 java.lang.ArrayIndexOutOfBoundsException: -1 at

作为我使用JIST/SWANS工具运行的一些模拟的一部分,我得到了一些奇怪的错误。这个模拟器是为Java1.4编写的,我正在尝试将它移植到1.5

我试图做的是用1.5SDK编译原始代码。问题是模拟器使用重写字节码,以便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)
它将
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());

也许下载BCEL的源代码并在该方法的第135行设置断点

org.apache.bcel.verifier.structurals.OperandStack.pop(OperandStack.java:135)
我会告诉你更多。显然,数组索引操作存在问题

据我所见,BCEL已不再处于开发阶段,因此,如果存在缺陷,如果您报告它,可能很难修复它


是一个正在开发的更现代的字节码生成库。你可能已经知道这一点;但是,如果您有模拟器的源代码,并且它没有太多地使用BCEL,那么您可以使用ASM重写它。当然,像这样的东西通常是多余的。

也许下载BCEL的源代码并在这个方法的第135行设置断点

org.apache.bcel.verifier.structurals.OperandStack.pop(OperandStack.java:135)
我会告诉你更多。显然,数组索引操作存在问题

据我所见,BCEL已不再处于开发阶段,因此,如果存在缺陷,如果您报告它,可能很难修复它


是一个正在开发的更现代的字节码生成库。你可能已经知道这一点;但是,如果您有模拟器的源代码,并且它没有太多地使用BCEL,那么您可以使用ASM重写它。当然,像这样的东西通常是多余的。

AFAIK,1.5虚拟机应该能够运行针对1.4编译的代码,而无需修改。同样的代码在1.4中运行吗?@CurtainDog:是的。它运行没有任何问题。但是字节码表示不是从1.4变为1.5了吗?也许我错了……是的,1.5会有额外的指令来处理泛型等,但在.class文件的顶部,它会有.class文件编译时使用的SDK版本,这会告诉VM如何处理它。@CurtainDog:我明白了。。。在这种情况下,我想我有点卡住了,因为这个错误对我来说没有任何意义,因为问题可能存在于哪里。嗯。。。你能试着把
去掉吗。同样的代码在1.4中运行吗?@CurtainDog:是的。它运行没有任何问题。但是字节码表示不是从1.4变为1.5了吗?也许我错了……是的,1.5会有额外的指令来处理泛型等,但在.class文件的顶部,它会有.class文件编译时使用的SDK版本,这会告诉VM如何处理它。@CurtainDog:我明白了。。。在这种情况下,我想我有点卡住了,因为这个错误对我来说没有任何意义,因为问题可能存在于哪里。嗯。。。你能试着拿出
+1谢谢你的建议。对当我开始使用它时,我意识到BCEL已经停产了。不幸的是,这个模拟器是建立在BCEL的基础上的,所以重写对我来说不是一件立即的奢侈品。我会看看是否能像你建议的那样从信息来源中找出一些东西。谢谢你的建议。对当我开始使用它时,我意识到BCEL已经停产了。不幸的是,这个模拟器是建立在BCEL的基础上的,所以重写对我来说不是一件立即的奢侈品。我会看看是否能像你建议的那样从源头上找到一些东西。
org.apache.bcel.verifier.structurals.OperandStack.pop(OperandStack.java:135)