5

The following Java code compiles, but there's an error at runtime:

# javac ByteBufTest.java
# java ByteBufTest
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.nio.ByteBuffer.array(ByteBuffer.java:959)
    at ByteBufTest.<init>(ByteBufTest.java:12)
    at ByteBufTest.main(ByteBufTest.java:33)
# 

Why does this happen?

Note:Next, I need to use mDirectBuffer in JNI, so I have to use the ByteBuffer.allocateDirect(TEST_BUFFER_SIZE) function。

ByteBufTest.java:

import java.nio.ByteBuffer;

public class ByteBufTest {

    public static final int TEST_BUFFER_SIZE = 128;

    private ByteBuffer mDirectBuffer;

    public ByteBufTest() {
        mDirectBuffer = ByteBuffer.allocateDirect(TEST_BUFFER_SIZE);
        byte[] buf = mDirectBuffer.array();
        buf[1]=100;
    }

    public void test() {

        printBuffer("nativeInitDirectBuffer",mDirectBuffer.array());

    }

    private void printBuffer( String tag, byte[] buffer ) {
        StringBuffer sBuffer = new StringBuffer();
        for( int i=0; i<buffer.length; i++ ) {
            sBuffer.append(buffer[i]);
            sBuffer.append(" ");    
        }
        //System.out.println(tag+sBuffer);
    }

    public static void main(String[] args) throws Exception {

        ByteBufTest item = new ByteBufTest();
        item.test(); 
    }
}
zzkjliu
  • 86
  • 1
  • 8

3 Answers3

2

This is the expected behaviour. The Javadoc states

throws UnsupportedOperationException - If this buffer is not backed by an accessible array

You should try another approach or search for another implementation, e.g.

mDirectBuffer = ByteBuffer.wrap(new byte[TEST_BUFFER_SIZE]);
Kalle Richter
  • 8,008
  • 26
  • 77
  • 177
  • ,I need to use mDirectBuffer in JNI, so I have to use the ByteBuffer.allocateDirect(TEST_BUFFER_SIZE) function – zzkjliu Feb 02 '18 at 12:41
  • 2
    For JDK,the array() method of byte buffer class returns a byte array (byte []) of the buffer’s contents. This is only valid for non-direct buffers. When used with direct buffers this method throws an exception: UnsupportedOperationException。 For android,the array() works ok。 – zzkjliu Feb 03 '18 at 09:13
1

This exception occurs at runtime if the resulting buffer is not backed by an accessible array. You can try allocate() method.

Ankit Shubham
  • 2,989
  • 2
  • 36
  • 61
1

You should call java.nio.ByteBuffer.hasArray() to ensure that java.nio.ByteBuffer.array() will succeed in order to write clean and portable code as stated in the Java API documentation:

If this method returns true then the array and arrayOffset methods may safely be invoked

You can allocate a direct writable NIO byte buffer in your Java source code by calling java.nio.ByteBuffer.allocateDirect(int) as you already do and call java.nio.ByteBuffer.get(byte[]) to store the content of the buffer into an array, this method is supported by Android too. Keep in mind that it's a relative operation that affects the position of the NIO buffer.

Maybe another approach would consist in using the NIO buffer as is without doing any conversion but I'm not sure that it suits your needs.

gouessej
  • 3,640
  • 3
  • 33
  • 67