FULL PRODUCT VERSION :
On Mac OSX:
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
On Windows:
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)
For some reason, running this code in Eclipse does not fail.
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
Mac OS 10.9.5
A DESCRIPTION OF THE PROBLEM :
When an anonymous inner class extending an abstract class is annotated with a TYPE_USE annotation, the implementation code is unable to access methods and variables on the local class at runtime. Execution results in "Exception in thread "main" java.lang.NoSuchFieldError: this$0".
If the annotation is removed, the code will work just fine.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See the super-simplified attached code. Removing @MyAnnot from the class allows it to work, but then the instance cannot be checked for the annotation elsewhere in the system.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The output should be "5a".
ACTUAL -
Exception in thread "main" java.lang.NoSuchFieldError: this$0
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class TestFailure {
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnot {
}
public static abstract class MyCallable {
protected abstract String getString(int number);
}
public static void main(String[] args) {
System.out.println(new MyTester().createCallable().getString(5));
}
public static class MyTester {
private String getA(){
return "a";
}
private String a = "a";
protected MyCallable createCallable() {
return new MyCallable() {
@Override
protected String getString(int number) {
return number + getA();
// or: return number + a;
}
};
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
If a local variable is what cannot be accessed, making it final avoids the bug. Using final on a method doesn't help.