Статическая проверка Java-приложения на наличие ошибок ссылок
У меня есть сценарий, в котором у меня есть код, написанный для версии 1 библиотеки, но я хочу отправить версию 2 библиотеки вместо этого. Код отправлен и поэтому не подлежит изменению. Я обеспокоен тем, что он может попытаться получить доступ к классам или членам библиотеки, которая существовала в v1, но была удалена в v2.
Я подумал, что можно было бы написать инструмент для простой проверки того, будет ли код ссылаться на более новую версию библиотеки. Я ценю, что код может все еще быть очень сломанным, даже если код ссылается. Я думаю об этом с другой стороны - если код не будет ссылаться, то я могу быть уверен, что есть проблема.
Насколько я вижу, мне нужно пройти через байт-код, проверяя ссылки, вызовы методов и обращения к полям к классам библиотеки, а затем использовать отражение, чтобы проверить, существует ли класс / член.
У меня тройной вопрос:
(1) Такой инструмент уже существует?
(2) Я чувствую, что это гораздо сложнее, чем я себе представляю, и что я пропустил что-то важное - так ли это?
(3) Знаете ли вы о удобной библиотеке, которая позволила бы мне проверять байт-код, чтобы я мог найти вызовы методов, ссылки и т. Д.?
Спасибо!
5 ответов
Я думаю, что Clirr - бинарная проверка совместимости - может помочь здесь:
Clirr - это инструмент, который проверяет библиотеки Java на двоичную и исходную совместимость со старыми версиями. По сути, вы предоставляете ему два набора jar-файлов, а Clirr выдает список изменений в общедоступном API. Задача Clirr Ant может быть настроена на прерывание сборки, если она обнаруживает несовместимые изменения API. В процессе непрерывной интеграции Clirr может автоматически предотвратить случайное появление проблем совместимости двоичного кода или исходного кода.
Изменение библиотеки в вашей IDE приведет ко всем возможным ошибкам во время компиляции.
Вам больше ничего не нужно, если только ваш код не использует другую библиотеку, которая, в свою очередь, использует обновленную библиотеку.
Будьте особенно осторожны с конфигурационными файлами Spring. Имена классов настроены как текстовые и не отображаются как отсутствующие до времени выполнения.
Если у вас есть доступ к исходному коду, вы можете просто скомпилировать исходный код для новой библиотеки. Если он не компилируется, у вас определенно есть проблема. Если он компилируется, у вас все еще могут быть проблемы, если программа использует рефлексию, что-то вроде IoC, например Spring и т. Д.
Если у вас есть модульные тесты, то вы можете лучше изменить ловлю ошибок связывания.
Если у вас есть только файл.class программы, то я не знаю каких-либо инструментов, которые могли бы помочь, кроме декомпозиции файла класса с исходным кодом и повторной компиляции исходного кода для новой библиотеки, но это звучит не слишком здорово.
Упомянутые вами проверки выполняются загрузчиком классов JVM/Java, см., Например, связывание классов и интерфейсов.
Таким образом, "попытка связать" может быть просто достигнута при попытке запустить приложение. Конечно, вы можете поднять чеки, чтобы запустить их самостоятельно в вашей коллекции файлов.class/.jar. Я полагаю, что некоторые сторонние манипуляторы с байтовым кодом, такие как BCEL, также выполнят аналогичные проверки для вас.
Я заметил, что вы упоминаете отражение в тегах. Если вы загружаете классы / вызываете методы через рефлексию, нет никакого способа проанализировать это в целом.
Удачи!