JDK-8051443 : Bogus "no suitable method found" error from javac
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u20
  • Priority: P3
  • Status: Resolved
  • Resolution: Duplicate
  • OS: other
  • CPU: generic
  • Submitted: 2014-07-18
  • Updated: 2014-08-20
  • Resolved: 2014-07-21
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 8
8u40Resolved
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_20-ea"
Java(TM) SE Runtime Environment (build 1.8.0_20-ea-b23)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b22, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
OS X 10.9.4

A DESCRIPTION OF THE PROBLEM :
Some combination of generics and the new Stream APIs is not compiling with 8u20 b23 this is code that compiles find with 8u11.  The error reported is: "no suitable method found", but the 8u11 compiler find a the correct method and the code runs as expected.

REGRESSION.  Last worked in version 8u11

ADDITIONAL REGRESSION INFORMATION: 
This version is working:
java version "1.8.0_11"
Java(TM) SE Runtime Environment (build 1.8.0_11-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.11-b03, mixed mode)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The code being compiled is:

			Class<? extends StandardRootBean> genericFindClass = null;
			// most of these classes implement the SoftDelete interface (defined below)
			if( StringUtils.equals(entityName, Agent.class.getName()) ) {
				genericFindClass = AgentBean.class;
			} else if( StringUtils.equals(entityName, PluginsRepo.class.getName()) ) {
				genericFindClass = PluginsRepoBean.class;
			} else if( StringUtils.equals(entityName, TestSuite.class.getName()) ) {
				genericFindClass = TestSuiteBean.class;
			} else if( StringUtils.equals(entityName, TestSubmission.class.getName()) ) {
				genericFindClass = TestSubmissionBean.class;
			} else if( StringUtils.equals(entityName, User.class.getName()) ) {
				genericFindClass = UserBean.class;
			} else {
				throw new WebServiceException("Unhandled findAll class: "+entityName);
			}
			if( genericFindClass != null ) {
				// Classes that just use the DB findAll() method...
				List<?> dbList = db.findAll(genericFindClass, null);
				// Filter deleted elements if applicable
				if( SoftDelete.class.isAssignableFrom(genericFindClass) ) {
					dbList = dbList.stream().filter( o-> !((SoftDelete)o).isDeletedFlag() ).collect( Collectors.toList()); // <-- error on this line with 8u20
				}
				GenericContainer result = new GenericContainer(
						modelMapper.toXmlLayer( dbList ));
				return result;
			}

This line compiles fine with 8u11 and produces the error message below in 8u20 b23
SoftDelete is an interface defined as:

