JDK-8043734 : lambda ambiguous reference caused by RuntimeException
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86_64
  • Submitted: 2014-05-14
  • Updated: 2014-06-26
  • Resolved: 2014-06-26
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_majorResolved
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux fgutmann-desktop 3.11.0-20-generic #35~precise1-Ubuntu SMP Fri May 2 21:32:55 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
Method calls with a lamda expression argument which always throws a RuntimeException in the body aren't correctly disambiguated between overloaded methods. The disambiguation problem arises when one of the overloaded methods takes a function with void return type and the other a function with a return value.

void invoke(Runnable r) { }

<T> T invoke(Supplier<T> s) { return null; }

// fails
invoke(() -> {
	throw new RuntimeException();
});
		
// while this works
invoke(() -> {
	if(true) {
		throw new RuntimeException();
	}
});

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the supplied test case.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Compiler should have chosen invoke(Runnable r)
ACTUAL -
Compiler error reference to invoke is ambiguous


ERROR MESSAGES/STACK TRACES THAT OCCUR :
LambdaTest.java:13: error: reference to invoke is ambiguous
		test.invoke(() -> {
		    ^
  both method invoke(Runnable) in LambdaTest and method <T>invoke(Supplier<T>) in LambdaTest match
  where T is a type-variable:
    T extends Object declared in method <T>invoke(Supplier<T>)
1 error


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.function.Supplier;

public class LambdaTest {
	
	private void invoke(Runnable r) { }
	
	private <T> T invoke(Supplier<T> s) { return null; }
	
	public static void main(String [] args) {
		LambdaTest test = new LambdaTest();
		
		// fails
		test.invoke(() -> {
			System.out.println("hello world");
			throw new RuntimeException();
		});
		
		// while this works
		test.invoke(() -> {
			if(true) {
				throw new RuntimeException();
			}
		});
	}
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Wrap throwing of the  RuntimeException in a if(true) statement.