JDK-6446635 : (bf spec) GetDirectBufferCapacity spec'ed to return buffer's capacity in bytes rather than capacity
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2006-07-06
  • Updated: 2017-05-16
  • Resolved: 2010-01-08
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 7
7 b79Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b90)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b90, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Linux ip173 2.6.16.13-4-default #1 Wed May 3 04:53:23 UTC 2006 i686 i686 i386 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
The JNI function GetDirectBufferCapacity seems to return capacity in elements, not in bytes, as described in the spec:

http://java.sun.com/j2se/1.5.0/docs/guide/jni/jni-14.html#GetDirectBufferCapacity

The attached test program creates a ByteBuffer sized 4 bytes, and an IntBuffer with asIntBuffer(). If the spec was right, GetDirectBufferCapacity would return the same capacity for both buffers. However, it seems that GetDirectBufferCapacity is instead implemented as Buffer.capacity() which returns capacity in elements (4 for the ByteBuffer, 1 for the IntBuffer in the test). Either the spec or the implementation should be corrected.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile and run the test with the supplied run.sh script
2. If the sizes doesn't match, an assertion will fail

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
If GetDirectBufferCapacity for the ByteBuffer and the IntBuffer were the same, the test should complete without any output or exceptions.
ACTUAL -
Exception in thread "main" java.lang.AssertionError: ByteBuffer JNI capacity (4) != IntBuffer JNI capacity! (1)
        at test.main(test.java:10)


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.AssertionError: ByteBuffer JNI capacity (4) != IntBuffer JNI capacity! (1)
        at test.main(test.java:10)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
test.java
--------------

import java.nio.*;

public class test {
    public static void main(String[] args) {
        System.loadLibrary("test");
        ByteBuffer byte_buf = ByteBuffer.allocateDirect(4);
        IntBuffer int_buf = byte_buf.asIntBuffer();
        int byte_buf_capacity = GetDirectBufferCapacity(byte_buf);
        int int_buf_capacity = GetDirectBufferCapacity(int_buf);
        assert byte_buf_capacity == int_buf_capacity: "ByteBuffer JNI capacity (" + byte_buf_capacity + ") != IntBuffer JNI capacity! (" + int_buf_capacity + ")";
    }

    private static native int GetDirectBufferCapacity(Buffer buffer);
}

test.c
---------
#include <jni.h>
#include "test.h"

JNIEXPORT jint JNICALL Java_test_GetDirectBufferCapacity(JNIEnv * env, jclass clazz, jobject buffer) {
    return (*env)->GetDirectBufferCapacity(env, buffer);
}


run.sh
------------
#!/bin/sh

$JAVA_HOME/bin/java -version
$JAVA_HOME/bin/javac test.java
$JAVA_HOME/bin/javah test
gcc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -Wall -shared -o libtest.so -fPIC test.c
$JAVA_HOME/bin/java -ea -Djava.library.path=. $@ test

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Assume that GetDirectBufferCapacity returns buffer capacity in elements, not bytes.

Comments
EVALUATION The submitter is correct, and GetDirectBufferCapacity actually returns the buffer's capacity rather than the capacity in bytes.
10-07-2006