diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent.java b/common/src/main/java/io/netty/util/internal/PlatformDependent.java index 40785e4c92..d9f550de63 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent.java @@ -78,6 +78,9 @@ public final class PlatformDependent { private static final Pattern MAX_DIRECT_MEMORY_SIZE_ARG_PATTERN = Pattern.compile( "\\s*-XX:MaxDirectMemorySize\\s*=\\s*([0-9]+)\\s*([kKmMgG]?)\\s*$"); + // this must be initialized before any code below triggers initialization of PlatformDependent0 + private static final boolean IS_EXPLICIT_NO_UNSAFE = explicitNoUnsafe0(); + private static final boolean IS_ANDROID = isAndroid0(); private static final boolean IS_WINDOWS = isWindows0(); private static volatile Boolean IS_ROOT; @@ -86,7 +89,6 @@ public final class PlatformDependent { private static final boolean CAN_ENABLE_TCP_NODELAY_BY_DEFAULT = !isAndroid(); - private static final boolean IS_EXPLICIT_NO_UNSAFE = explicitNoUnsafe0(); private static final boolean HAS_UNSAFE = hasUnsafe0(); private static final boolean CAN_USE_CHM_V8 = HAS_UNSAFE && JAVA_VERSION < 8; private static final boolean DIRECT_BUFFER_PREFERRED = @@ -1116,6 +1118,10 @@ public final class PlatformDependent { } } + static boolean isExplicitNoUnsafe() { + return IS_EXPLICIT_NO_UNSAFE; + } + private static boolean explicitNoUnsafe0() { final boolean noUnsafe = SystemPropertyUtil.getBoolean("io.netty.noUnsafe", false); logger.debug("-Dio.netty.noUnsafe: {}", noUnsafe); 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 eb7cdb388d..6f86da9be4 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent0.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent0.java @@ -58,36 +58,43 @@ final class PlatformDependent0 { private static final boolean UNALIGNED; static { - final ByteBuffer direct = ByteBuffer.allocateDirect(1); + final ByteBuffer direct; final Field addressField; - // attempt to access field Buffer#address - final Object maybeAddressField = AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Object run() { - try { - final Field field = Buffer.class.getDeclaredField("address"); - field.setAccessible(true); - // if direct really is a direct buffer, address will be non-zero - if (field.getLong(direct) == 0) { - return null; - } - return field; - } catch (IllegalAccessException e) { - return e; - } catch (NoSuchFieldException e) { - return e; - } catch (SecurityException e) { - return e; - } - } - }); - if (maybeAddressField instanceof Field) { - addressField = (Field) maybeAddressField; - logger.debug("java.nio.Buffer.address: available"); - } else { - logger.debug("java.nio.Buffer.address: unavailable", (Exception) maybeAddressField); + if (PlatformDependent.isExplicitNoUnsafe()) { + direct = null; addressField = null; + } else { + direct = ByteBuffer.allocateDirect(1); + // attempt to access field Buffer#address + final Object maybeAddressField = AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Object run() { + try { + final Field field = Buffer.class.getDeclaredField("address"); + field.setAccessible(true); + // if direct really is a direct buffer, address will be non-zero + if (field.getLong(direct) == 0) { + return null; + } + return field; + } catch (IllegalAccessException e) { + return e; + } catch (NoSuchFieldException e) { + return e; + } catch (SecurityException e) { + return e; + } + } + }); + + if (maybeAddressField instanceof Field) { + addressField = (Field) maybeAddressField; + logger.debug("java.nio.Buffer.address: available"); + } else { + logger.debug("java.nio.Buffer.address: unavailable", (Exception) maybeAddressField); + addressField = null; + } } Unsafe unsafe; @@ -247,7 +254,9 @@ final class PlatformDependent0 { logger.debug("java.nio.DirectByteBuffer.(long, int): {}", DIRECT_BUFFER_CONSTRUCTOR != null ? "available" : "unavailable"); - freeDirectBuffer(direct); + if (direct != null) { + freeDirectBuffer(direct); + } } static boolean isUnaligned() {