Graal: [native-image] Micronaut doesn't work with GraalVM and JDK11

Created on 25 Nov 2019  路  7Comments  路  Source: oracle/graal

According to this PR https://github.com/netty/netty/pull/9631 Netty should work with JDK +9 with Graal but it doesn't work with Micronaut when using JDK11.

Steps to reproduce the issue:

  • git clone https://github.com/micronaut-graal-tests/micronaut-basic-app
  • cd micronaut-basic-app
  • git checkout jdk11
  • Use GraalVM 19.3.0-java11 or GraalVM built from master branch with JDK 11
  • ./build-native-image.sh
  • ./basic-app

Error:

18:09:13.631 [main] DEBUG i.m.web.router.DefaultRouteBuilder - Created Route: GET /hello/{name} -> HelloController#Single sayHi(String name) (application/json )
18:09:13.632 [main] DEBUG i.m.web.router.DefaultRouteBuilder - Created Route: HEAD /hello/{name} -> HelloController#Single sayHi(String name) (application/json )
18:09:13.642 [main] ERROR io.micronaut.runtime.Micronaut - Error starting Micronaut server: The offset of private final java.util.Set sun.nio.ch.SelectorImpl.selectedKeys is accessed without the field being first registered as unsafe accessed. Please register the field as unsafe accessed. You can do so with a reflection configuration that contains an entry for the field with the attribute "allowUnsafeAccess": true. Such a configuration file can be generated for you. Read CONFIGURE.md and REFLECTION.md for details.
com.oracle.svm.core.jdk.UnsupportedFeatureError: The offset of private final java.util.Set sun.nio.ch.SelectorImpl.selectedKeys is accessed without the field being first registered as unsafe accessed. Please register the field as unsafe accessed. You can do so with a reflection configuration that contains an entry for the field with the attribute "allowUnsafeAccess": true. Such a configuration file can be generated for you. Read CONFIGURE.md and REFLECTION.md for details.
    at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:101)
    at jdk.internal.misc.Unsafe.objectFieldOffset(Unsafe.java:50)
    at sun.misc.Unsafe.objectFieldOffset(Unsafe.java:640)
    at io.netty.util.internal.PlatformDependent0.objectFieldOffset(PlatformDependent0.java:505)
    at io.netty.util.internal.PlatformDependent.objectFieldOffset(PlatformDependent.java:651)
    at io.netty.channel.nio.NioEventLoop$4.run(NioEventLoop.java:225)
    at java.security.AccessController.doPrivileged(AccessController.java:80)
    at io.netty.channel.nio.NioEventLoop.openSelector(NioEventLoop.java:215)
    at io.netty.channel.nio.NioEventLoop.<init>(NioEventLoop.java:147)
    at io.netty.channel.nio.NioEventLoopGroup.newChild(NioEventLoopGroup.java:138)
    at io.netty.channel.nio.NioEventLoopGroup.newChild(NioEventLoopGroup.java:37)
    at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:84)
    at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:58)
    at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:47)
    at io.netty.channel.MultithreadEventLoopGroup.<init>(MultithreadEventLoopGroup.java:59)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:78)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:73)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:60)
    at io.micronaut.http.server.netty.NioEventLoopGroupFactory.createEventLoopGroup(NioEventLoopGroupFactory.java:70)
    at io.micronaut.http.server.netty.NettyHttpServer.newEventLoopGroup(NettyHttpServer.java:536)
    at io.micronaut.http.server.netty.NettyHttpServer.createWorkerEventLoopGroup(NettyHttpServer.java:427)
    at io.micronaut.http.server.netty.NettyHttpServer.start(NettyHttpServer.java:265)
    at io.micronaut.http.server.netty.NettyHttpServer.start(NettyHttpServer.java:97)
    at io.micronaut.runtime.Micronaut.lambda$start$2(Micronaut.java:70)
    at java.util.Optional.ifPresent(Optional.java:183)
    at io.micronaut.runtime.Micronaut.start(Micronaut.java:68)
    at io.micronaut.runtime.Micronaut.run(Micronaut.java:294)
    at io.micronaut.runtime.Micronaut.run(Micronaut.java:280)
    at example.micronaut.Application.main(Application.java:8)

