JDK-8160244 : skip capture conversion before subtyping if types are parameterizations of the same class or interface
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 9
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • CPU: x86
  • Submitted: 2016-06-22
  • Updated: 2019-08-02
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_majorUnresolved
Related Reports
Blocks :  
Blocks :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Sub Tasks
JDK-8177854 :  
Description
FULL PRODUCT VERSION :
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+121)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+121, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Darwin snazy-ds15.local 15.5.0 Darwin Kernel Version 15.5.0: Tue Apr 19 18:36:36 PDT 2016; root:xnu-3248.50.21~8/RELEASE_X86_64 x86_64


A DESCRIPTION OF THE PROBLEM :
Apache Cassandra fails to compile o.a.c.utils.Throwables at line #79.

https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/utils/Throwables.java#L79

The relevant methods look like this:

    public static <E extends Exception> void perform(DiscreteAction<? extends E> ... actions) throws E
    {
        perform(Stream.of(actions));
    }
    public static <E extends Exception> void perform(Stream<DiscreteAction<? extends E>> actions) throws E
    {
        ...
    }

The above compiles fine w/ JDK8 but fails with JDK9.

As a workaround, I've changed the invocation to "Throwables.<E>perform(Stream.of(actions));"

(FYI: Got a branch that compiles fine working around that issue here: https://github.com/snazy/cassandra/tree/9608-java9-trunk)

REGRESSION.  Last worked in version 8u92

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Checkout Apache Cassandra using current trunk & run "ant jar"


REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
(see above)


Comments
The patch breaks some tests that rely on subtyping to capture the return type of a method reference. But it turns out that the specified capture being performed here is unsound, so the spec needs to be changed: see JDK-8170887.
29-03-2017

Impact=High (regression) Likelihood=Medium (reports from multiple users) Workaround=Low (fix with a cast, parameter type, or explicit type argument) Raising to P2.
29-03-2017

Additional test from RedHat WildFly: import java.util.List; import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; /** * @author Radoslav Husar */ public class JChannelFactory { void createChannel() { ProtocolStackConfiguration configuration = new ProtocolStackConfiguration(); ProtocolStack stack = new ProtocolStack(); stack.addProtocols(Stream.of( Stream.of(configuration.getTransport()), configuration.getProtocols().stream() ).flatMap(Function.identity()).filter(Objects::nonNull).map(pc -> pc.createProtocol(configuration)).collect(Collectors.toList())); // infers 'Object' as type of 'pc' } public abstract static class Protocol { } public interface ProtocolConfiguration<P extends Protocol> { P createProtocol(ProtocolStackConfiguration stackConfiguration); } static class ProtocolStackConfiguration { ProtocolConfiguration<? extends TP> getTransport() { return null; } List<ProtocolConfiguration<? extends Protocol>> getProtocols() { return null; } } static class TP extends Protocol { } public static class ProtocolStack { public ProtocolStack addProtocols(Protocol... prots) { return this; } public ProtocolStack addProtocols(List<Protocol> prots) { return this; } } }
29-03-2017

another related test case reported by JetBrains: import java.util.Optional; import java.util.stream.Stream; import java.lang.invoke.MethodType; import java.util.function.Function; public class TestJetBrains { void foo(Stream<MethodType> methodTypeStream){ Optional<Class<?>> first = methodTypeStream.map(MethodType::returnType).findFirst(); // javac is accepting this code, should fail } void f(Stream<MethodType> methodTypeStream, Class<?> c){ Optional<Class<?>> first = methodTypeStream.map(getReturnType(c)).findFirst(); // javac is correctly rejecting this code } private <T>Function<MethodType, Class<T>> getReturnType(Class<T> c) { return null; } }
04-01-2017

This interacts with an unresolved spec issue, JDK-8016196.
08-09-2016

the change was provoked by the changeset for: JDK-8039214
07-09-2016

test case: import java.util.stream.*; class Throwables { interface DiscreteAction<E extends Exception> {} //@SafeVarargs static public <E extends Exception> void m(DiscreteAction<? extends E>[] actions) throws E { // or DiscreteAction<? extends E>... actions // Throwables.<E>perform(Stream.of(actions)); //works perform(Stream.of(actions)); //fails } static public <E extends Exception> void perform(Stream<DiscreteAction<? extends E actions) throws E {} }
25-08-2016

Below are the test details 8u92 - Pass 9 ea b-121- Fail
24-06-2016