Strange covariant/generics downcasting issue with JDK8

Mark Derricutt mark at talios.com
Mon Sep 23 01:30:44 PDT 2013


Hi all,

Since you're all enjoying JavaOne at the moment I was thinking it was about time that I starting building $work's project under JDK8 and give it some love over my normal small projects and ran into an odd issue with generics/covariant returns that works fine under 7u40 and breaks under 8DP.

I've extracted this into a simple project [1] which I've pushed to github, I've added a comment on the code that breaks under JDK8.

The code in question is:

List<Strings> strings…

assertThat(strings).describedAs("test")
  .isNotEmpty()
  .has(regexMatch("th.*"))
  .doesNotHave(regexMatch("moo.*"))
  .hasSize(3);

When calling assertThat(strings) a class of type ListAssertion is returned, and passed along the call chain.

The problem appears to be that when doesNotHave() returns, javac no longer sees a ListAssertion but rather a top level AbstractAssertion on which doesNotHave is defined:

  /** {@inheritDoc} */
  public S has(Condition<? super A> condition) {
    conditions.assertHas(info, actual, condition);
    return myself;
  }

  /** {@inheritDoc} */
  public S doesNotHave(Condition<? super A> condition) {
    conditions.assertDoesNotHave(info, actual, condition);
    return myself;
  }

Now, both has() and doesNotHave() appear to have the exact same signature, yet commenting out the call to doesNotHave() doesn't appear to trigger what appears to be a down casting to AbstractAssertion which doesn't include a method called hasSize(), the output I see from javac is:

~/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


Is this a known bug in the JDK at all? I'm quite surprised no one else has hit something like this before if its not?




[1] https://github.com/talios/jdk8-covariantfail
[2] https://github.com/talios/jdk8-covariantfail/commit/faa016e57f754230da46e3453b964d497ec065b5#commitcomment-4151896


--
Mark Derricutt — twitter — podcast — blog — google+

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20130923/8454bcc9/attachment.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: Message signed with OpenPGP using GPGMail
Url : http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20130923/8454bcc9/signature.asc 


More information about the compiler-dev mailing list