JDK-5043362 : (bf) NewDirectByteBuffer always has order ByteOrder.BIG_ENDIAN
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 1.4.2
  • Priority: P5
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2004-05-06
  • Updated: 2019-03-21
  • Resolved: 2019-03-15
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 13
13 b13Fixed
Related Reports
CSR :  
Sub Tasks
JDK-8225152 :  
Description

Name: rmT116609			Date: 05/06/2004


A DESCRIPTION OF THE REQUEST :
NewDirectByteBuffer always has order ByteOrder.BIG_ENDIAN, even when the order is ByteOrder.LITTLE_ENDIAN.

The following might be a fix for this problem, except that isDirect() is abstract, so JVMs are not required to implement the isDirect() method:

ByteBuffer bb = nativeMethodReturningDirectByteBuffer();
if (bb.isDirect()) {
  bb.order(ByteOrder.nativeOrder());
}

Also note that passing a memory address from Java to C++ works similarly... C++ assumes the data is LITTLE_ENDIAN unless the ByteBuffer that refers to the address is explicitly given order ByteOrder.nativeOrder().

JUSTIFICATION :
isDirect() isn't the best solution. Maybe an isNative() method would be better?

But preferably the ByteBuffer returned by NewDirectByteBuffer would already be ByteOrder.nativeOrder() by default.

Someone on comp.lang.java.programmer suggested htonl or kind. I have no idea what these are, but possibly the would be a good  solution to the whole big-endian little-endian mess.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Any ByteBuffer returned by NewDirectByteBuffer should have order ByteOrder.nativeOrder().

Obvious, no?
ACTUAL -
ByteBuffer returned by NewDirectByteBuffer has order ByteOrder.BIG_ENDIAN, which is false, mis-leading, incorrect, etc.

---------- BEGIN SOURCE ----------
ByteBuffer bb = nativeMethodReturningDirectByteBuffer();
System.out.println("bb.order() " + bb.order());

Complete C++ and Java source code is available here:
http://www.alpha-mu.com/alpha/files/



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

CUSTOMER SUBMITTED WORKAROUND :
ByteBuffer bb = nativeMethodReturningDirectByteBuffer();
if (bb.isDirect()) {
  bb.order(ByteOrder.nativeOrder());
}
(Incident Review ID: 261264) 
======================================================================

Comments
As noted in the evaluation from 2004, it hardly seems worth introducing a new JNI function for this. Instead I think the JNI spec should be clarified so that the spec for NewDirectByteBuffer is clear that the byte order is big endian. This will align the JNI spec with the long standing javadoc in ByteBuffer.allocateDirect.
06-02-2018

EVALUATION The JNI function NewDirectByteBuffer always returns a big-endian byte buffer in order to be consistent with the java.nio.ByteBuffer API, which also always creates new buffers with big-endian order. Changing this behavior now has the potential to break existing, working code, so we won't do that. We could add a new JNI function, say NewDirectByteBufferOfNativeOrder, but since the workaround is so trivial it's not clear that doing so would be worthwhile. -- ###@###.### 2004/5/12
05-12-0178