public interface SoftDelete {
	public boolean isDeletedFlag();
	public void setDeletedFlag(boolean deletedFlag);
}


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Successful compile
ACTUAL -
Users/scott/dev/TestAutomationServer/TASWebService/src/main/java/ca/digitalrapids/tas/ws/TASWS.java:149: error: no suitable method found for collect(Collector<Object,CAP#1,List<Object>>)
					dbList = dbList.stream().filter( o-> !((SoftDelete)o).isDeletedFlag() ).collect( Collectors.toList());
					                                                                       ^
    method Stream.<R#1>collect(Supplier<R#1>,BiConsumer<R#1,? super CAP#2>,BiConsumer<R#1,R#1>) is not applicable
      (cannot infer type-variable(s) R#1
        (actual and formal argument lists differ in length))
    method Stream.<R#2,A>collect(Collector<? super CAP#2,A,R#2>) is not applicable
      (cannot infer type-variable(s) R#2,A,CAP#3,T#2
        (argument mismatch; Collector<CAP#2,CAP#4,List<CAP#2>> cannot be converted to Collector<? super CAP#2,CAP#4,List<CAP#2>>))
  where R#1,T#1,R#2,A,T#2 are type-variables:
    R#1 extends Object declared in method <R#1>collect(Supplier<R#1>,BiConsumer<R#1,? super T#1>,BiConsumer<R#1,R#1>)
    T#1 extends Object declared in interface Stream
    R#2 extends Object declared in method <R#2,A>collect(Collector<? super T#1,A,R#2>)
    A extends Object declared in method <R#2,A>collect(Collector<? super T#1,A,R#2>)
    T#2 extends Object declared in method <T#2>toList()
  where CAP#1,CAP#2,CAP#3,CAP#4 are fresh type-variables:
    CAP#1 extends Object from capture of ?
    CAP#2 extends Object from capture of ?
    CAP#3 extends Object from capture of ?
    CAP#4 extends Object from capture of ?
1 error
:TASWebService:compileJava FAILED


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Users/scott/dev/TestAutomationServer/TASWebService/src/main/java/ca/digitalrapids/tas/ws/TASWS.java:149: error: no suitable method found for collect(Collector<Object,CAP#1,List<Object>>)
					dbList = dbList.stream().filter( o-> !((SoftDelete)o).isDeletedFlag() ).collect( Collectors.toList());
					                                                                       ^
    method Stream.<R#1>collect(Supplier<R#1>,BiConsumer<R#1,? super CAP#2>,BiConsumer<R#1,R#1>) is not applicable
      (cannot infer type-variable(s) R#1
        (actual and formal argument lists differ in length))
    method Stream.<R#2,A>collect(Collector<? super CAP#2,A,R#2>) is not applicable
      (cannot infer type-variable(s) R#2,A,CAP#3,T#2
        (argument mismatch; Collector<CAP#2,CAP#4,List<CAP#2>> cannot be converted to Collector<? super CAP#2,CAP#4,List<CAP#2>>))
  where R#1,T#1,R#2,A,T#2 are type-variables:
    R#1 extends Object declared in method <R#1>collect(Supplier<R#1>,BiConsumer<R#1,? super T#1>,BiConsumer<R#1,R#1>)
    T#1 extends Object declared in interface Stream
    R#2 extends Object declared in method <R#2,A>collect(Collector<? super T#1,A,R#2>)
    A extends Object declared in method <R#2,A>collect(Collector<? super T#1,A,R#2>)
    T#2 extends Object declared in method <T#2>toList()
  where CAP#1,CAP#2,CAP#3,CAP#4 are fresh type-variables:
    CAP#1 extends Object from capture of ?
    CAP#2 extends Object from capture of ?
    CAP#3 extends Object from capture of ?
    CAP#4 extends Object from capture of ?
1 error
:TASWebService:compileJava FAILED

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

import java.util.*;
import java.util.stream.Collectors;

interface SoftDelete {
	public boolean isDeletedFlag();
	public void setDeletedFlag(boolean deletedFlag);
}

class A implements SoftDelete {
	private boolean deleted;
	public boolean isDeletedFlag() {
		return deleted;
	}
	public void setDeletedFlag(boolean deletedFlag) {
		this.deleted = deletedFlag;
	}
}

class B extends A {
	public String toString() { return "B";}
}

class C extends A {
	public String toString() { return "C";}
}


public class Test {
	public static void main(String [] args) throws RuntimeException {

		Class<? extends A> genericFindClass = null;
		if( args.length == 1) {
			genericFindClass = A.class;
		} else {
			genericFindClass = B.class;
		}

		if( genericFindClass != null ) {
			List<?> dbList = findStuff(genericFindClass);
			// Filter deleted elements if applicable
			if( SoftDelete.class.isAssignableFrom(genericFindClass) ) {
				dbList = dbList.stream().filter( o-> !((SoftDelete)o).isDeletedFlag() ).collect( Collectors.toList());
			}
			for (Object o : dbList) {
				System.out.println(o);
			}
		}
	}

	static List<?> findStuff(Class someType) {
		List list = new ArrayList();
		if (someType == B.class)
			list.add(new B());
		else if (someType == C.class)
			list.add(new C());
		return list;
	}
}

---------- END SOURCE ----------


Comments
This bug should be fixed once we backport JDK-8051402 to 8u20
21-07-2014

Offending changeset: http://hg.openjdk.java.net/jdk8u/jdk8u-dev/langtools/rev/1aeb322cf646
21-07-2014

This regression was introduced in 8u20 b20. Hoping the Dev team can evaluate if this change in behaviour was intentional or is a bug.
21-07-2014