Преамбула
В пылу работы, особенно если могут отвлекать, люди могут забывать очевидные вещи.Не потому что они плохие или некомпетентные, не потому что мало времени,а просто потому что вот забыли и всего делов.
Особенно больно становится когда твой код на Java, а люди забыли про определение методов equals и hashCode у объектов представляющих собой сущности в домене. toString конечно еще, но с ним чуть больше нюансов - современные IDE предоставляют хорошую интроспекцию объектов в дебаге, поэтому найти то, что toString продолбан чаще всего получается уже в логах с прода, где он не дает никакой информации.
А вот с equals и hashCode все веселее и проще - они иногда приводят к дням веселой отладки в попытках понять что же происходит.
И все это начинает пестрить красками особенно ярко в тот самый момент, когда проблема закопана в библиотеке, которую вы используете в другой библиотеке, а эту в свою очередь уже где-нибудь еще.
И я решил что нужно попробовать сделать хоть какой-то инструмент для борьбы с этой проблемой.
Почему не статический анализ кода?
Инструмент для обнаружения проблемы можно построить и не с нуля, используя средства статического анализа кода типа findbugz, checkstyle, pmd.Все они предоставляют возможность расширения набора правил анализа, и все они open-source.
И все они обладают избыточным набором правил анализа на все случаи жизни, который можно и приходится настраивать.
И ни один из указанных инструментов не может проверить нужные мне условия прямо из коробки.
И самое главное - редко когда и мало кто ставит этот статический анализ кода в таком месте своего жизненного цикла разработки так чтобы он прерывал сборку проекта.
Мне же хотелось иметь средство, которое по умолчанию будет останавливать сборку проекта.
Почему именно так ?
Мне совершенно не хотелось строить свое решение на построении AST, потому что это сравнительно дорого, так уже делают статические анализаторы кода, и если уж честно хотелось попробовать чего-то нового.Для решения своей проблемы я решил попробовать использовать инструменты языка , а конкретнее возможности по процессингу аннотаций.
Вообще толковых материалов о том что такое процессинг аннотаций и как им пользоваться в интернетах не так уж и много.
Идея решения проста - в процессе написания кода нужно поставить одну аннотацию, остальное компилятор при помощи процессоров аннотаций сделает сам.
Естественно процессор аннотации нужно написать, естественно аннотацию нужно повесить на класс, и если этого не сделать, то никакой процессинг не сработает.
Но аннотацию нужно поставить одну, а методов про которые нужно не забыть - три, так что уже выигрываем.
Аннотаций я пока реализовал две:
@Pojo - проверяет что у класса определены equals, hashCode, toString
@Helper - проверяет что класс соотвествует идее хэлпера (все методы статические, конструктор приватный, все поля константы, никакого состояния иметь не должен).
В натуре
В натуре это все выложено на гитхаб.Вот репозиторий с аннотациями и процессорами, а вот тут лежит тестовый проектик. Инструкция по запуску здесь.
При попытке компиляции тестового проекта вы увидите вот такую вот своершенно неизящный вывод в консоли.
Для тех кто не поленится сходить и почитать код сразу предупреждение - там есть говнокод, особенно в местах по анализу и сравнению типов возвращаемых методами. Сделано отвратительно, самому не нравится, но пока живет. Как исправлю - обязательно выложу.
Мысли по ходу.
Мыслей в связи с этим вот pet project у меня накопилось больше, чем сам проект.- Казалось бы фундаментальнейшая и низкоуровнвая вещь, такая как процессор аннотаций, должна быть вылизана, задокументирована и спроектирована очень хорошо. Но вот с документацией вообще швах.
- Информации и примеров того как это делать правильно в интернете не очень много. Свою подборку ссылок приведу в конце.
Я не нашел ни одного вменяемого метода для тестирования этих процессоров аннотаций, кроме как создать отдельный проект в котором эти самые аннотации будут развешаны на классах дающих нужные кейсы.(смотри апдейт ниже) В мыслях крутиться использования инфраструктуры для тестирования плагинов к maven, но этот ад мы прибережем для следующей серии нашей мыльной оперы.- Если отбросить лично мои заморочки и скомбинировать подход с построением AST, то анализатор может получится весьма и весьма мощный.
- Сразу нужно думать про нормальный репортинг, посколько API процессора аннотаций ничего кроме как минималистичного вывода в консоль делать не дает. То есть проанализировать код, найти плохое место в нем вы конечно можете но вот отрапортовать об этом будет сложно. Нужно писать что-то сбоку.
- Чтобы вся эта радость нормально работала библиотеку с аннотациями и процессорами нужно подключать к мавену в scope = provided. Так и только так!!! Иначе зависимость на аннотации и анализатор полезет дальше транзитивно, а мы помним что это всего лишь инструмент, не более того.
Ссылки
- Пост на хабре вдохновивший меня сделать это.
- Туториал по похожему кейсу.
- Фундаментальная статей про процессинг аннотаций в Java. Все разжевано и разложено по полочкам.
- Еще один хороший туториал в трех
частяхпостах (раз, два, три)
UPD 22.11.2016 В процессе археологических раскопок кургана Гитхаб наша экспедиция нашла древний артефакт для тестирования кода процессоров. Подключили, попробовали - работает!
Комментариев нет:
Отправить комментарий