Community
Participate
Working Groups
I'm using the last CVS change available on 7th of july for the jdt debug plugin and eclipse 2.0 for the rest. When using the SUN J2ME Wireless Toolkit I have noticed something strange. When I place a breakpoint into class A, method 3 and when the breakpoint is hit eclipse show the method 3 of java.lang.Object. When hiting a breakpoint the eclipse debugger use ReferenceTypeImpl.findMethod to check that the method is a "part of a known reference type". But when iterating, the methods are not in the right order (superclass method n, superclass method n-1 ...., class method m, class method m-1 ...) Using j2se they are in the right order. The problem seems to come in ReferenceTypeImpl.allMethods when converting an HashSet into an ArrayList. classId and methodID doesn't have the same form in WTK and j2se. Replacing the HashSet with a Vector seems to fix the problem. There is the same thing in ReferenceTypeImpl.allInterfaces and ReferenceTypeImpl.allFields but it may cause problem with duplicate entry...
I'm not sure I follow your analysis. ReferenceTypeImpl.findMethod(JdwpMethodID) iterates over all methods until it finds one with the matching ID. I don't think the ordering of the methods returned from ReferenceType.allMethods() should matter because a method on java.lang.Object shouldn't have the same ID as a method on a subclass. Also, there's nothing in the JDI specification about the ordering of methods returned by ReferenceType.allMethods(). Can you explain why you mean when you say that classID and methodID don't have the same form in WTK(J2ME) and J2SE?
In fact in the KVM methods index are defined by there order in the class file. - KVM ids form : java.lang.Object classID = 0x4C4524 methods1 methodID = 0x0 methods2 methodID = 0x1 .... MyHelloWorld classID = 0x4D5401 methods1 methodID = 0x0 methods2 methodID = 0x1 .... - JVM ids form : java.lang.Object classID = 0xB methods1 methodID = 0x98A500 methods1 methodID = 0x98A523 ... MyHelloWorld classID = 0xA methods1 methodID = 0x98D456 methods2 methodID = 0x99D578 .... This is just an example. So in the KVM methods from different class can have the same ID. I think a method is identified by juxtaposing classID and methodID. But you can't make ordering assumption based on this id.
I met this problem same with Christophe. I fix Eclipse JDT Debugger just like below: public MethodImpl findMethod(JdwpMethodID methodID) { Iterator iter = allMethods().iterator(); while(iter.hasNext()) { MethodImpl method = (MethodImpl)iter.next(); //fix by vickie //if (method.getMethodID().equals(methodID)) if (method.getMethodID().equals(methodID) && method.referenceTypeImpl().equals(this)) return method; } if (methodID.value() == 0) { return new MethodImpl(virtualMachineImpl(), this, methodID, JDIMessages.getString("ReferenceTypeImpl.Obsolete_method_1"), "", -1); //$NON- NLS-1$ //$NON-NLS-2$ } return null; }
Thank you, Christophe and Vickie. You've been very helpful. The JDWP spec is very clear about the fact that methodIDs are only unique when paired with a referenceTypeID. Vickie, your fix is correct. However, there's another fix, which is to change the call to allMethods() to just call methods(). This will not only fix the bug, it's also a performance gain. It fixes the bug because methods() only returns methods declared in this ReferenceType (thus implicitly including the referenceTypeID check). It's a performance gain because allMethods() makes repeated JDWP queries while methods() only makes one. This same problem exists in the method ReferenceTypeImpl.findField(...). The fix is the same: change the call to allFields() to just call fields().
Fixed. Darin, please verify.
Jared, Thank you for your another fix. It is an appropriate solution and certainly more efficient than mine.
Verified code.