1

As part of some simulations that I am running using a tool called JIST/SWANS I am getting some weird errors. This simulator has been written for Java 1.4 and I am attempting to port it to 1.5.

What I am trying to do is to compile the original code with the 1.5 SDK. The problem is that the simulator uses bcel to rewrite the bytecode so that JVM could be used for simulations. When I compile the code under the new SDK, I get the error given below. Can someone point me in the right direction to fix this? I know the byte code produced by 1.4 and 1.5 are somewhat different but I have no clue where to start looking from.

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)

UPDATE: I narrowed down to this line from where the exception is being thrown:

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

There is a main method in the class which is being passed to this function so I have no clue why it is returning a null.

UPDATE 2:

There is one function:

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

which passes the MyClient.class to a function that makes use of this in the findMain method posted above. Using the debugger, I can see that declaredMethods is null so obviously the getDeclaredMethods call is dying. The MyClient class is defined as an inner static class in the following way:

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

      ...

   }
}

I am not sure if this has anything to do with declaredMethods being null so I tried extracting the class into a separate class but with no luck.

UPDATE 3:

Ok narrowed it down. The following throws an exception even in the main class:

System.out.println(MyClient.class.getDeclaredMethods());
Legend
  • 113,822
  • 119
  • 272
  • 400
  • AFAIK, a 1.5 VM should be able to run code compiled against 1.4 without modification. Does the same code run in 1.4? – CurtainDog Nov 30 '10 at 05:38
  • @CurtainDog: Yes. It runs without any problems. But didn't the bytecode representation change from 1.4 to 1.5? Or maybe I am wrong... – Legend Nov 30 '10 at 05:41
  • Yes, 1.5 would have extra instructions for handling generics, etc, but at the top of the .class file it would have the SDK version that the .class file was compiled with and that would tell the VM to how to treat it. – CurtainDog Nov 30 '10 at 05:56
  • @CurtainDog: I see... In that case, I am kind of stuck I guess because the error does not make any sense to me as to where the problem could be residing at. – Legend Nov 30 '10 at 05:58
  • Hmmm... can you try taking out the `>` – CurtainDog Nov 30 '10 at 06:15
  • @CurtainDog: Actually, I just added that unable to bear the yellow lines in Eclipse :) The error however is the same whether or not the `>` is present. – Legend Nov 30 '10 at 06:17
  • @CurtainDog: I updated my question again with some extra detail. – Legend Nov 30 '10 at 06:25

1 Answers1

1

Perhaps downloading BCEL's source code and putting a breakpoint at line 135 of this method

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

will tell you more. Obviously, there's a problem somewhere with array index manipulation.

From what I see, BCEL is no more in development, so if a bug exists, it might be difficult to have it fixed if you report it.

ASM is a more modern bytecode generation library that's under development. You probably already know this; but if you have that simulator's source code and it isn't using BCEL too much, you might be able to rewrite it using ASM. Of course, stuff like this is usually overkill.

darioo
  • 46,442
  • 10
  • 75
  • 103
  • +1 Thank you for your suggestions. Yes. When I started working with this, I realized that BCEL was discontinued. Unfortunately, this simulator is built on the basis of BCEL so rewriting is not an immediate luxury for me. I will see if I can figure out something with the source as you suggested. – Legend Nov 30 '10 at 05:58