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.<clinit>(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
This commit is contained in:
parent
c4754cf7b8
commit
0601389766
@ -53,6 +53,11 @@ final class PlatformDependent0 {
|
|||||||
private static final Object INTERNAL_UNSAFE;
|
private static final Object INTERNAL_UNSAFE;
|
||||||
private static final boolean IS_EXPLICIT_TRY_REFLECTION_SET_ACCESSIBLE = explicitTryReflectionSetAccessible0();
|
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;
|
static final Unsafe UNSAFE;
|
||||||
|
|
||||||
// constants borrowed from murmur3
|
// constants borrowed from murmur3
|
||||||
@ -283,7 +288,7 @@ final class PlatformDependent0 {
|
|||||||
Class<?> bitsClass =
|
Class<?> bitsClass =
|
||||||
Class.forName("java.nio.Bits", false, getSystemClassLoader());
|
Class.forName("java.nio.Bits", false, getSystemClassLoader());
|
||||||
int version = javaVersion();
|
int version = javaVersion();
|
||||||
if (version >= 9) {
|
if (unsafeStaticFieldOffsetSupported() && version >= 9) {
|
||||||
// Java9/10 use all lowercase and later versions all uppercase.
|
// Java9/10 use all lowercase and later versions all uppercase.
|
||||||
String fieldName = version >= 11 ? "UNALIGNED" : "unaligned";
|
String fieldName = version >= 11 ? "UNALIGNED" : "unaligned";
|
||||||
// On Java9 and later we try to directly access the field as we can do this without
|
// 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");
|
DIRECT_BUFFER_CONSTRUCTOR != null ? "available" : "unavailable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean unsafeStaticFieldOffsetSupported() {
|
||||||
|
return !RUNNING_IN_NATIVE_IMAGE;
|
||||||
|
}
|
||||||
|
|
||||||
static boolean isExplicitNoUnsafe() {
|
static boolean isExplicitNoUnsafe() {
|
||||||
return EXPLICIT_NO_UNSAFE_CAUSE != null;
|
return EXPLICIT_NO_UNSAFE_CAUSE != null;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user