Community
Participate
Working Groups
Draw2d has a listener interface called AncestorListener with 3 methods. It has an adapter implementation called AncestorListener.Stub. In another class I am creating an anonymous AncestorListener.Stub(){}. This listener gets added to a List using addAncestorListener(AncestorListener listener): ancestorListener = new AncestorListener.Stub() { public void ancestorAdded(IFigure ancestor) { } public void ancestorRemoved(IFigure ancestor) { } public void ancestorMoved(IFigure ancestor) { placeCellEditor(); } }; The field ancestorListener is typed as AncestorListener. Later, when enumerating through the listeners, I get a ClassCastException. This is impossible. Here is the interface: public interface AncestorListener { /** * Called when an ancestor has been added into the listening * figure's hierarchy. */ public void ancestorAdded(IFigure ancestor); /** * Called when an ancestor has moved to a new location. */ public void ancestorMoved(IFigure ancestor); /** * Called when an ancestor has been removed from the listening * figure's hierarchy. */ public void ancestorRemoved(IFigure ancestor); class Stub implements AncestorListener { public void ancestorMoved(IFigure ancestor){} public void ancestorAdded(IFigure ancestor){} public void ancestorRemoved(IFigure ancestor){} } } If I change the anonymous implementer to be "new AncestorListener(){}", implementing all of the methods, the class cast problem goes away. If I add back in ".Stub" to make it "new AncestorListener.Stub(){}", it comes back. Even after shutdown, restart, and full build.
Maybe I'm missing some steps, but the following works fine: X.java [import java.util.ArrayList; import java.util.Iterator; public class X { AncestorListener listener = new AncestorListener.Stub() { public void ancestorAdded(Object ancestor) { } public void ancestorMoved(Object ancestor) { } public void ancestorRemoved(Object ancestor) { } }; public static void main(String[] arguments) { new X().foo(); } void foo(){ ArrayList list = new ArrayList(); list.add(this.listener); Iterator iter = list.iterator(); while (iter.hasNext()) { AncestorListener element = (AncestorListener) iter.next (); System.out.println(element); } } }] AncestorListener.java [public interface AncestorListener { /** * Called when an ancestor has been added into the listening * figure's hierarchy. */ public void ancestorAdded(Object ancestor); /** * Called when an ancestor has moved to a new location. */ public void ancestorMoved(Object ancestor); /** * Called when an ancestor has been removed from the listening * figure's hierarchy. */ public void ancestorRemoved(Object ancestor); class Stub implements AncestorListener { public void ancestorMoved(Object ancestor) { } public void ancestorAdded(Object ancestor) { } public void ancestorRemoved(Object ancestor) { } } } ]
I can reproduce this over and over in my workspace. Can you think of something I would be doing wrong?
You can now reproduce this by checking out: org.eclipse.gef org.eclipse.draw2d org.eclipse.gef.examples.logic from the dev.eclipse.org/eclipse/tools CVS server. Load this into an F2 workspace, which also has F2 org.eclipse.ui + dependencies loaded as PDE projects. Launch the runtime workbench. 1) Run the Logic Wizard on a simple project, and create a 4-bit adder in the simple project. 2) Drop a label inside a Circuit with some other parts in it. Resize the circuit until it has scrollbars. 3) double click on the label. 4) Scroll the circuit. This will work until you make the following change. Shutdown the runtime workbench and then change line #169 of DirectEditManager to read: ancestorListener = new AncestorListener.Stub() { If you do this, you will get ClassCastException during step 4 above.
Runtime JRE is SUN JRE 1.3.1 R08
I'll give it a try then, however did you change the default compiler settings ?
Did you fail with the exact test case I pasted in before ?
Haven't been able to reproduce so far. One question though: could you have got confused by the presence of javax.swing.event.AncestorListener ?
I don't see any imports to that type in my code, do you? It should be sufficient to verify the AncestorListener.Stub is not implementing the wrong interface, because making the anonymous inner class the Stub versus the interface is what causes the problem. You cannot reproduce this on F2? Compiler settings are first two Error, next 4 Warnings, the rest ignore. I think this is default.
I cannot reproduce so far (missing com.ibm.etools. projects). But did you reproduce the problem with the 2 files I pasted in this PR ?
As far as I can tell, the project are released to HEAD in eclipse/tools. What specifically can you not find? I'll try your smaller test case, just for fun.
Smaller test does not reproduce the problem. I could put my workspace on wall "I" if it would help.
Missing projects are com.ibm.etools.draw2d and com.ibm.etools.gef. A constructed workspace would indeed be interesting.
I manually recreated the missing projects from an old version of them I had around. These are likely obsolete, but exposed the fact that at that time, AncestorListener.Stub was a subclass of Object, not an implementation of AncestorListener (com.ibm.etools.draw2d). Please double check that Stub hierarchy is effectively what it should be. The one which matters is the one found first on the classpath order from DirectEditManager (in #hookCellEditor).
The problem is specific to my workspace. I *did* make the correction in this workspace that Stub was not implementing the interface. Obviously I did this right away because otherwise I would have a compile error. I tried to recreate the problem in a fresh workspace and could not. However, I did reproduce the problem twice because I "cloned" (copied) my workspace prior to changing the code. I cloned my workspace in order to release the code to dev.eclipse.org. When I found the problem in my internal workspace, I was able to reproduce it again in my "Open Source" workspace. The ancestor listener was originally a FigureListener, so the entire change involved: change a field, anonymous inner-class, and then fixing Stub.
Might then be an incremental compilation bug, where an obsolete type would not have been rebuilt... sounds weird. Are you running in autobuild mode ? Did you cancel a build before ?
I always run in autobuild, but even exiting the workbench and invoking full- build doesn't fix the problem. Have you reproduced it?
No we cannot reproduce so far.
Was able to drop label without any problem using your workspace (had to rebuild completely after adjusting JRE to my local install). - launched Eclipse using launch config (disabled all external plugins) - created simple project P - add other resource: Examples/GEF/Logic Diagram - selected 4-bits adder - select label in toolbar, dropped it into Circuit #9 (just below Circuit #8) - could scroll Circuit #9 without getting any exception
and the anonymous inner class is an AncestorListener.Stub()? I zipped it up to you without the .Stub() being used.
Yes, I tried with both cases, using member type Stub or not, didn't make a difference, as one would expect.
There is no evidence of a classfile being wrong, even checking the binaries generated in Randy's original workspace did show the proper hierarchy. Closing as not reproduceable.