| Summary: | EventDispatcher#getFocusOwner protected visibility leads to verify error | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Tools] GEF | Reporter: | Jens Von Pilgrim <developer> | ||||
| Component: | GEF-Legacy Draw2d | Assignee: | Anthony Hunter <ahunter.eclipse> | ||||
| Status: | RESOLVED FIXED | QA Contact: | |||||
| Severity: | blocker | ||||||
| Priority: | P3 | CC: | ahunter.eclipse, heiko.boettger, remy.suen | ||||
| Version: | 3.6 | ||||||
| Target Milestone: | 3.6.0 (Helios) RC1 | ||||||
| Hardware: | All | ||||||
| OS: | All | ||||||
| Whiteboard: | |||||||
| Bug Depends on: | 241767 | ||||||
| Bug Blocks: | |||||||
| Attachments: |
|
||||||
|
Description
Jens Von Pilgrim
I had the same problem when I was trying to run GEF3D on e4. Changing the GEF3D variant's method to be protected didn't help (well, it fixed the compiler error anyway). When I made the originating method in EventDispatcher public then the VerifyError went away. ok, will investigate a solution in 3.6 M7. Created attachment 163558 [details] Simplified projects reproducing the error I tried to reproduce the error with simplified Java classes. I finally found the problem (thanks to http://www.coderanch.com/forums/forums/posts/watch/0/328067 ): It's the classloaders. I have attached an archive with two simple projects: APlugin (=draw2D) and BPlugin (=draw3d). This is the overall structure: APlugin: A.java: package a; public class A { // = EventDispatcher protected void m() { // = getFocusOwner() }; } BPlugin: B.java package a; public class B extends A { // = EventDispatcher3D private A x; public B(A x) { this.x = x; } @Override protected void m() { x.m(); } } BPlugin contains a view (in order to get loaded). In its activator, you'll find the following code: public Activator() { new B(new A()); // got you! } This is where the error occurs: Caused by: java.lang.VerifyError: (class: a/B, method: m signature: ()V) Bad access to protected data at bplugin.Activator.<init>(Activator.java:24) As explained by Ernest Friedman-Hill (see URL above) the problem is, that two packages with the same name are in fact different when loaded with different class loaders. From the VM spec (http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html): "R is either protected or package private (that is, neither public nor protected nor private), and is declared by a class in the same runtime package as D." Apparently, package and runtime package are different. Frankly, I'm not a VM expert. What confuses me most is, that it's all working with package visibility, because this should apply to the very same "rule", should it? I admit that we are using a dirty hack in Draw3D by defining the same package as in Draw2D. Anyway, we absolutely need the EventDispatcher class to be publicly accessible and subclassable (or at least from outside Draw2D). (In reply to comment #3) > I admit that we are using a dirty hack in Draw3D by defining the same package > as in Draw2D. Anyway, we absolutely need the EventDispatcher class to be > publicly accessible and subclassable (or at least from outside Draw2D). Are you planning on fixing this hack? You guys did not do a release of Draw3D with org.eclipse.draw2d packages did you? Anyway, I will look and see if we can make the methods public. > Are you planning on fixing this hack? OK, GEF3D itself is a kind of hack ;-) IMHO it's impossible to create something like GEF3D without some hacks... (at least when a framework uses non-public access). But seriously, we absolutely rely on that specific hack as we need to replace the EventDispatcher with a 3D version. Actually, there are some other dirty things, too, and I already reported some of these issues (https://bugs.eclipse.org/bugs/show_bug.cgi?id=278559, https://bugs.eclipse.org/bugs/show_bug.cgi?id=290531), some more issues are GMF related. I didn't added more bugs because these bug reports were ignored so far (except this bug, which I marked as a blocker). In general I'm wondering why so much methods (and fields with no public/protected accessors) are private or package visible only. Fortunately, EventDispatcher is the only case in which we were forced to "camouflage" our classes with a foreign package name. Other problems of that type: - org.eclipse.draw2d.FreeformHelper, we duplicated the code simply because FreeformHelper is package visible only... - org.eclipse.draw2d.MouseEvent has a package visible constructor only. Fortunately we do not need that constructor in Draw3D anymore, but it was a blocker in a predecessor version of GEF3D in which I used Java3D (which is AWT based, that is, I needed to create such a MouseEvent in order to propagate the AWT events to Draw2D). Do you think I should file bug reports about these issues (that is, is there a chance these things get changed?) > You guys did not do a release of Draw3D with org.eclipse.draw2d packages did you? No, we didn't release Draw3D yet, since there is no release of GEF3D at all (I planned to create a release including JOGL, but unfortunately JOGL is under IP review for more than a year now, but that's a different issue). > Anyway, I will look and see if we can make the methods public. That would be great! Cheers, Jens We released 3.6 M7 today so moving unresolved bugs to 3.6 RC1. We need to re-access if we can complete these for Helios. I fixed the method we changed in M6 to public. Can you confirm this is sufficient? (In reply to comment #7) > I fixed the method we changed in M6 to public. Can you confirm this is > sufficient? Reopen if not. It's working, thank you very much! |