JDK-8066981 : Code compiles but throws java.lang.VerifyError when run
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u11
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_7
  • CPU: x86
  • Submitted: 2014-08-20
  • Updated: 2014-12-09
  • Resolved: 2014-08-27
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_11"
Java(TM) SE Runtime Environment (build 1.8.0_11-b12)
Java HotSpot(TM) Client VM (build 25.11-b03, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
Using an outer class field reference in the call to the super constructor of an inner class that extends another inner class results in no compiler errors but generates a VerifyError when run.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the minimal example entered at 'Source code for an executable test case' below.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Successful execution without error.
ACTUAL -
VerifyError

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    bug/Problem$Sub.<init>(Lbug/Problem;)V @8: invokedynamic
  Reason:
    Type uninitializedThis (current frame, stack[2]) is not assignable to 'bug/Problem$Sub'
  Current Frame:
    bci: @8
    flags: { flagThisUninit }
    locals: { uninitializedThis, 'bug/Problem' }
    stack: { uninitializedThis, 'bug/Problem', uninitializedThis }
  Bytecode:
    0000000: 2a2b b500 022a 2b2a ba00 0300 00b7 0004
    0000010: b1                                     

	at bug.Problem.main(Problem.java:8)
Java Result: 1

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Problem {

  private final String text = "";

  public static void main(String[] args) {
    new Problem().new Sub();
  }

  private class Super<T> {

    public Super(java.util.function.Consumer<T> consumer) {
    }
  }

  private class Sub extends Super<String> {

    public Sub() {
      super(s -> System.out.println(text));
    }
  }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use an anonymous inner class instead of a lambda for the parameter.  e.g.

...
    public Sub() {
      //super(s -> System.out.println(text));
      super(new java.util.function.Consumer<String>() {
        @Override
        public void accept(String t) {
          System.out.println(text);
        }
      });
    }
...