... until the collector arrives ...

This "blog" is really just a scratchpad of mine. There is not much of general interest here. Most of the content is scribbled down "live" as I discover things I want to remember. I rarely go back to correct mistakes in older entries. You have been warned :)

2009-06-10

Compiler Bug in Eclipse 3.4

Eclipse 3.4 generates bad bytecode for the following Java:

package a;

abstract class AA {
    final String _value = "the value";

    protected String get() {
        return _value;
    }
}

public abstract class A extends AA {
}


package b;

public class B extends a.A {

    public static void main(String[] args) {
        B b = new B();
        b.doit();
    }

    private void doit() {
        new Runnable() {
            public void run() {
                System.out.println(get()); // IllegalAccessError thrown here
            }
        }.run();
    }

}

An IllegalAccessError is thrown on the indicated line.  A comparison of the bytecode generated by Eclipse versus that from Javac reveals only one significant difference, in the synthetic accessor method generated in B that is necessary to give B$1 (the Runnable) access to the protected method get():

   Javac:   invokevirtual #1;  //Method get:()Ljava/lang/String;

   Eclipse: invokevirtual #33; //Method a/AA.get:()Ljava/lang/String;

The Javac-version is invoking the method by its unqualified name.  The Eclipse version is using a qualified name.  Apparently the JVM gets grumpy with the latter.

This is reported as fixed in Eclipse 3.5 -- see Eclipse's Bugzilla, bug #249107.

Blog Archive