From 0601389766e2feec82c1d6d9e1834a3930c82caa Mon Sep 17 00:00:00 2001 From: Roman Puchkovskiy Date: Mon, 3 Aug 2020 21:49:06 +0400 Subject: [PATCH] Do not try to use Unsafe.staticFieldOffset() method under a native image. (#10428) Motivation: GraalVM's native images built with native-image tool do not support Unsafe.staticFieldOffset() method (at least, currently). If an application using Netty (and causing initialization of io.netty.util.internal.PlatformDependent0 class) is built into a native image and run, this results in the following error thrown during initialization: Exception in thread "main" com.oracle.svm.core.jdk.UnsupportedFeatureError: Unsupported method of Unsafe at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:86) at jdk.internal.misc.Unsafe.staticFieldOffset(Unsafe.java:230) at sun.misc.Unsafe.staticFieldOffset(Unsafe.java:662) at io.netty.util.internal.PlatformDependent0$5.run(PlatformDependent0.java:294) at java.security.AccessController.doPrivileged(AccessController.java:83) at io.netty.util.internal.PlatformDependent0.(PlatformDependent0.java:279) This seems to be the reason of the behavior described in #10051. Modification: The idea of this commit is to only invoke Unsafe.staticFieldOffset() is we are not in a native image; if we are, behave like if we could not find the field at all. GraalDetector is borrowed from Spring framework. Result: Fixes #10051 --- .../io/netty/util/internal/PlatformDependent0.java | 11 ++++++++++- 1 file changed, 10 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 44976f18cb..d95aaa8cdb 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent0.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent0.java @@ -53,6 +53,11 @@ final class PlatformDependent0 { private static final Object INTERNAL_UNSAFE; private static final boolean IS_EXPLICIT_TRY_REFLECTION_SET_ACCESSIBLE = explicitTryReflectionSetAccessible0(); + // See https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ + // ImageInfo.java + private static final boolean RUNNING_IN_NATIVE_IMAGE = SystemPropertyUtil.contains( + "org.graalvm.nativeimage.imagecode"); + static final Unsafe UNSAFE; // constants borrowed from murmur3 @@ -283,7 +288,7 @@ final class PlatformDependent0 { Class bitsClass = Class.forName("java.nio.Bits", false, getSystemClassLoader()); int version = javaVersion(); - if (version >= 9) { + if (unsafeStaticFieldOffsetSupported() && 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 @@ -399,6 +404,10 @@ final class PlatformDependent0 { DIRECT_BUFFER_CONSTRUCTOR != null ? "available" : "unavailable"); } + private static boolean unsafeStaticFieldOffsetSupported() { + return !RUNNING_IN_NATIVE_IMAGE; + } + static boolean isExplicitNoUnsafe() { return EXPLICIT_NO_UNSAFE_CAUSE != null; }