2

One of the tests below is not working. Why?

public class SortedInterfacesTest {

private static final Logger log = LoggerFactory.getLogger(SortedInterfacesTest.class);

<T> void forAll(Consumer<T> consumer, T... values) { }

@Test
public void firstTest() {
    forAll(Shape::draw, new MyShape(), new Universal());
}

@Test
public void secondTest() {
    log.info("\njava.version {}", System.getProperty("java.version"));
    forAll(Picture::draw, new MyPicture(), new Universal());
}

interface Shape { void draw(); }
interface Marker { }
interface Picture { void draw(); }

class MyShape implements Marker, Shape { public void draw() {} }
class MyPicture implements Marker, Picture { public void draw() {} }
class Universal implements Marker, Picture, Shape { public void draw() {} }
}

After all, a pair of Shape and MyShape a symmetric pair of Picture and MyPicture.

Second test fails with the following error(use cli: mvn.exe test):

-------------------------------------------------------
 T E S T S (Java.version: 1.8.0_102)
-------------------------------------------------------
Running SortedInterfacesTest
01:36:28.234 [main] INFO  SortedInterfacesTest - 
java.version 1.8.0_102
Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.223 sec <<< FAILURE!
secondTest(SortedInterfacesTest)  Time elapsed: 0.009 sec  <<< ERROR!
java.lang.BootstrapMethodError: call site initialization exception
    at java.lang.invoke.CallSite.makeSite(Unknown Source)
    at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(Unknown Source)
    at java.lang.invoke.MethodHandleNatives.linkCallSite(Unknown Source)
    at SortedInterfacesTest.secondTest(SortedInterfacesTest.java:18)

Stacktrace on Java 9+181:

