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

时间:2018-03-02 20:35:37

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

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

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

1 个答案:

答案 0 :(得分:2)

  1. Open the Eclipse development environment.
  2. Choose Run menu –> Run Configurations... –> Java Application –> (your configuration) –> Arguments.
  3. In the VM arguments text box, type "--illegal-access=deny" [0].
  4. Click the Apply button.
  5. Click the Run button.
  6. Illegal access will throw the 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