Community
Participate
Working Groups
Build ID: I20071101-2000 Steps To Reproduce: 1. compile the code below (there are two packages) package eclipse.modifier; public abstract class Pool<E extends Pool.Entry<E>> { static abstract class Entry<E extends Entry<E>> { E next; } static public class AbstractEntry<E extends AbstractEntry<E>> extends Entry<E> { } public E m() { return delegate(); } protected abstract E delegate(); } ----------------------- package eclipse.modifier.impl; import eclipse.modifier.Pool; public class EclipseModifierBug { static class MyEntry extends Pool.AbstractEntry<MyEntry> { } static final Pool<MyEntry> pool=new Pool<MyEntry>() { @Override protected MyEntry delegate() { return new MyEntry(); } }; public static void main(String[] args) { MyEntry entry=pool.m(); } } ------------------- 2. run it, the VM throws an IllegalAccessError. the exception: Exception in thread "main" java.lang.IllegalAccessError: tried to access class eclipse.modifier.Entry from class eclipse.modifier.impl.EclipseModifierBug$1 at eclipse.modifier.impl.EclipseModifierBug$1.delegate(EclipseModifierBug.java:1) at eclipse.modifier.Pool.m(Pool.java:8) at eclipse.modifier.impl.EclipseModifierBug.main(EclipseModifierBug.java:14) it works if the code is compiles with javac. More information: In my opinion, the VM tries to call the bridge method in Pool but bacuse this bridge returns an non visible class (MyEntry), it fails. javac seems to generate another bridge that returns an AbstractEntry wich is visible. By the way, i'am not sure this code is legal, This bug may be related to Bug 215843. Rémi
This bug is (unfortunately) not related to bug 215843.
On a variation, it becomes visible we do accept invalid code: public class X { static class MyEntry extends Pool.AbstractEntry<MyEntry> { } static final Pool<MyEntry> pool=new Pool<MyEntry>() { @Override protected MyEntry delegate() { return new MyEntry(); } }; public static void main(String[] args) { MyEntry entry=pool.m(); } } abstract class Pool<E extends Pool.Entry<E>> { private static abstract class Entry<E extends Entry<E>> { E next; } static public class AbstractEntry<E extends AbstractEntry<E>> extends Entry<E> { } public E m() { System.out.println("SUCCESS"); return delegate(); } protected abstract E delegate(); }
Pls ignore comment 2, this is a different issue (and there I believe we are right). The original problem comes from a bogus checkcast inserted in the bridge method body. Its presence forces the VM to perform a invalid class access, hence crash at runtime. Basically, the cast shouldn't have been inserted in the first place, and the condition for detecting the need for the cast is guilty.
Added GenericTypeTest#test1243-1246
Created attachment 87654 [details] Proposed patch
Released for 3.4M5
Fixed
Created attachment 87681 [details] Patch for 3.3.x
This bug came in fairly late for 3.3.2. If we recontribute for 3.3.2 for another more critical issue, then I would consider addressing this one as well. It is quite a simple fix, and without it we may produce corrupted binaries for quite some time. This is no regression though. Remi - how critical is that for you?
(In reply to comment #9) > This bug came in fairly late for 3.3.2. If we recontribute for 3.3.2 for > another more critical issue, then I would consider addressing this one as well. > It is quite a simple fix, and without it we may produce corrupted binaries for > quite some time. > > This is no regression though. > > Remi - how critical is that for you? > Not critical here, there is a simple workaround declare Pool.Entry public. It was a mistake in my code to declare it with a package visibility modifier. Otherwise, eclipse compiler inserts a useless cast, it's not a big deal, the VM will remove it. many thanks for your diligence. Rémi
Note: to reproduce the problem described in comment 0, one must run with -verify Verified for 3.4M5 using I20080204-0010
Released fix in 3.3.x maintenance branch (post 3.3.2)