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.