Hi Ryan,

Apropos of this discussion, I happened to recently give a talk to the JCP that in part covered behavioral compatibility in the JDK:

https://jcp.org/aboutJava/communityprocess/ec-public/materials/2023-06-13/JCP-EC-Public-Agenda-June-2023.html
https://jcp.org/aboutJava/communityprocess/ec-public/materials/2023-06-13/Contributing_to_OpenJDK_2023_04_12.pdf

There are many observable details of the JDK implementation, including reflective details, timing, etc. there are _not_ part of the interfaces users should rely on.

My current evaluation here is that it would set an unfortunate precedent to preclude making the sort of source changes in questions because of (potential) compatibility concerns in reflective modeling, especially in a feature release. (IMO, there is a stronger argument for not making such a change in an update release, but even there as the change is a semantically equivalent refactoring, I think it is generally fine.)

HTH,

-Joe

On 6/29/2023 11:30 AM, Ryan Ernst wrote:
Thanks for replying, Joe. First, let me reiterate, we fully admit
there was a bug in painless, we stopped short in walking the class
hierarchy. There is no bug in the SequencedCollection hierarchy. But I
do think there is an inconsistency.

The two definition are semantically equivalent
...
The JDK 22 javadoc for List shows:
All Superinterfaces:
     Collection<E>, Iterable<E>, SequencedCollection<E>
While that is true, in practice the reflection API does not give the
same collapsed view that javadocs do. Calling getInterfaces() on a
class only returns direct super interfaces, so
List.class.getInterfaces() no longer returns Collection.class in JDK
21.

The inconsistency I see is that SortedSet.class.getInterfaces() *does*
still return Set.class. Was that intentional? It seems like either
SortedSet does not need to extend Set directly, or List should still
extend Collection directly. And doing the latter would provide an
extra layer of "compatibility" for applications that may look at
direct super interfaces, and be surprised that Collection disappeared
across JDK versions for List.

On Wed, Jun 28, 2023 at 6:31 PM Joseph D. Darcy <joe.da...@oracle.com> wrote:
Hello,

What is Painless doing that would fail under

      List extends SequencedCollection ...

but work under

      List extends SequencedCollection, Collection ...

The two definition are semantically equivalent since SequencedCollection
itself extends Collection.

The JDK 22 javadoc for List shows:

All Superinterfaces:
     Collection<E>, Iterable<E>, SequencedCollection<E>
There are certainly implementation artifacts concerning the details of
how a type was declared that exposed via core reflection (for the
javax.lang.model API during annotation processing at compile time), but
it is a bug for third party programs to rely on such details.

HTH,

-Joe

On 6/27/2023 7:37 AM, Ryan Ernst wrote:
Hi core-libs-dev,

I know various threads have existed over the past few months on
SequencedCollection and its implications on compatibility. I wanted to
raise this semi-related issue we noticed recently after beginning
testing against Java 21.

Elasticsearch began testing against Java 21, and noticed a series of
failures in Painless (our builtin scripting language, which
dynamically compiles to bytecode). Most tests that used List failed to
compile, with several unknown methods (eg add). Painless builds a
hierarchy of classes it knows about for method resolution. This
hierarchy didn't know anything about SequencedCollection since we
currently compile against Java 17. Now, this was ultimately a bug in
Painless, because we knew there could be cases where we encounter
unknown classes in the hierarchy (eg a class which is not blessed to
be visible in the language). However, I think the reason we found that
bug (List extending from SequencedCollection) might still cause issues
for some.

While debugging the issue, something that struck me as interesting in
the SequencedCollection hierarchy is the difference between List and
SortedSet. Both of these classes were made to be compatible with
sequenced classes by adding the new classes as super interfaces,
SequencedCollection and SequencedSet, respectively. However, while
SortedSet was *added* as a super interface, List had its super
interface Collection *replaced* by SequencedCollection.

I don't know enough about the rampdown process to know if this is
still fixable in Java 21. It is probably an extreme edge case that
doesn't matter, since eg instanceof Collection will still work in
existing code. But for consistency, it would seem better to maintain
Collection as a direct super interface of List. Is there any reason
such a change doesn't fit with the collections architecture going
forward?

Reply via email to