"недопустимое использование @throws" при компиляции при наличии log4j-core в classpath
Мы начали получать эту ошибку на наших тестах около недели назад. Это было включено и выключено - иногда люди получат это, а другие не будут.
/.../product/integration/src/test/java/com/acme/integration/code/CodeTestUtils.java:74: error: invalid use of @throws
* @throws Exception if an error occurs.
Я думаю, что сообщение об ошибке немного расплывчато. Неверно, как? Код выглядит нормально для меня:
/**
* Iterates to find modules and then calls
* {@link #checkModule(Path, String, DirectoryStream.Filter, CheckFile)} for each.
*
* @param subPath the path within each module to start checks from.
* @param filter the filter to apply to choose which files to check.
* @param checkFile the checks to perform on each file.
* @throws Exception if an error occurs.
*/
public static void checkProject(String subPath, DirectoryStream.Filter<Path> filter, CheckFile checkFile) throws Exception
{
for (Path file : listFiles(EnvironmentUtils.getDevelopmentRoot().toPath()))
{
if (FileUtils.isDirectory(file) && FileUtils.exists(file.resolve("src/java")))
{
checkModule(file, subPath, filter, checkFile);
}
}
}
Мы включаем doclint во время компиляции, потому что мы хотим узнать об ошибках Javadoc без необходимости отдельного запуска Javadoc.
Что именно должна означать эта ошибка? Есть ли что-то недопустимое в том, что мы здесь делаем? Мы смотрим на ошибку компилятора? Конечно, ошибка, подобная этой, поразит первого человека, который попытался объявить, что метод вызывает исключение...:(
Расследование пока...
- Мне удалось сократить пример до простого проекта, который выдает ту же ошибку. Помимо того, что Travis CI может воспроизводить его в Linux, я могу воспроизвести его здесь в macOS, начиная с сегодняшнего дня (не знаю, почему это зависит от времени!), И другие пользователи Windows уже говорили об этом уже пару дней.
- Из этого проекта я посмотрел на командную строку, которую Gradle использовал для javac, и ему удалось получить ту же ошибку, которая вызвала вызов javac напрямую.
Вырубаем командную строку javac дальше:
javac -source 1.8 -target 1.8 -d build/classes/test \ -classpath build/classes/main:build/resources/main:$HOME/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-core/2.8.2/979fc0cf8460302e4ffbfe38c1b66a99450b0bb7/log4j-core-2.8.2.jar:$HOME/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-api/2.8.2/e590eeb783348ce8ddef205b82127f9084d82bf3/log4j-api-2.8.2.jar \ -Xdoclint:all,-missing \ src/test/java/com/acme/CodeTestUtils.java
Это показывает, что проблема все еще происходит без Gradle на картинке. (Gradle добавил
-processorpath
а также-g
тоже.)
3 ответа
В конце концов я подал заявку на Log4j, полагая, что даже если бы это была ошибка в javac, Oracle так или иначе не исправит критические ошибки, о которых мы сообщаем.
Очевидно, что обработка пользовательских аннотаций в Log4j каким-то образом вызывает проблему - в комментарии там предлагается добавить -proc:none
в командной строке javac, чтобы отключить всю обработку аннотаций, и действительно, при отключенной обработке аннотаций компиляция теперь работает!
Почему именно процессор аннотаций вызывает это, до сих пор остается загадкой. Я прочитал код, но, похоже, он не изменял существующие классы.
Согласно исходному коду DocLint OpenJDK, это сообщение связано со свойством "dc.invalid.throws", и это сообщение свойства выводится как ошибка, если вы используете тег @throws либо с типом не-Исключения, либо если вы используете это что-то кроме конструктора или метода.
Ни один из них, кажется, не применяется в вашем случае. Однако я видел, как несколько человек жалуются, что получают это сообщение с несовместимыми сборками - обычно ответом является полная перестройка.
Например, это Lucene Jira, которое относится к тому же сообщению об ошибке, ответ:
Эти ошибки обычно случаются (особенно в сборке Solr), если в выходной папке все еще есть устаревшие файлы классов или если предыдущий прогон компиляции не удался.
Я продублировал эту проблему без Log4j. Проект находится по адресу https://github.com/rgoers/LOG4J2-1925. Из того, что я могу сказать, это произойдет с любым процессором аннотаций.
Эта ошибка была подана в Oracle по адресу http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8186647.