JDK-8308167 : SequencedMap::firstEntry throws NPE when first entry has null key or value
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:collections
  • Affected Version: 21
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2023-05-16
  • Updated: 2023-07-18
  • Resolved: 2023-06-06
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.
JDK 21
21 b26Fixed
Related Reports
Blocks :  
Description
Observed that SequencedMap:firstEntry() throws NullPointerEx when the map entry has null key or null value.

Example  : the following code snippet throws NPEx.
======== ( When key is null ) 
SequencedMap<String, String> sequencedMap = new LinkedHashMap<>();
        sequencedMap.put(null, "v1");
        sequencedMap.firstEntry();

======== (When value is null )
SequencedMap<String, String> sequencedMap = new LinkedHashMap<>();
        sequencedMap.put("k", null);
        sequencedMap.firstEntry();

=====

Comments
The same NPE pathology occurs with firstEntry(), lastEntry(), pollFirstEntry(), and pollLastEntry(). Added tests for those methods when a key or value is null. Briefly, these methods need to create new Map.Entry instances that are disconnected from the underlying Map. The existing code used the Map.entry() API (which returns a KeyValueHolder) but that's wrong, since it disallows nulls. Retrofitting KeyValueHolder to allow nulls is complicated. AbstractMap.SimpleImmutableEntry is the obvious alternative but it's serializable, and I wanted to avoid increasing the serialization footprint of the platform. Instead, I created a new internal class NullableKeyValueHolder as a Map.Entry implementation that accommodates nullable keys and values. See comments in the new class for additional rationale. This could probably be merged with KeyValueHolder at some point, but modifying the specifications would make this easier. src/java.base/share/classes/jdk/internal/util/NullableKeyValueHolder.java
06-06-2023

Changeset: 6d155a47 Author: Stuart Marks <smarks@openjdk.org> Date: 2023-06-06 00:19:50 +0000 URL: https://git.openjdk.org/jdk/commit/6d155a47f13ff80cf7a9de363fc5ae2943b6603a
06-06-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/14278 Date: 2023-06-02 01:12:32 +0000
02-06-2023

Various default methods in SequencedMap use Map.Entry.copyOf, which internally uses KeyValueHolder. However, that class rejects nulls for key and value. Retrofitting it to allow nulls (even internally) is a bit problematic because it spoils the @Stable annotations on the fields, which require a non-null initialization to be effective. An alternative is to use AbstractMap.SimpleImmutableEntry. However, that's serializable! As annoying as it seems, it may be necessary to have a third class, similar to KeyValueHolder, which doesn't have stable fields (but which might be value-based) and which isn't serializable. In addition, its equals() and hashCode() methods would need to be null-safe.
16-05-2023