Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 436350

Summary: [1.8][compiler] Missing bridge method in interface results in AbstractMethodError
Product: [Eclipse Project] JDT Reporter: Tobias Grasl <toby>
Component: CoreAssignee: Srikanth Sankaran <srikanth_sankaran>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: jarthana, shankhba, srikanth_sankaran, stephan.herrmann, toby
Version: 4.4Flags: jarthana: review+
Target Milestone: 4.4.1   
Hardware: Macintosh   
OS: Mac OS X   
Whiteboard:
Attachments:
Description Flags
Code that demonstrates the bug none

Description Tobias Grasl CLA 2014-06-02 07:08:52 EDT
Created attachment 243774 [details]
Code that demonstrates the bug

In the attached sample I have a Generic Interface which accepts generic objects, and a specialised subinterface which accepts specialised objects, and provides a default method for the generic interface's method, which delegates to the specialised implementation.

If I implement the specialised method in an anonymous class, and pass it to some code that calls the generic method, then the code correctly executes and passed through to the specialised method.

However, if, rather than implementing the anonymous class, I use a lambda expression, the code compiles fine, but at runtime I get an AbstractMethodError "java.lang.AbstractMethodError: Method LambdaBugDemo$$Lambda$1.reduce(Ljava/util/Iterator;)Ljava/lang/Object". Apparently, the default method is not picked up.

This code compiles and runs fine on Oracle JDK 1.8_05 for OsX. It compiles fine in eclipse, but the generated code throughs the error as specified.

The attached java file contains a full demonstration of the problem.
Comment 1 Tobias Grasl CLA 2014-06-02 07:09:28 EDT
I should add, I tested it in Kepler SR2 and Luna.
Comment 2 Srikanth Sankaran CLA 2014-08-05 01:52:33 EDT
Retargetting to M2, as I don't expect to finish work on these before this week's build(s)
Comment 3 Srikanth Sankaran CLA 2014-08-26 01:09:39 EDT
Much shorter/simpler test case that still shows the problem: 

// --
public class X {
	public static void main(String[] args) {
		reduce((DoubleInterface) i -> {
			return 0;
		});
	}
	static Double reduce(GenericInterface<Double> r) {
		return r.reduce(null);
	}
}
interface GenericInterface<T> {
	T reduce(Integer i);
}
interface DoubleInterface extends GenericInterface<Double> {
	default Double reduce(Integer i) {
		return 0.0;
	}
	double reduce(String s);
}
// --
Comment 4 Srikanth Sankaran CLA 2014-08-26 01:18:47 EDT
Interface DoubleInterface is missing a bridge to accommodate for the difference
in return type erasure. In the case of the anonymous class, this bridge gets
emitted into the class. Emitting it into the interface would be the right thing
to accommodate for the lambda case. Looking into it.
Comment 5 Srikanth Sankaran CLA 2014-08-26 01:30:08 EDT
*** Bug 421747 has been marked as a duplicate of this bug. ***
Comment 7 Srikanth Sankaran CLA 2014-08-26 02:18:45 EDT
Jay, I think this should be backported to SR1. Please review.
Comment 8 Jay Arthanareeswaran CLA 2014-08-26 12:49:54 EDT
Patch looks safe for SR1 to me.
Comment 9 Jay Arthanareeswaran CLA 2014-08-26 12:50:51 EDT
(In reply to Jayaprakash Arthanareeswaran from comment #8)
> Patch looks safe for SR1 to me.

Tests ran fine locally. Will release after looking at tonight's I build result.
Comment 10 Jay Arthanareeswaran CLA 2014-08-27 00:09:28 EDT
Released in R4_4_maintenance.
Comment 11 shankha banerjee CLA 2014-08-28 05:13:17 EDT
Verified for 4.4.1 with build M20140827-0800.

and

Verified for 4.5 M2 with build N20140827-2000.