JDK-8026329 : Regression: Type Inferencer can return incorrect type signatures
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P3
  • Status: Resolved
  • Resolution: Not an Issue
  • OS: os_x
  • Submitted: 2013-10-06
  • Updated: 2013-11-11
  • Resolved: 2013-11-11
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
8Resolved
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
openjdk version "1.8.0-jdk8-b108"
OpenJDK Runtime Environment (build 1.8.0-jdk8-b108-20130923)
OpenJDK 64-Bit Server VM (build 25.0-b50, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Darwin Stormbringer.local 12.5.0 Darwin Kernel Version 12.5.0: Sun Sep 29 13:33:47 PDT 2013; root:xnu-2050.48.12~1/RELEASE_X86_64 x86_64

A DESCRIPTION OF THE PROBLEM :
When compiled under Java 8, the sample project found [1] fails to compile. This small project is extracted from a larger commercial project and compiles fine under Java 7, but fails under Java 8.

As originally reported on the jdk8-dev/compiler-dev mailing lists [2], the sample project which uses the popular FEST-Assert testing library now fails to compile it's second test method, with javac reporting that the method 'hasSize' can not be found.

As the FEST-Assert library employs a fairly deep class hierarchy, and also employing some complex generics magic to provide some recursive 'self types' I'm finding it difficult to extract a totally standalone test case that triggers the observed regression.

It would appear, that somewhere along the call chain, the generic 'S' type on FEST's AbstractAssertion class is being returned as itself (AbstractAssertion) rather than the subclass that the method was actually invoked upon (ListAssertion).

So far my method of testing this, is to run "mvn clean compile" under both JDK7 and JDK8, and calling javac directly.

[1] https://github.com/talios/jdk8-covariantfail
[2] http://mail.openjdk.java.net/pipermail/jdk8-dev/2013-September/003226.html

REGRESSION.  Last worked in version 7u40

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Clone the sample project

$ git clone git@github.com:talios/jdk8-covariantfail.git
$ cd jdk8-covariantfail

2. Build with Apache Maven under JDK8

$ JAVA_HOME=~/j2sdk-image mvn clean test



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect the code to compile, and tests to run as expected.
ACTUAL -
~/D/covariantfail (master|???) $ /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/bin/java -version
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b106)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b48, mixed mode)

~/D/covariantfail (master|???) $ /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/bin/javac -version
javac 1.8.0-ea

/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/bin/javac -d /Users/amrk/Dropbox/covariantfail/target/test-classes -classpath /Users/amrk/Dropbox/covariantfail/target/test-classes:/Users/amrk/Dropbox/covariantfail/target/classes:/Users/amrk/.m2/repository/org/testng/testng/6.8.5/testng-6.8.5.jar:/Users/amrk/.m2/repository/junit/junit/4.10/junit-4.10.jar:/Users/amrk/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar:/Users/amrk/.m2/repository/org/beanshell/bsh/2.0b4/bsh-2.0b4.jar:/Users/amrk/.m2/repository/com/beust/jcommander/1.27/jcommander-1.27.jar:/Users/amrk/.m2/repository/org/yaml/snakeyaml/1.6/snakeyaml-1.6.jar:/Users/amrk/.m2/repository/org/easytesting/fest-assert-core/2.0M10/fest-assert-core-2.0M10.jar:/Users/amrk/.m2/repository/org/easytesting/fest-util/1.2.5/fest-util-1.2.5.jar: -sourcepath /Users/amrk/Dropbox/covariantfail/src/test/java: /Users/amrk/Dropbox/covariantfail/src/test/java/com/talios/RegexMatch.java /Users/amrk/Dropbox/covariantfail/src/test/java/com/talios/AppTest.java -g -nowarn -target 1.5 -source 1.5 -encoding UTF-8
/Users/amrk/Dropbox/covariantfail/src/test/java/com/talios/AppTest.java:37: error: cannot find symbol
                .hasSize(3);
                ^
  symbol:   method hasSize(int)
  location: class AbstractAssert
Note: /Users/amrk/Dropbox/covariantfail/src/test/java/com/talios/AppTest.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error


REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
Don't use Java 8 sadly :(
Comments
See [1] to find a detailed explanation of why this is not a bug. [1] http://mail.openjdk.java.net/pipermail/compiler-dev/2013-November/008038.html
11-11-2013

I have created this test, not minimal version, that should recreate the same conditions of the original report: import java.util.*; abstract class GenericAssert<S, A> { public S describedAs(String description) { return null; } } abstract class GroupAssert<S, A> extends GenericAssert<S, A> { public final S isNotEmpty() { return null; } public final S hasSize(int expected) { return null; } S has(Condition<? super A> matcher) { return null; } S doesNotHave(Condition<? super A> matcher) { return null; } } class ListAssert extends GroupAssert<ListAssert, List<?>> {} abstract class Condition<T> { public abstract boolean matches(T value); } class RegexMatch extends Condition { public static RegexMatch regexMatch(String pattern) { return null; } @Override public boolean matches(Object value) { return true; } } public class Test { public static void testHasReturns() { List<String> strings = Arrays.asList("one", "two", "three"); assertThat(strings) .describedAs("test") .isNotEmpty() .has(RegexMatch.regexMatch("th.*")) .doesNotHave(RegexMatch.regexMatch("moo.*")) .hasSize(3); } public static <T> ListAssert assertThat(List<T> actual) { return null; } } I have traversed the different definitions in the fest library getting the original code. The code compiles with jdk8 TL, with warnings but compiles, so I will change the state of this bug to can't reproduce.
01-11-2013

Use this workaround suggested here: http://mail.openjdk.java.net/pipermail/compiler-dev/2013-October/007586.html
11-10-2013