Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8059531

Anonymous inner class unable to access in-scope variables/methods when annotated

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Cannot Reproduce
    • Icon: P4 P4
    • tbd
    • 8u20
    • tools
    • x86
    • other

      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.


            darcy Joe Darcy
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: