JDK-8059531 : Anonymous inner class unable to access in-scope variables/methods when annotated
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u20
  • Priority: P4
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: other
  • CPU: x86
  • Submitted: 2014-09-30
  • Updated: 2021-04-15
  • Resolved: 2021-04-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbd_minorResolved
Related Reports
Duplicate :  
Relates :  
Description
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.



Comments
Not reproducible using more recent JDK 8 updates. The related bug JDK-8177316 reproduces if compiled with a JDK 8 update, but *not* if compiled using --release 8 on a subsequent JDK release. The bug also does not reproduce if compiled with JDK 9 or later.
15-04-2021

Presence of annotation should not impede execution of the code. Differences in javac output with and without the type use annotation need further investigation.
05-06-2015