Ковыряю тут на досуге вопросы защиты от NullPointerException в Java.
Пока выбрал такую связку:
— в коде — NotNull/Nullable аннотации от JetBrains
— чтоб не расставлять NotNull на каждой строчке, взять Null4J — оно дает аннотацию NotNullByDefault, которую можно влепить на весь класс и получить не-null по умолчанию. Оно там немного не в том виде, в каком мне надо, но для начала сойдет
— С IDE понятно — IDEA умеет отслеживать аннотации и подсвечивать возможные нарушения
— Чтоб контролировать следование этим аннотациям на уровне билда, берем связку из статического анализатора error-prone от Google + плагин NullAway от Uber к нему. Все плагины кроме контроля Null-аннотаций пока отключаем, для скорости.
Так вот.. этот самый error-prone работает как надстройка над компилятором и фактически в билде вызывается этот самый error-prone вместо javac. Оно как бы работает, но теперь некошерно, что продакшн-билд собирается этим анализатором, а не ванильной JDK. В нашем энтерпрайзе такой билд не примут, у меня несколько месяцев ушло на то чтоб аннотации от JetBrains одобрили. А билд, с использованием сторонней надстройки, скорее всего, тут же развернут.
По этим причинам, да и просто для собственного спокойствия, хочется чтоб error-prone вызывался не для основного билда, а как вспомогательная задача. Чтоб добавить в Maven какую-нибудь дополнительную цель, которая будет вызываться только для генерации отчета, но не для получения продакшен-бинарников.
Подскажите, как в Maven добавить такую цель? С Maven'ом я пока знаком несколько поверхностно. Посмотрел кое-какие руководства и курсы, но они все концентрируются на базовом функционале, не давая особых примеров и пояснений по дополнительным настройкам и расширению билдов.
Про другие анализаторы вроде FindBug/Spotbug знаю, игрался с ними. До error-prone они не дотягивают, ну или я не умею их готовить. Простейшие случаи вроде этого они ловят:
@NotNull Object foo() {
return null;
}
А если логика чуть посложнее, то уже не ловят:
@NotNull Object foo(int i) {
return someMap.get(i); // <- тут возвращается null, если элемент не найден
}
Error-prone + NullAway пока единственная комбинация, которая поймала нарушение аннотации на этом примере и некоторых других не-тривиальных случаях, которые я попробовал.
Здравствуйте, Artem Korneev, Вы писали:
AK>Подскажите, как в Maven добавить такую цель? С Maven'ом я пока знаком несколько поверхностно. Посмотрел кое-какие руководства и курсы, но они все концентрируются на базовом функционале, не давая особых примеров и пояснений по дополнительным настройкам и расширению билдов.
В мавене все нестандартное плохо вкорячивается. Можно попробовать немного анта в мавен добавить или сделать профиль и запускать с ним отдельно.
AK>Так вот.. этот самый error-prone работает как надстройка над компилятором и фактически в билде вызывается этот самый error-prone вместо javac. Оно как бы работает, но теперь некошерно, что продакшн-билд собирается этим анализатором, а не ванильной JDK. В нашем энтерпрайзе такой билд не примут, у меня несколько месяцев ушло на то чтоб аннотации от JetBrains одобрили. А билд, с использованием сторонней надстройки, скорее всего, тут же развернут.
С чего ты взял? Код по прежнему компилируется с помощью javac. Сравни генерируемый jar с плагином и без — я думаю, должно быть одинаково
Здравствуйте, bzig, Вы писали:
B>С чего ты взял? Код по прежнему компилируется с помощью javac.
Если error-prone вызывается вместо прямого вызова javac, то чисто теоретически оно может менять генерируемый байт-код, а это уже потребует кучу разрешений и одобрений для использования. Плюс, я и сам не смогу ручаться, что оно беспроблемно подхватит любой апгрейд JDK — одно дело отвалившийся вспомогательный репорт, другое дело полностью поломаный билд.
С организационной точки зрения мне куда проще предложить такой подход, который не потребует изменения продакш билда.
Здравствуйте, GarryIV, Вы писали:
GIV>Можно попробовать немного анта в мавен добавить или сделать профиль и запускать с ним отдельно.
Т.е. искать по ключевым словам "профиль maven"? Спасибо, попробую.
Ант немного пугает, но если понадобится, то и его можно раскурить.
GIV>Грейдл рулит в таких сценариях.
Проект большой, в нем десятки под-проектов, и везде используется Maven. Тащить Gradle всего-лишь из-за статического анализатора для одного из под-проектов врятли есть смысл. Да и руководство не одобрит. Уж проще раскурить ант.
AK>Если error-prone вызывается вместо прямого вызова javac,
Он не вызывается вместо явац, а как плагин к явац. Теоритически, он может генерировать байт код, но называется он "статический анализатор", а значит не должен. Именно поэтому я тебе предлагаю скомпилировать с плагином и без и побайтово сравнить результат. Если тот же, то значит он своего байт кода не генерирует.
AK>С организационной точки зрения мне куда проще предложить такой подход, который не потребует изменения продакш билда.
Просто прогоняй ещё раз с плагином. Профили один из способов.