1

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:

1 つの機能があります。

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

上記のメソッドMyClient.classで this を利用する関数にを渡します。デバッガーを使用すると、明らかに呼び出しが停止しているfindMainことがわかります。クラスは、次の方法で内部静的クラスとして定義されます。declaredMethodsnullgetDeclaredMethodsMyClient

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

      ...

   }
}

declaredMethodsこれが存在することと関係があるかどうかはわからないnullので、クラスを別のクラスに抽出しようとしましたが、うまくいきませんでした。

更新 3:

わかりました。以下は、メイン クラスでも例外をスローします。

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

1 に答える 1

1

おそらく、BCEL のソース コードをダウンロードし、このメソッドの 135 行目にブレークポイントを配置します。

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

もっと教えてくれます。明らかに、配列インデックス操作のどこかに問題があります。

私が見たところでは、BCEL はもう開発中ではないため、バグが存在する場合、報告しても修正するのは難しいかもしれません。

ASMは、開発中の最新のバイトコード生成ライブラリです。あなたはおそらくこれをすでに知っています。しかし、そのシミュレーターのソース コードがあり、BCEL をあまり使用していない場合は、ASM を使用して書き直すことができるかもしれません。もちろん、このようなものは通常やり過ぎです。

于 2010-11-30T05:45:50.350 に答える