-
Bug
-
Resolution: Fixed
-
P2
-
None
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8337934 | 23.0.1 | Brian Burkhalter | P2 | Resolved | Fixed | b06 |
JDK-8337824 | 23 | Brian Burkhalter | P2 | Resolved | Fixed | b36 |
The following example shows that starting in JDK 23, a HeapByteBuffer and DirectByteBufferR with the same contents are equal according to equals, but have different hashcodes.
I noticed this debugging a test that started failing on JDK 23, and which was putting ByteBuffers in a set and relying on Set#equals.
I haven't verified this yet, but https://bugs.openjdk.org/browse/JDK-8321279 seems like a possible culprit, if the behaviour of the hashCode implementations in Heap-X-Buffer.java.template and X-Buffer.java.template is no longer equivalent.
```java
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Set;
public class X {
public static void main(String[] args) throws IOException {
byte[] bytes = "hello world".getBytes(UTF_8);
Path path = Files.createTempFile("", "");
Files.write(path, bytes);
FileChannel chan = FileChannel.open(path, StandardOpenOption.READ);
MappedByteBuffer one = chan.map(FileChannel.MapMode.READ_ONLY, 0, bytes.length);
ByteBuffer two = ByteBuffer.wrap(bytes);
System.err.printf(
"comparing:\n %s (%s)\n %s (%s)\n", one, one.getClass(), two, two.getClass());
System.err.printf("equals: %s\n", one.equals(two));
int oneHash = one.hashCode();
int twoHash = two.hashCode();
System.err.printf("hashCode (%d == %d) = %s\n", oneHash, twoHash, oneHash == twoHash);
System.err.printf("contains: %s\n", Set.of(one).contains(two));
}
}
```
$ java -fullversion
$ java X.java
openjdk full version "22.0.2+9-70"
comparing:
java.nio.DirectByteBufferR[pos=0 lim=11 cap=11] (class java.nio.DirectByteBufferR)
java.nio.HeapByteBuffer[pos=0 lim=11 cap=11] (class java.nio.HeapByteBuffer)
equals: true
hashCode (621715235 == 621715235) = true
contains: true
$ java -fullversion
$ java X.java
openjdk full version "23-ea+34-2361"
comparing:
java.nio.DirectByteBufferR[pos=0 lim=11 cap=11] (class java.nio.DirectByteBufferR)
java.nio.HeapByteBuffer[pos=0 lim=11 cap=11] (class java.nio.HeapByteBuffer)
equals: true
hashCode (621715235 == 1923188771) = false
I noticed this debugging a test that started failing on JDK 23, and which was putting ByteBuffers in a set and relying on Set#equals.
I haven't verified this yet, but https://bugs.openjdk.org/browse/JDK-8321279 seems like a possible culprit, if the behaviour of the hashCode implementations in Heap-X-Buffer.java.template and X-Buffer.java.template is no longer equivalent.
```java
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Set;
public class X {
public static void main(String[] args) throws IOException {
byte[] bytes = "hello world".getBytes(UTF_8);
Path path = Files.createTempFile("", "");
Files.write(path, bytes);
FileChannel chan = FileChannel.open(path, StandardOpenOption.READ);
MappedByteBuffer one = chan.map(FileChannel.MapMode.READ_ONLY, 0, bytes.length);
ByteBuffer two = ByteBuffer.wrap(bytes);
System.err.printf(
"comparing:\n %s (%s)\n %s (%s)\n", one, one.getClass(), two, two.getClass());
System.err.printf("equals: %s\n", one.equals(two));
int oneHash = one.hashCode();
int twoHash = two.hashCode();
System.err.printf("hashCode (%d == %d) = %s\n", oneHash, twoHash, oneHash == twoHash);
System.err.printf("contains: %s\n", Set.of(one).contains(two));
}
}
```
$ java -fullversion
$ java X.java
openjdk full version "22.0.2+9-70"
comparing:
java.nio.DirectByteBufferR[pos=0 lim=11 cap=11] (class java.nio.DirectByteBufferR)
java.nio.HeapByteBuffer[pos=0 lim=11 cap=11] (class java.nio.HeapByteBuffer)
equals: true
hashCode (621715235 == 621715235) = true
contains: true
$ java -fullversion
$ java X.java
openjdk full version "23-ea+34-2361"
comparing:
java.nio.DirectByteBufferR[pos=0 lim=11 cap=11] (class java.nio.DirectByteBufferR)
java.nio.HeapByteBuffer[pos=0 lim=11 cap=11] (class java.nio.HeapByteBuffer)
equals: true
hashCode (621715235 == 1923188771) = false
- backported by
-
JDK-8337824 ByteBuffer hashCode implementations are inconsistent
-
- Resolved
-
-
JDK-8337934 ByteBuffer hashCode implementations are inconsistent
-
- Resolved
-
- relates to
-
JDK-8321279 Implement hashCode() in Heap-X-Buffer.java.template
-
- Resolved
-
- links to
-
Commit(jdk23) openjdk/jdk/b7ede41a
-
Commit(master) openjdk/jdk/8bd3cd51
-
Review(jdk23) openjdk/jdk/20461
-
Review(master) openjdk/jdk/20451
(2 links to)