Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8337716

ByteBuffer hashCode implementations are inconsistent

    XMLWordPrintable

Details

    • 23
    • b10

    Backports

      Description

        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

        Attachments

          Issue Links

            Activity

              People

                bpb Brian Burkhalter
                cushon Liam Miller-Cushon
                Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: