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.
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.
- relates to
-
JDK-4395095 JNI access to java.nio DirectBuffer constructor/accessor
- Resolved