From bf0beb772c83fb5fa2240369ec7602a65000e089 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Wed, 19 Apr 2017 15:22:06 +0200 Subject: [PATCH] Fix IllegalArgumentException when release a wrapped ByteBuffer on Java9 Motivation: Unsafe.invokeCleaner(...) checks if the passed in ByteBuffer is a slice or duplicate and if so throws an IllegalArgumentException on Java9. We need to ensure we never try to free a ByteBuffer that was provided by the user directly as we not know if its a slice / duplicate or not. Modifications: Never try to free a ByteBuffer that was passed into UnpooledUnsafeDirectByteBuf constructor by an user (via Unpooled.wrappedBuffer(....)). Result: Build passes again on Java9 --- .../netty/buffer/UnpooledUnsafeDirectByteBuf.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java b/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java index 1702ab2051..e2637b0f43 100644 --- a/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java @@ -74,7 +74,16 @@ public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf * @param maxCapacity the maximum capacity of the underlying direct buffer */ protected UnpooledUnsafeDirectByteBuf(ByteBufAllocator alloc, ByteBuffer initialBuffer, int maxCapacity) { - this(alloc, initialBuffer, maxCapacity, true); + // We never try to free the buffer if it was provided by the end-user as we not know if this is an duplicate or + // an slice. This is done to prevent an IllegalArgumentException when using Java9 as Unsafe.invokeCleaner(...) + // will check if the given buffer is either an duplicate or slice and in this case throw an + // IllegalArgumentException. + // + // See http://hg.openjdk.java.net/jdk9/hs-demo/jdk/file/0d2ab72ba600/src/jdk.unsupported/share/classes/ + // sun/misc/Unsafe.java#l1250 + // + // We also call slice() explicitly here to preserve behaviour with previous netty releases. + this(alloc, initialBuffer.slice(), maxCapacity, false); } UnpooledUnsafeDirectByteBuf(ByteBufAllocator alloc, ByteBuffer initialBuffer, int maxCapacity, boolean doFree) { @@ -100,7 +109,7 @@ public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf this.alloc = alloc; doNotFree = !doFree; - setByteBuffer(initialBuffer.slice().order(ByteOrder.BIG_ENDIAN), false); + setByteBuffer(initialBuffer.order(ByteOrder.BIG_ENDIAN), false); writerIndex(initialCapacity); }