Как я могу выдать исключение для предупреждения о незаконном отражающем доступе?

Как я могу выдать исключение для предупреждения о незаконном отражающем доступе? Например, рассмотрим следующий код:

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: произошла недопустимая операция отражающего доступа. Org.python.core.PySystemState).

Я хотел бы выдать исключение для предупреждения, чтобы получить трассировку стека, где произошел незаконный доступ. Тогда я мог бы изменить код, чтобы избежать несанкционированного доступа, вызвавшего предупреждение. Я также хотел бы сделать модульный тест, который проверил бы для предупреждения в будущем.

Я пытался проверить печать в System.err в соответствии с вопросом Stackru, тест JUnit для System.out.println (). Это включает в себя настройку System.err для ByteArrayOutputStream и последующую проверку содержимого. Но, к сожалению, согласно Как скрыть предупреждение "Незаконный рефлексивный доступ" в java 9 без аргумента JVM?, IllegalAccessLogger получает ссылку на System.err во время начальной загрузки JVM, прежде чем я могу изменить его.

Я также попытался закрыть 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 ответ

Решение
  1. Откройте среду разработки Eclipse.
  2. Выберите меню "Выполнить" -> "Выполнить настройки" -> "Приложение Java" -> (ваша конфигурация) -> "Аргументы".
  3. В текстовом поле аргументов виртуальной машины введите "--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

Другие вопросы по тегам