-
Bug
-
Resolution: Unresolved
-
P4
-
9, 11, 17, 19, 20, 21
ADDITIONAL SYSTEM INFORMATION :
JDK 19:
java version "19.0.2" 2023-01-17
Java(TM) SE Runtime Environment (build 19.0.2+7-44)
Java HotSpot(TM) 64-Bit Server VM (build 19.0.2+7-44, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
Hello,
While updating a large code base
I encountered a compilation error
in JDK 19
which does not happen in JDK 8.
I eventually managed to reproduce it
in the test code below.
JDK 8 compiles the code OK.
JDK 19 produces the following error:
error: getContext() in AbstractSomething cannot implement getContext() in Something
return type CAP#1 is not compatible with CAP#2
where Ctx#1,Ctx#2 are type-variables:
Ctx#1 extends Context declared in class AbstractSomething
Ctx#2 extends Context declared in interface Something
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends Context from capture of ? extends Context
CAP#2 extends Context from capture of ? extends Context
1 error
The error does not include any source filenames or line numbers.
The error suggests that something is wrong in the AbstractSomething class
but the actual cause of the problem
seems to be the generics of the stream() code in the getSomethings() method
which is not mentioned in the error.
JDK 19 will compile the code
after replacing .map(c -> construct(c))
with .map(this::construct)
JDK 8 compiles either version of the code.
This feels like a regression in the compiler
but maybe I am missing something?
REGRESSION : Last worked in version 8u361
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile the test code using JDK 8
2. Code compiles OK
3. Compile the test code using JDK 19
4. An unexpected error is produced
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code is expected to compile JDK 19
ACTUAL -
Error message produced by JDK 19:
error: getContext() in AbstractSomething cannot implement getContext() in Something
return type CAP#1 is not compatible with CAP#2
where Ctx#1,Ctx#2 are type-variables:
Ctx#1 extends Context declared in class AbstractSomething
Ctx#2 extends Context declared in interface Something
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends Context from capture of ? extends Context
CAP#2 extends Context from capture of ? extends Context
1 error
---------- BEGIN SOURCE ----------
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Test {
List<Something> getSomethings() {
return Stream.of(
SomethingA.class,
SomethingB.class)
.map(c -> construct(c)) // UNEXPECTED COMPILER ERROR IN JDK 17+19 (BUT COMPILES IN JDK 8)
// .map(this::construct) // COMPILES IN JDK 17+19+8
.collect(Collectors.toList());
}
Something construct(Class<? extends Something> clazz) {
return null;
}
interface Context { }
interface ContextA extends Context { }
interface ContextB extends Context { }
interface Something<Ctx extends Context> {
Ctx getContext();
}
interface SpecificSomething<Ctx extends Context>
extends Something<Ctx> { }
abstract static class AbstractSomething<Ctx extends Context>
implements Something<Ctx> {
@Override
public Ctx getContext() {
return null;
}
}
static class SomethingA
extends AbstractSomething<ContextA>
implements SpecificSomething<ContextA> { }
static class SomethingB
extends AbstractSomething<ContextB>
implements SpecificSomething<ContextB> { }
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
JDK 19 will compile the code
after replacing .map(c -> construct(c))
with .map(this::construct)
FREQUENCY : always
JDK 19:
java version "19.0.2" 2023-01-17
Java(TM) SE Runtime Environment (build 19.0.2+7-44)
Java HotSpot(TM) 64-Bit Server VM (build 19.0.2+7-44, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
Hello,
While updating a large code base
I encountered a compilation error
in JDK 19
which does not happen in JDK 8.
I eventually managed to reproduce it
in the test code below.
JDK 8 compiles the code OK.
JDK 19 produces the following error:
error: getContext() in AbstractSomething cannot implement getContext() in Something
return type CAP#1 is not compatible with CAP#2
where Ctx#1,Ctx#2 are type-variables:
Ctx#1 extends Context declared in class AbstractSomething
Ctx#2 extends Context declared in interface Something
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends Context from capture of ? extends Context
CAP#2 extends Context from capture of ? extends Context
1 error
The error does not include any source filenames or line numbers.
The error suggests that something is wrong in the AbstractSomething class
but the actual cause of the problem
seems to be the generics of the stream() code in the getSomethings() method
which is not mentioned in the error.
JDK 19 will compile the code
after replacing .map(c -> construct(c))
with .map(this::construct)
JDK 8 compiles either version of the code.
This feels like a regression in the compiler
but maybe I am missing something?
REGRESSION : Last worked in version 8u361
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile the test code using JDK 8
2. Code compiles OK
3. Compile the test code using JDK 19
4. An unexpected error is produced
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code is expected to compile JDK 19
ACTUAL -
Error message produced by JDK 19:
error: getContext() in AbstractSomething cannot implement getContext() in Something
return type CAP#1 is not compatible with CAP#2
where Ctx#1,Ctx#2 are type-variables:
Ctx#1 extends Context declared in class AbstractSomething
Ctx#2 extends Context declared in interface Something
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends Context from capture of ? extends Context
CAP#2 extends Context from capture of ? extends Context
1 error
---------- BEGIN SOURCE ----------
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Test {
List<Something> getSomethings() {
return Stream.of(
SomethingA.class,
SomethingB.class)
.map(c -> construct(c)) // UNEXPECTED COMPILER ERROR IN JDK 17+19 (BUT COMPILES IN JDK 8)
// .map(this::construct) // COMPILES IN JDK 17+19+8
.collect(Collectors.toList());
}
Something construct(Class<? extends Something> clazz) {
return null;
}
interface Context { }
interface ContextA extends Context { }
interface ContextB extends Context { }
interface Something<Ctx extends Context> {
Ctx getContext();
}
interface SpecificSomething<Ctx extends Context>
extends Something<Ctx> { }
abstract static class AbstractSomething<Ctx extends Context>
implements Something<Ctx> {
@Override
public Ctx getContext() {
return null;
}
}
static class SomethingA
extends AbstractSomething<ContextA>
implements SpecificSomething<ContextA> { }
static class SomethingB
extends AbstractSomething<ContextB>
implements SpecificSomething<ContextB> { }
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
JDK 19 will compile the code
after replacing .map(c -> construct(c))
with .map(this::construct)
FREQUENCY : always