【问题标题】:How can I throw an exception for an illegal reflective access warning?如何为非法反射访问警告抛出异常?
【发布时间】:2018-03-02 20:35:37
【问题描述】:

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

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

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

此代码向 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

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

当我搜索此警告消息时,我发现建议将其报告给包维护者、避免警告或完全禁用它 (JDK9: An illegal reflective access operation has occurred. org.python.core.PySystemState)。

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

我尝试根据 StackOverflow 问题 JUnit test for System.out.println() 测试打印到 System.err。这涉及将 System.err 设置为 ByteArrayOutputStream,然后检查内容。但不幸的是,根据How to hide warning “Illegal reflective access” in java 9 without JVM argument?,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");
    }
}

输出:

Start
err-1
End

【问题讨论】:

  • 我在 Apache Commons 问题跟踪器中打开了一个问题:issues.apache.org/jira/browse/LANG-1383
  • --illegal-access=deny 将导致预期的 IllegalAccessException 或 InaccessibleObjectException 被抛出。如果您只想要堆栈跟踪,那么 --illegal-access=debug 就是您要查找的内容。
  • @AlanBateman 谢谢,我会试试这个命令行参数!

标签: java reflection apache-commons-lang apache-commons-lang3 illegalaccessexception


【解决方案1】:
  1. 打开 Eclipse 开发环境。
  2. 选择运行菜单 –> 运行配置... –> Java 应用程序 –>(您的配置) –> 参数。
  3. 在 VM 参数文本框中,输入“--illegal-access=deny”[0]。
  4. 点击应用按钮。
  5. 点击运行按钮。
  6. 非法访问会抛出 java.lang.reflect.InaccessibleObjectException [1]。

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

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

【讨论】:

  • 请记住在创建配置时设置所有其他设置。我习惯于在没有配置的情况下直接运行它。查看设置,我必须设置 JRE、目录、主要类型、编译器版本等。
猜你喜欢
  • 2020-07-09
  • 1970-01-01
  • 2020-03-09
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多