JDK-8184989 : Incorrect class file created when passing lambda in inner class constructor and outer is subclass
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u141,9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux_ubuntu
  • CPU: x86
  • Submitted: 2017-07-20
  • Updated: 2017-10-21
  • Resolved: 2017-10-16
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.
JDK 10
10 b28Fixed
Related Reports
Relates :  
Description
The fix for JDK-8129740 is incomplete. It fails on cases when outer class is a subclass and the entities of it's superclass are referred to in lambda expression.

Reproduced on:
javac 1.8.0_141
and
javac from jdk9 build 9+178

The test source:
A.java
public class A {
    public boolean test(){
        return true;
    }
    class AA{
        public AA(Condition condition) {
        }
    }
}
Condition.java
public interface Condition<T> {
    boolean check(T t);
}
B.java
public class B extends A {
    private final BA myBA;
    public B() {
        myBA = new BA();
    }
    public class BA extends AA{
        public BA() {
            super(o -> test());
        }
    }
    public static void main(String[] args) {
        B b = new B();
        System.out.println(b);
    }
}

source compiles but execution of B fails with:
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    B$BA.lambda$new$0(LB;Ljava/lang/Object;)Z @1: getfield
  Reason:
    Type 'B' (current frame, stack[0]) is not assignable to 'B$BA'
  Current Frame:
    bci: @1
    flags: { }
    locals: { 'B', 'java/lang/Object' }
    stack: { 'B' }
  Bytecode:
    0x0000000: 2ab4 0001 b600 04ac                    

	at B.<init>(B.java:6)
	at B.main(B.java:17)

Comments
I think that the proposed fix could fail in some cases. See the suggested improvement http://mail.openjdk.java.net/pipermail/compiler-dev/2017-August/011035.html
04-08-2017

suggested fix is http://cr.openjdk.java.net/~apetushkov/8184989/webrev/
20-07-2017

Apparently all superclasses of outer class(es) should be considered when looking up for symbol owner to decide whether we need to translate entity through which we perform invocation (which is originally "this", but since "this" was eliminated we change to "Outer.this")
20-07-2017