Please not that Micronaut version 1.3.0.BUILD-SNAPSHOT used in that branch already includes Netty 4.1.43 (https://github.com/micronaut-projects/micronaut-core/blob/master/gradle.properties#L83) which contain the fix mentioned in https://github.com/netty/netty/pull/9631

native-image

Most helpful comment

The PR (https://github.com/micronaut-projects/micronaut-core/pull/2418) has been merged so it will be included in the next release. At this moment it has been merged in 1.2.x branch but we will merge it into master so it is also included in 1.3.0.M2.

All 7 comments

The problem is this config

{
  "name" : "sun.nio.ch.SelectorImpl",
  "allDeclaredFields" : true,
  "allDeclaredConstructors" : true
}

in file basic-app-0.1-all.jar!/META-INF/native-image/io.micronaut/http-netty-channel/reflection-config.json. It overrides the allowUnsafeAccess flag from the Netty config. The reflection configs are processed in the order they appear on the command line.

Thank you so much. I'll fix that in Micronaut.

To avoid this kind of errors on our side in the future, is there a way to display all the parameters "collected" from the jars that are used by native-image tool?

If you run native-image with --verbose you should see all the processed /native-image.properties files as well as the command line built from all the collected parameters. For your example code you can see the multiple -H:ReflectionConfigurationResources=... entries:

$ native-image --verbose --no-server --static --no-fallback --class-path build/libs/basic-app-*-all.jar
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/common/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/buffer/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/transport/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/handler/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/codec-http/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/io.micronaut.http/mime-types/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/io.micronaut/inject/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/io.micronaut/http/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/io.micronaut/netty/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/io.micronaut/http-netty-channel/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/io.micronaut/runtime-graal/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/io.micronaut/health/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/example/micronaut/basic-application/native-image.properties
Apply jar:file://~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar!/META-INF/native-image/example/micronaut/native-image.properties
Executing [
~/vm/graalvm-ee-java11-19.3.0/bin/java \
-XX:+UnlockExperimentalVMOptions \
-XX:+EnableJVMCI \
-Dtruffle.TrustAllTruffleRuntimeProviders=true \
-Dtruffle.TruffleRuntime=com.oracle.truffle.api.impl.DefaultTruffleRuntime \
-Dgraalvm.ForcePolyglotInvalid=true \
-Dgraalvm.locatorDisabled=true \
-Dsubstratevm.IgnoreGraalVersionCheck=true \
-Djava.lang.invoke.stringConcat=BC_SB \
--add-exports \
jdk.internal.vm.ci/jdk.vm.ci.runtime=ALL-UNNAMED \
--add-exports \
jdk.internal.vm.ci/jdk.vm.ci.code=ALL-UNNAMED \
--add-exports \
jdk.internal.vm.ci/jdk.vm.ci.aarch64=ALL-UNNAMED \
--add-exports \
jdk.internal.vm.ci/jdk.vm.ci.amd64=ALL-UNNAMED \
--add-exports \
jdk.internal.vm.ci/jdk.vm.ci.meta=ALL-UNNAMED \
--add-exports \
jdk.internal.vm.ci/jdk.vm.ci.hotspot=ALL-UNNAMED \
--add-exports \
jdk.internal.vm.ci/jdk.vm.ci.services=ALL-UNNAMED \
--add-exports \
jdk.internal.vm.ci/jdk.vm.ci.common=ALL-UNNAMED \
--add-exports \
jdk.internal.vm.ci/jdk.vm.ci.code.site=ALL-UNNAMED \
--add-exports \
jdk.internal.vm.ci/jdk.vm.ci.code.stack=ALL-UNNAMED \
--add-opens \
jdk.internal.vm.compiler/org.graalvm.compiler.debug=ALL-UNNAMED \
--add-opens \
jdk.internal.vm.compiler/org.graalvm.compiler.nodes=ALL-UNNAMED \
--add-opens \
jdk.unsupported/sun.reflect=ALL-UNNAMED \
--add-opens \
java.base/jdk.internal.module=ALL-UNNAMED \
--add-opens \
java.base/jdk.internal.ref=ALL-UNNAMED \
--add-opens \
java.base/jdk.internal.reflect=ALL-UNNAMED \
--add-opens \
java.base/java.io=ALL-UNNAMED \
--add-opens \
java.base/java.lang=ALL-UNNAMED \
--add-opens \
java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens \
java.base/java.lang.invoke=ALL-UNNAMED \
--add-opens \
java.base/java.lang.ref=ALL-UNNAMED \
--add-opens \
java.base/java.net=ALL-UNNAMED \
--add-opens \
java.base/java.nio=ALL-UNNAMED \
--add-opens \
java.base/java.nio.file=ALL-UNNAMED \
--add-opens \
java.base/java.security=ALL-UNNAMED \
--add-opens \
java.base/javax.crypto=ALL-UNNAMED \
--add-opens \
java.base/java.util=ALL-UNNAMED \
--add-opens \
java.base/java.util.concurrent.atomic=ALL-UNNAMED \
--add-opens \
java.base/sun.security.x509=ALL-UNNAMED \
--add-opens \
java.base/jdk.internal.logger=ALL-UNNAMED \
--add-opens \
org.graalvm.sdk/org.graalvm.nativeimage.impl=ALL-UNNAMED \
--add-opens \
org.graalvm.sdk/org.graalvm.polyglot=ALL-UNNAMED \
--add-opens \
org.graalvm.truffle/com.oracle.truffle.polyglot=ALL-UNNAMED \
--add-opens \
org.graalvm.truffle/com.oracle.truffle.api.impl=ALL-UNNAMED \
-XX:+UseJVMCINativeLibrary \
-Xss10m \
-Xms1g \
-Xmx14g \
-Duser.country=US \
-Duser.language=en \
-Dorg.graalvm.version=19.3.0 \
-Dorg.graalvm.config=EE \
-Dcom.oracle.graalvm.isaot=true \
--module-path \
~/vm/graalvm-ee-java11-19.3.0/lib/truffle/truffle-api.jar \
-Djdk.internal.lambda.disableEagerInitialization=true \
-Djdk.internal.lambda.eagerlyInitialize=false \
-Djava.lang.invoke.InnerClassLambdaMetafactory.initializeLambdas=false \
-cp \
~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/svm-llvm.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/objectfile.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/graal-llvm.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/svm-enterprise-llvm.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/svm.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/svm-enterprise.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/javacpp-shadowed.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/pointsto.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/llvm-platform-specific-shadowed.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/llvm-wrapper-shadowed.jar \
com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus \
-watchpid \
31292 \
-imagecp \
~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/svm-llvm.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/objectfile.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/graal-llvm.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/svm-enterprise-llvm.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/svm.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/svm-enterprise.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/javacpp-shadowed.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/pointsto.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/llvm-platform-specific-shadowed.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/builder/llvm-wrapper-shadowed.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/library-support-enterprise.jar:~/vm/graalvm-ee-java11-19.3.0/lib/svm/library-support.jar:~/projects/github/gh-1885/micronaut-basic-app/build/libs/basic-app-0.1-all.jar \
-H:Path=~/projects/github/gh-1885/micronaut-basic-app \
-H:+StaticExecutable \
-H:FallbackThreshold=0 \
-H:ClassInitialization=io.netty.util.AbstractReferenceCounted:run_time \
-H:ClassInitialization=io.netty.buffer.PooledByteBufAllocator:run_time,io.netty.buffer.ByteBufAllocator:run_time,io.netty.buffer.ByteBufUtil:run_time,io.netty.buffer.AbstractReferenceCountedByteBuf:run_time \
-H:ReflectionConfigurationResources=META-INF/native-image/io.netty/transport/reflection-config.json \
-H:ClassInitialization=io.netty.handler.ssl.util.ThreadLocalInsecureRandom:run_time \
-H:ClassInitialization=io.netty:build_time \
-H:ClassInitialization=io.netty.handler.codec.http.HttpObjectEncoder:run_time,io.netty.handler.codec.http.websocketx.WebSocket00FrameEncoder:run_time \
-H:IncludeResources=META-INF/http/mime.types \
-H:+AllowIncompleteClasspath \
-H:EnableURLProtocols=http,https \
-H:ReflectionConfigurationResources=META-INF/native-image/io.micronaut/http/reflection-config.json \
-H:ClassInitialization=com.sun.jndi.dns.DnsClient:run_time,io.netty.handler.ssl.ConscryptAlpnSslEngine:run_time,io.netty.handler.ssl.JettyNpnSslEngine:run_time,io.netty.handler.ssl.ReferenceCountedOpenSslEngine:run_time,io.netty.handler.ssl.JdkNpnApplicationProtocolNegotiator:run_time,io.netty.handler.ssl.ReferenceCountedOpenSslServerContext:run_time,io.netty.handler.ssl.ReferenceCountedOpenSslClientContext:run_time,io.netty.handler.ssl.util.BouncyCastleSelfSignedCertGenerator:run_time,io.netty.handler.ssl.ReferenceCountedOpenSslContext:run_time,io.micronaut.buffer.netty.NettyByteBufferFactory:run_time \
-H:ReflectionConfigurationResources=META-INF/native-image/io.micronaut/http-netty-channel/reflection-config.json \
-H:ClassInitialization=io.micronaut.reactive.reactor.ReactorInstrumentation:run_time \
-H:ClassInitialization=ch.qos.logback:build_time,com.fasterxml.jackson:build_time,io.micronaut:build_time,io.reactivex:build_time,org.reactivestreams:build_time,org.slf4j:build_time,org.yaml.snakeyaml:build_time,javax:build_time \
-H:ReflectionConfigurationResources=META-INF/native-image/io.micronaut/health/reflection-config.json \
-H:IncludeResources=logback.xml|application.yml|bootstrap.yml \
-H:Name=basic-app \
-H:Class=example.micronaut.Application \
-H:ReflectionConfigurationResources=META-INF/native-image/example/micronaut/reflection-config.json \
-H:CLibraryPath=~/vm/graalvm-ee-java11-19.3.0/lib/svm/clibraries/linux-amd64
]

Awesome, thanks!

@ilopmar when can we see a new Micronaut release with the fix?

The PR (https://github.com/micronaut-projects/micronaut-core/pull/2418) has been merged so it will be included in the next release. At this moment it has been merged in 1.2.x branch but we will merge it into master so it is also included in 1.3.0.M2.

Adding this here for reference as a workaround until we release next Micronaut version:

Create the file src/main/graal/reflect.json with the content:

[
  {
    "name": "sun.nio.ch.SelectorImpl",
    "fields": [
      {"name": "selectedKeys", "allowUnsafeAccess": true},
      {"name": "publicSelectedKeys", "allowUnsafeAccess": true}
    ]
  }
]
Was this page helpful?
0 / 5 - 0 ratings

Related issues

borkdude picture borkdude  路  3Comments

sxend picture sxend  路  3Comments

himanshumps picture himanshumps  路  3Comments

helloguo picture helloguo  路  3Comments

koduki picture koduki  路  3Comments