如何为非法反射访问警告抛出异常?

Bri*_*ack 6 java reflection illegalaccessexception apache-commons-lang apache-commons-lang3

如何为非法反射访问警告抛出异常?例如,考虑以下代码:

import org.apache.commons.lang3.builder.*;

class Test {
    public static void main(String[] args) {
        System.out.println(ReflectionToStringBuilder.toString(Boolean.TRUE));
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码向 System.err 打印以下警告:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.commons.lang3.builder.ReflectionToStringBuilder (file:/Users/brianschack/eclipse-workspace/User%20Libraries/com
mons-lang3-3.7/commons-lang3-3.7.jar) to field java.lang.Boolean.value
WARNING: Please consider reporting this to the maintainers of org.apache.commons.lang3.builder.ReflectionToStringBuilder
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
Run Code Online (Sandbox Code Playgroud)

Boolean.TRUE 是一个如此简单的值,我真的不需要 ReflectionToStringBuilder。但是更复杂的类型(例如 HashMap)会打印相同的警告。我选择 Boolean.TRUE 是为了简化这个例子。

当我搜索此警告消息时,我发现建议将其报告给包维护者、避免警告或完全禁用它(JDK9:发生非法反射访问操作。org.python.core.PySystemState)。

我想为警告抛出异常,以便获得非法访问发生位置的堆栈跟踪。然后我可以更改代码以避免导致警告的非法访问。我还想做一个单元测试,以便将来检查警告。

我试图根据 StackOverflow 问题,即System.out.println() 的 JUnit 测试来测试是否打印到 System.err 。这涉及将 System.err 设置为 ByteArrayOutputStream,然后检查内容。但不幸的是,根据如何在没有 JVM 参数的情况下在 java 9 中隐藏警告“非法反射访问”?,IllegalAccessLogger 在 JVM 引导期间获得对 System.err 的引用,然后我才能更改它。

我也尝试关闭 System.err,但似乎打印到关闭的流会以静默方式失败而不是引发异常。请注意,以下代码的输出不包含字符串“err-2”:

代码:

class Test {
    public static void main(String[] args) {
        System.out.println("Start");
        System.err.println("err-1");
        System.err.close();
        System.err.println("err-2");
        System.out.println("End");
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

Start
err-1
End
Run Code Online (Sandbox Code Playgroud)

Bri*_*ack 2

    \n
  1. 打开Eclipse开发环境。
  2. \n
  3. 选择“运行”菜单 \xe2\x80\x93> 运行配置...\xe2\x80\x93> Java 应用程序 \xe2\x80\x93>(您的配置)\xe2\x80\x93> 参数。
  4. \n
  5. 在虚拟机参数文本框中,键入“--illegal-access=deny”[0]。
  6. \n
  7. 单击“应用”按钮。
  8. \n
  9. 单击运行按钮。
  10. \n
  11. 非法访问会抛出java.lang.reflect.InaccessibleObjectException[1]。
  12. \n
\n\n

[0] http://mail.openjdk.java.net/pipermail/jigsaw-dev/2017-May/012673.html

\n\n

[1] http://docs.oracle.com/javase/9​​/docs/api/java/lang/reflect/InaccessibleObjectException.html

\n