From ade60c11e16db5f83070c419bcf8fc701cdd15f9 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Wed, 5 Sep 2018 07:22:16 +0200 Subject: [PATCH] PlatformDependent0 should be able to better detect if unaligned access is supported on java9 and later. (#8255) Motivation: In Java8 and earlier we used reflection to detect if unaligned access is supported. This fails in Java9 and later as we would need to change the accessible level of the method. Lucky enough we can use Unsafe directly to read the content of the static field here. Modifications: Add special handling for detecting if unaligned access is supported on Java9 and later which does not fail due jigsaw. Result: Better and more correct detection on Java9 and later. --- .../util/internal/PlatformDependent0.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent0.java b/common/src/main/java/io/netty/util/internal/PlatformDependent0.java index 53e9ed7bdc..cf3c471273 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent0.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent0.java @@ -262,13 +262,32 @@ final class PlatformDependent0 { DIRECT_BUFFER_CONSTRUCTOR = directBufferConstructor; ADDRESS_FIELD_OFFSET = objectFieldOffset(addressField); BYTE_ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset(byte[].class); - boolean unaligned; + final boolean unaligned; Object maybeUnaligned = AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { try { Class bitsClass = Class.forName("java.nio.Bits", false, getSystemClassLoader()); + int version = javaVersion(); + if (version >= 9) { + // Java9/10 use all lowercase and later versions all uppercase. + String fieldName = version >= 11 ? "UNALIGNED" : "unaligned"; + // On Java9 and later we try to directly access the field as we can do this without + // adjust the accessible levels. + try { + Field unalignedField = bitsClass.getDeclaredField(fieldName); + if (unalignedField.getType() == boolean.class) { + long offset = UNSAFE.staticFieldOffset(unalignedField); + Object object = UNSAFE.staticFieldBase(unalignedField); + return UNSAFE.getBoolean(object, offset); + } + // There is something unexpected stored in the field, + // let us fall-back and try to use a reflective method call as last resort. + } catch (NoSuchFieldException ignore) { + // We did not find the field we expected, move on. + } + } Method unalignedMethod = bitsClass.getDeclaredMethod("unaligned"); Throwable cause = ReflectionUtil.trySetAccessible(unalignedMethod, true); if (cause != null) {