java.lang.BootstrapMethodError: call site initialization exception

    at java.base/java.lang.invoke.CallSite.makeSite(CallSite.java:385)
    at java.base/java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:250)
    at java.base/java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:240)
    at play.Play.firstTest(Play.java:12)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type interface play.Play$Marker; not a subtype of implementation type interface play.Play$Shape
    at java.base/java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:254)
    at java.base/java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:311)
    at java.base/java.lang.invoke.CallSite.makeSite(CallSite.java:332)
    ... 25 more
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
Ilya
  • 720
  • 6
  • 14
  • 1
    which one is not working, and what is the error you're getting? – Nir Levy Nov 16 '17 at 21:28
  • 3
    I have downvoted this question because you have posted code on here without specifying what is wrong with it. We expect to see what you expect the code to do, why you expect it to do this, what it is actually doing, and why it is wrong. Please [edit] your question to include this information, and then I will consider retracting my downvote. See: [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) – Joe C Nov 16 '17 at 21:28
  • 3
    There is no interface named `SortedInterfaces` in your code, so how can compilation fail with that name? – Andreas Nov 16 '17 at 21:38
  • 1
    Please state the version of Java you're using (Java 8 I assume). In Java 9 I can repro with a different error... both errors are related to `interface Marker {}` if you'll declare it *after* the other two interfaces it will solve your issue. To be honest - I'm not sure why... (and I'm also curious!) – Nir Alfasi Nov 16 '17 at 21:38
  • @JoeC maybe the wording can be improved but he definitely created MCVE - so I'm not sure what do you mean... – Nir Alfasi Nov 16 '17 at 21:39
  • 1
    @Andreas I'm getting `java.lang.BootstrapMethodError: call site initialization exception` on Java **9+181** – Nir Alfasi Nov 16 '17 at 21:40
  • 1
    @Ilya any additional information should go into the question - don't post it in the comments section! – Nir Alfasi Nov 16 '17 at 21:44
  • 1
    Are you sure only one of them is not working? With the same Java version both of them fail for me. – Oleg Nov 16 '17 at 21:48
  • If you write the type parameter explicitly, or use a normal lambda expression instead of a method reference, it works just fine. – Bubletan Nov 16 '17 at 22:08
  • 4
    Seems you have hit [this issue](https://stackoverflow.com/a/34160332/2711488). Unfortunately, [this bug report](https://bugs.openjdk.java.net/browse/JDK-8058112) has been closed as “fixed”. So you can try to annoy Oracle unit they reopen the bug or downvote [this answer](https://stackoverflow.com/a/27138640/2711488) that claims that the bug has been fixed; whether it helps, I don't know… – Holger Nov 16 '17 at 22:08
  • 4
    You should be able to workaround it with explicit types `this.forAll(Shape::draw, new MyShape(), new Universal());` and `this.forAll(Picture::draw, new MyPicture(), new Universal());`. – Holger Nov 16 '17 at 22:14
  • @Holger I get the error with eclipse compiler, with `javac` it works fine. So at least based on my test Oracle did fix the bug, not sure what OP is using. – Oleg Nov 16 '17 at 22:28
  • 1
    @Oleg: which version? Since the order of the types in the inferred intersection type is unspecified, it is a matter of luck, whether the `Marker` is first or not, e.g. in my tests with `javac`, changing the order of the interface declarations changed the outcome. Of course, for Eclipse, the version matters as well, in one of the older questions, it has been confirmed that Eclipse has a similar bug (two years ago). – Holger Nov 16 '17 at 22:33
  • @Oleg that's weird, both fail with `Oxygen 4.7.1a` for me – Eugene Nov 16 '17 at 22:35
  • 1
    @Eugene: https://bugs.eclipse.org/bugs/show_bug.cgi?id=483219 still open, targeted for 4.8 – Holger Nov 16 '17 at 22:37
  • 1
    @Holger My bad, I mixed up my test. After fixing it I got the same results as you with `javac`, you were correct to blame Oracle. In eclipse ecj 4.6.1 it fails all the time regardless of order. – Oleg Nov 16 '17 at 22:44
  • 1
    Seems [this issue](https://bugs.openjdk.java.net/browse/JDK-8141508), fixed in Java9, also is only fixed as much as its included test case requires it. – Holger Nov 16 '17 at 22:53
  • Thanks to all. I realized this is a bug and it is not fixed – Ilya Nov 16 '17 at 23:53
  • 1
    @Holger No need to annoy Oracle about anything; just ask someone to have a look. – Stuart Marks Nov 17 '17 at 06:45
  • 1
    @Stuart Marks: I just supposed, being queried about the same bug over and over again, *is* annoying, though, those who close bugs as fixed, despite being still there might deserve it. Robert Field got several comments at his answer that the bug is not fixed, but did not react at all within the last two years… – Holger Nov 17 '17 at 07:16
  • 1
    @Holger I don't think Robert is very active here or on social media, so he might not be seeing the notifications. Regardless, I've pointed our compiler team at this, so I hope one of them can tackle the issue. – Stuart Marks Nov 17 '17 at 08:29
  • 1
    @Stuart Marks: he has posted several answers this year. However, I didn’t want to focus on a single person. The link is included in the bug report, but apparently, no-one took the time to follow it to e.g. use more than one test case. Well, I had left a comment there, if I had an account. – Holger Nov 17 '17 at 08:45
  • 1
    @Holger The fact is that Stack Overflow comments are an unreliable way to get feedback to the JDK team. If you think there's a bug that hasn't gotten any attention, please file a bug report at http://bugreport.java.com/ . – Stuart Marks Nov 17 '17 at 17:45
  • @Stuart Marks: it would be much easier, if adding information to existing bug reports would be allowed. Why should users file an entirely new bug report when the bug report already exists? What advantage has this strategy? – Holger Nov 17 '17 at 19:47
  • @Holger In OpenJDK we generally don't reopen bugs that have been marked as fixed (even if the fix has failed) in order to keep to one changeset per fixed bug. If an additional change needs to be made, a new bug report would need to be opened anyway. JDK engineers are used to this. Sometimes adding a comment to an open bug is called for, but unfortunately there's no good way to do this without an OpenJDK JIRA account. Sometimes a submitter will file a second bug with followup information. This isn't entirely unreasonable; it's simple enough to transfer the information to the original. – Stuart Marks Nov 18 '17 at 00:25
  • 3
    New bug filed: [JDK-8191655](https://bugs.openjdk.java.net/browse/JDK-8191655). The previous bug [JDK-8058112](https://bugs.openjdk.java.net/browse/JDK-8058112) fixed only part of the problem, but the code here shows a case that remains unfixed. Sorry for any confusion. – Stuart Marks Nov 21 '17 at 16:54
  • 1
    @alfasin Thanks for mentioning this to me on Twitter! I'm not sure what should happen with this SO question now. It's not really a duplicate of the other question. Is it worth reopening it? I don't think it should be deleted though. – Stuart Marks Nov 21 '17 at 16:58
  • @StuartMarks since it's not a dup I re-opened it. Thanks for following up on it - much appreciated! – Nir Alfasi Nov 21 '17 at 17:02
  • Please add an answer to the question since it was answered in the comments :) – Steffen Harbich Nov 23 '17 at 12:32

1 Answers1

4

A new bug has been registered as JDK-8191655. Workaround: use a normal lambda expression instead of a method reference.

Ilya
  • 720
  • 6
  • 14