Netty- cannot access class jdk.internal.misc.Unsafe
Asked Answered
S

5

52

When I upgraded the Java from 8 to 11, I got an error from Netty about the "jdk.internal.misc.Unsafe", the details are below:

I knew it is a debug level message, and I can change the level of the log to ignore it. But I'm not sure if there would be other problems - such as performance - when I ignore it. Does anyone know the best solution to this?

java.lang.IllegalAccessException: class io.netty.util.internal.PlatformDependent0$6 cannot access class jdk.internal.misc.Unsafe (in module java.base) because module java.base does not export jdk.internal.misc to unnamed module @84b8f0f
    at jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:361) ~[?:?]
    at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:591) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:558) ~[?:?]
    at io.netty.util.internal.PlatformDependent0$6.run(PlatformDependent0.java:334) ~[netty-all-4.1.36.Final.jar:4.1.36.Final]
    at java.security.AccessController.doPrivileged(Native Method) ~[?:?]
    at io.netty.util.internal.PlatformDependent0.<clinit>(PlatformDependent0.java:325) ~[netty-all-4.1.36.Final.jar:4.1.36.Final]
    at io.netty.util.internal.PlatformDependent.isAndroid(PlatformDependent.java:214) ~[netty-all-4.1.36.Final.jar:4.1.36.Final]
    at io.netty.util.internal.PlatformDependent.<clinit>(PlatformDependent.java:82) ~[netty-all-4.1.36.Final.jar:4.1.36.Final]
    at io.netty.buffer.UnpooledByteBufAllocator.<clinit>(UnpooledByteBufAllocator.java:37) ~[netty-all-4.1.36.Final.jar:4.1.36.Final]
    at io.netty.buffer.Unpooled.<clinit>(Unpooled.java:73) ~[netty-all-4.1.36.Final.jar:4.1.36.Final]
    at wedo.stream3.framework.base.connector.supplier.DelimiterDecoderSupplier.getDelimiter(DelimiterDecoderSupplier.java:41) ~[classes/:?]
    at wedo.stream3.framework.base.connector.supplier.DelimiterDecoderSupplier.<init>(DelimiterDecoderSupplier.java:26) ~[classes/:?]
    at wedo.stream3.framework.base.connector.supplier.DelimiterDecoderSupplier.<init>(DelimiterDecoderSupplier.java:20) ~[classes/:?]
    at wedo.stream3.framework.base.connector.supplier.CommonChannelHandlerSupplier.<init>(CommonChannelHandlerSupplier.java:37) ~[classes/:?]
    at wedo.stream3.framework.base.connector.supplier.CommonChannelHandlerSupplier.<init>(CommonChannelHandlerSupplier.java:25) ~[classes/:?]
    at wedo.stream3.framework.base.connector.TcpClientConnector.start(TcpClientConnector.java:39) ~[classes/:?]
    at wedo.stream3.framework.bootstrap.FrameworkLauncher.lambda$start$0(FrameworkLauncher.java:61) ~[classes/:?]
    at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) [?:?]
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177) [?:?]
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654) [?:?]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) [?:?]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) [?:?]
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) [?:?]
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) [?:?]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) [?:?]
    at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497) [?:?]
    at wedo.stream3.framework.bootstrap.FrameworkLauncher.start(FrameworkLauncher.java:58) [classes/:?]
    at org.stream3.prototype.mfc.App.launchFramework(App.java:58) [classes/:?]
    at org.stream3.prototype.mfc.App.main(App.java:41) [classes/:?]
Silken answered 11/9, 2019 at 9:13 Comment(0)
L
53

To allow netty to access the class, start java with the following option:

--add-opens java.base/jdk.internal.misc=ALL-UNNAMED

This opens the package jdk.internal.misc in module java.base to the unamed module.

See also the documentation for the java command, and this intro to the Java module system in general.

EDIT: For Netty to use its direct buffer optimizations, you also need to set

-Dio.netty.tryReflectionSetAccessible=true

There are a number of Netty issues on this subject, see e.g. netty/issues/7769

Luisluisa answered 11/9, 2019 at 15:46 Comment(6)
But there still has another message left: 09:10:28.902 [main] DEBUG io.netty.util.internal.PlatformDependent0 - direct buffer constructor: unavailable java.lang.UnsupportedOperationException: Reflective setAccessible(true) disabled Is there any method to solve this ?Silken
There is an issue on the netty github about that problem: github.com/netty/netty/issues/7817Luisluisa
Thank you very much. But I want to know does this parameter affect the performance ?Silken
I don't have the answer, but I notice that your netty version is from April. It could be worth a try to upgrade to the most recent version to see if the problem has been fixed: mvnrepository.com/artifact/io.netty/netty-all/4.1.41.FinalLuisluisa
How do you pass these options to run mvn test?Jennine
You can use <argLine> in the configuration to maven-surefire-plugin in your pom.xml. For exampe (sorry for bad formatting): <configuration><argLine>--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED</argLine></configuration>Luisluisa
H
21

When running Netty on Java 11, add these VM options to enable performance optimizations:

--add-opens java.base/jdk.internal.misc=ALL-UNNAMED
-Dio.netty.tryReflectionSetAccessible=true

Then, to know when deep reflection is used, you may add:

--illegal-access=warn
Hy answered 9/11, 2019 at 10:17 Comment(0)
K
5

As you said this is just an debug message and can be ignored. It basically tells you that Netty can not make use of "all optimisations" because it can not access a class. If you want you can open up the access level via command line flags when starting your application tho.

Korney answered 11/9, 2019 at 10:6 Comment(1)
Is this optimization something one would want to enable by default? Is this mentioned in some official guide, for instance?Glissando
C
3

Netty requires access, to a jdk module, so to allow access you need to add a jvm argument when starting your application.

--add-opens java.base/jdk.internal.misc=ALL-UNNAMED

Additionally if you want to disable "java.lang.UnsupportedOperationException: Reflective setAccessible(true) disabled....." warning stacktrace, you can also include:

-Dio.netty.tryReflectionSetAccessible=true

If you are using gradle, you can add these on your build.gradle as follows:

   distributions {
        applicationDefaultJvmArgs = ["--add-opens",
                                     "java.base/jdk.internal.misc=ALL-UNNAMED", "-Dio.netty.tryReflectionSetAccessible=true"]
        mainClassName = 'cl.domain.ServerLauncher'
        archivesBaseName = 'your-service'
        version = 'latest'
        main {
            baseName = 'your-service'
        }
    }
Columniation answered 26/10, 2021 at 15:49 Comment(0)
D
3

Unfortunately, using the latest version of io.grpc:grpc-netty-shaded:1.53.0 , I found that the following is what you need (not the same flag names as above), running on Java 11.

-Dio.grpc.netty.shaded.io.netty.tryReflectionSetAccessible=true
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED

As you can see in the source code io.netty.tryReflectionSetAccessible is no longer the property being checked.

Dyun answered 3/3, 2023 at 1:28 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.