-
Notifications
You must be signed in to change notification settings - Fork 11k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support JDK 21 Sequenced Collections #6903
Comments
One thing that Rhys mentioned that I hadn't considered before was the documentation aspect: For someone new to, say, Then there's the benefit of the methods themselves, like |
There is another aspect to this that, in my opinion, extends beyond documentation and instead would improve correctness. The
That practice is problematic in a subtle way: It's possible to pass in arguments with unspecified iteration order (e.g. As a concrete example, I'm currently hunting down instances of this in Bazel by patching I would be happy to help with this as well as the build system changes needed to make this possible. Where are we with this? |
Could you explain a little more what you have in mind? It sounds like maybe you want to be able to consistently define APIs in Bazel to require Unfortunately, I don't think we'll be in a position to make that particular change until Guava requires Java 21+. (And we're still waiting to require Java 11.) Even with a multi-release jar, the APIs across releases are supposed to match, and if they don't, bad things happen. (Sequenced-washing is definitely a problem, one that we also see with content that gets stringified or even copied to some other kind of |
Yes, that's exactly what I would like to be able to do.
I read the issue you linked, but I'm still not sure why we can't add support for this sooner, say like this:
We of course do need to be careful about Do you see a problem with this approach? |
Sorry for not providing a shorter version of that. My understanding is that tools do not reliably read the Java-21 section of the multi-release jar when building for Java 21. So you wouldn't necessarily be able to use Now, I'm actually not sure to what extent the JDK developers have gotten into the weeds of what it means for the API to "match": It seems as if it would be useful—and not harmful—to be able to do exactly what you describe. It's conceivable that we could get a clarification or change from the JDK developers, followed by changes to various tools to make those tools look at the release that they're targeting—presumably followed by changes by changes to various projects to configure those tools correctly in cases where they were getting away with doing things wrong before :) Sadly, I wouldn't hold my breath, but maybe it's a road that we should consider starting down, even if it wouldn't pay off for many years. (I do think there's a decent chance that new versions of Guava will someday require some version of Java that has built-in support for nullness. It's even conceivable that the next jump we made will be directly from Java 8 to that version, in which case we could pick up Java-21 changes at that point. But that's still far off and hypothetical.) |
That sounds like a hen-and-egg problem to me: As long as multi-release JARs aren't properly supported by all build tools, developers aren't incentivized to make use of them. But as long as they don't, there is little value in fixing the bugs in all these tools. :-) That said, wouldn't it be okay for Guava to add this kind of feature with the understanding that tools may need to fix bugs before they can make use of it? If a certain javac alternative doesn't see the All of this of course requires clarification from the JDK devs on whether they intend to support this use case. I could ask on the mailing lists. |
Yes, I think (no guarantees, but I think) that I'd be comfortable giving this a try if we had word from the JDK developers that it's an intended use case. It would be good to push the ecosystem forward to support the feature in that case. If you're up for asking, that would be great, and I'm happy to chime in in support if you CC [email protected]. |
I was reminded by raphw/asm-jdk-bridge#3 that That checking doesn't appear to mind a difference in supertypes:
Contrast that to what happens if I stick a direct method declaration into only
I don't mean to present that as conclusive, given that the JEP left things a bit up in the air, including noting that enforcement could be incomplete. But it's at least worth noting that this one specific potential obstacle does not exist, and that may be a blurry sign to us of how upstream has been thinking about "API compatibility"—or, alternatively, just of what they found easiest to implement or most likely to catch real-world problems :) |
Nice find! I looked through the history of that validation and found that its original version somewhat explicitly doesn't consider interfaces: https://github.com/openjdk/jdk/blob/def15478ebc213eeff8eb4da9178f8bac4c72604/jdk/src/jdk.jartool/share/classes/sun/tools/jar/FingerPrint.java#L240-L248 If I don't get a reply on the mailing list, I could try to add a test to the jar validation that codifies this behavior. |
I suspect that mr-jars aren't going to be an easy way out of this, and the only viable path may be pushing to #6614 and beyond. |
Consumers of an `Immutable{List,Map,Set}` cannot know whether it has been created from a source with unspecified iteration order, such as `HashMap`. Since `ImmutableMap` itself prescribes that it preserves insertion order, it's reasonable for consumers to expect a specified, reasonable, deterministic order. While the current implementation of `HashMap` in the OpenJDK still results in a deterministic order, this kind of "sequenced-washing" doesn't cause non-determinism, but it still runs the risk of having the order of elements change between JDK versions or vendors. The locations changed in this PR have been identified by instrumenting the factory methods of the `Immutable{List,Map,Set}` classes to track whether they 1) have been created from an unsequenced collection and 2) are iterated over. I then manually picked out those cases in which I couldn't rule out that a change in order would be observable to users. Related to google/guava#6903 (comment)
Consumers of an `Immutable{List,Map,Set}` cannot know whether it has been created from a source with unspecified iteration order, such as `HashMap`. Since `ImmutableMap` itself prescribes that it preserves insertion order, it's reasonable for consumers to expect a specified, reasonable, deterministic order. While the current implementation of `HashMap` in the OpenJDK still results in a deterministic order, this kind of "sequenced-washing" doesn't cause non-determinism, but it still runs the risk of having the order of elements change between JDK versions or vendors. The locations changed in this PR have been identified by instrumenting the factory methods of the `Immutable{List,Map,Set}` classes to track whether they 1) have been created from an unsequenced collection and 2) are iterated over. I then manually picked out those cases in which I couldn't rule out that a change in order would be observable to users. Related to google/guava#6903 (comment)
Consumers of an `Immutable{List,Map,Set}` cannot know whether it has been created from a source with unspecified iteration order, such as `HashMap`. Since `ImmutableMap` itself prescribes that it preserves insertion order, it's reasonable for consumers to expect a specified, reasonable, deterministic order. While the current implementation of `HashMap` in the OpenJDK still results in a deterministic order, this kind of "sequenced-washing" doesn't cause non-determinism, but it still runs the risk of having the order of elements change between JDK versions or vendors. The locations changed in this PR have been identified by instrumenting the factory methods of the `Immutable{List,Map,Set}` classes to track whether they 1) have been created from an unsequenced collection and 2) are iterated over. I then manually picked out those cases in which I couldn't rule out that a change in order would be observable to users. Related to google/guava#6903 (comment) Closes #25218. PiperOrigin-RevId: 724341188 Change-Id: I2f38a4c3dad80055cb8d80853e9f211836019e5b
Consumers of an `Immutable{List,Map,Set}` cannot know whether it has been created from a source with unspecified iteration order, such as `HashMap`. Since `ImmutableMap` itself prescribes that it preserves insertion order, it's reasonable for consumers to expect a specified, reasonable, deterministic order. While the current implementation of `HashMap` in the OpenJDK still results in a deterministic order, this kind of "sequenced-washing" doesn't cause non-determinism, but it still runs the risk of having the order of elements change between JDK versions or vendors. The locations changed in this PR have been identified by instrumenting the factory methods of the `Immutable{List,Map,Set}` classes to track whether they 1) have been created from an unsequenced collection and 2) are iterated over. I then manually picked out those cases in which I couldn't rule out that a change in order would be observable to users. Related to google/guava#6903 (comment) Closes bazelbuild#25218. PiperOrigin-RevId: 724341188 Change-Id: I2f38a4c3dad80055cb8d80853e9f211836019e5b
Consumers of an `Immutable{List,Map,Set}` cannot know whether it has been created from a source with unspecified iteration order, such as `HashMap`. Since `ImmutableMap` itself prescribes that it preserves insertion order, it's reasonable for consumers to expect a specified, reasonable, deterministic order. While the current implementation of `HashMap` in the OpenJDK still results in a deterministic order, this kind of "sequenced-washing" doesn't cause non-determinism, but it still runs the risk of having the order of elements change between JDK versions or vendors. The locations changed in this PR have been identified by instrumenting the factory methods of the `Immutable{List,Map,Set}` classes to track whether they 1) have been created from an unsequenced collection and 2) are iterated over. I then manually picked out those cases in which I couldn't rule out that a change in order would be observable to users. Related to google/guava#6903 (comment) Closes #25218. PiperOrigin-RevId: 724341188 Change-Id: I2f38a4c3dad80055cb8d80853e9f211836019e5b Commit b03cb63 Co-authored-by: Fabian Meumertzheim <[email protected]>
1. What are you trying to do?
Please see JEP-431 for background on what a Sequenced Collection is.
The javadoc for ImmutableCollection mentions that most Guava Collections have a well-defined iteration order. Indeed, I often rely on this behaviour. This issue is to discuss support for the SequencedCollections interface, in order to better communicate that Guava Collections have this property.
2. What's the best code you can write to accomplish that without the new feature?
This example does not make much sense without the context of the added methods in SequencedCollection, however:
3. What would that same code look like if we added your feature?
Sequenced Collections add new convenience methods that arise from having a defined iteration order. Applying this to (for example) ImmutableSet, which preserves insertion order, would result in the following code being valid:
(Optional) What would the method signatures for your feature look like?
No response
Concrete Use Cases
I have not yet used Guava with JDK 21.
Please see related Guava discussion: https://groups.google.com/g/guava-discuss/c/IXWZCHn7yJs
Packages
com.google.common.collect
Checklist
I agree to follow the code of conduct.
I have read and understood the contribution guidelines.
I have read and understood Guava's philosophy, and I strongly believe that this proposal aligns with it.
I have visited the idea graveyard, and did not see anything similar to this idea.
The text was updated successfully, but these errors were encountered: