如何隐藏警告“非法反射访问"在没有 JVM 参数的 java 9 中?
我刚刚尝试使用 Java 9 运行我的服务器并收到下一个警告:
I just tried to run my server with Java 9 and got next warning:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by io.netty.util.internal.ReflectionUtil (file:/home/azureuser/server-0.28.0-SNAPSHOT.jar) to constructor java.nio.DirectByteBuffer(long,int)
WARNING: Please consider reporting this to the maintainers of io.netty.util.internal.ReflectionUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
我想隐藏此警告,而不在启动期间将 --illegal-access=deny
添加到 JVM 选项.比如:
I would like to hide this warning without adding --illegal-access=deny
to JVM options during start. Something like:
System.setProperty("illegal-access", "deny");
有什么办法吗?
建议使用 JVM 选项的所有相关答案,我想从代码中关闭它.这可能吗?
All related answers suggesting to use JVM options, I would like to turn off this from code. Is that possible?
澄清一下 - 我的问题是关于从代码中转换此警告,而不是通过类似问题中所述的 JVM 参数/标志.
To clarify - my question is about turning this warning from the code and not via JVM arguments/flags as stated in similar questions.
推荐答案
有一些方法可以禁用非法访问警告,但我不建议这样做.
There are ways to disable illegal access warning, though I do not recommend doing this.
由于警告打印到默认错误流,您可以简单地关闭此流并将 stderr
重定向到 stdout
.
Since the warning is printed to the default error stream, you can simply close this stream and redirect stderr
to stdout
.
public static void disableWarning() {
System.err.close();
System.setErr(System.out);
}
注意事项:
- 这种方法合并了错误流和输出流.在某些情况下,这可能是不可取的.
- 您不能仅通过调用
System.setErr
来重定向警告消息,因为对错误流的引用在 JVM 引导的早期保存在IllegalAccessLogger.warningStream
字段中.
- This approach merges error and output streams. That may not be desirable in some cases.
- You cannot redirect warning message just by calling
System.setErr
, since the reference to error stream is saved inIllegalAccessLogger.warningStream
field early at JVM bootstrap.
一个好消息是 sun.misc.Unsafe
仍然可以在 JDK 9 中访问而不会出现警告.解决方案是借助 Unsafe API 重置内部 IllegalAccessLogger
.
A good news is that sun.misc.Unsafe
can be still accessed in JDK 9 without warnings. The solution is to reset internal IllegalAccessLogger
with the help of Unsafe API.
public static void disableWarning() {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe u = (Unsafe) theUnsafe.get(null);
Class cls = Class.forName("jdk.internal.module.IllegalAccessLogger");
Field logger = cls.getDeclaredField("logger");
u.putObjectVolatile(cls, u.staticFieldOffset(logger), null);
} catch (Exception e) {
// ignore
}
}
相关文章