Время от времени я получаю исключения, такие как NoSuchMethodError
или NoClassDefFoundError
в моих проектах во время выполнения. Проекты создаются по Maven
без каких-либо предупреждений.
Исследования показали, что это произошло из-за того, что у меня была прямая зависимость в моем проекте, которая требовала другую версию библиотеки, которую я также использовал напрямую. Таким образом, зависимость дерево может выглядеть примерно так:Как предотвратить исключения времени компиляции Java во время выполнения?
- my_project 1.0
- Apache HTTP-клиент 4.2.0
- CXF 2,6
- апач клиент HTTP 4.1.0
или вот так:
- my_project 1.0
- Apache HTTP-клиент 4.2.0
- Apache Commons кодек 1.9
- распорки 2.3
- Apache Commons кодек 1.4
- Apache HTTP-клиент 4.2.0
Я исправил эти проблемы, ища общий совместимый знаменатель конфликтной зависимости. Но это было только после того, как я получил ошибку в производстве.
Итак, вопрос в том, как предотвратить ошибки этого типа в ползучести в производственных сборках?
У меня есть некоторые идеи, как решить эту проблему:
Не напрямую зависят от библиотеки, если у вас уже есть переходную версию. Итак, в случае дерева зависимостей # 1 я удалю apache http client 4.2.0 и начну использовать apache http client 4.1.0. Мне, вероятно, нужно будет изменить свой код, чтобы сделать это, но для меня это кажется прекрасным. Или я мог бы обновить CXF до более новой версии, которая использует apache http client 4.2.0 и удаляет прямую зависимость от apache http client 4.2.0 из моего pom.xml. В этом случае каждая несовместимая команда изменений CXF делает по отношению к клиенту apache http, я заметил: мой собственный код не будет компилироваться. Не знаю, как использовать этот подход с деревом зависимостей # 2.
Использование/расширение инструмента статического анализа для обнаружения отсутствующих методов или классов. Меня беспокоит то, что я не мог найти инструменты, выполняющие именно такую работу. Это приводит к выводу, что у моей проблемы есть и другое решение. В противном случае кто-то создал такой инструмент.
Полностью измените мой подход к сборке. Создайте все (все необходимые библиотеки и собственный проект) из источников. Компилятор позаботится о проверке отсутствующих методов и классов.
Написать тесты. Похоже на хороший подход.Но трудно предсказать, какие потоки должны быть протестированы (например, на удаленном удаленном сервере может отвечать некоторая схема кодирования, о которой я не знал), и тестирование всех потоков кажется нецелесообразным, потому что в основном вы переписываете тесты библиотеки.
Ни один из этих подходов не кажется полным для меня. Какой подход вы используете? Как вы решаете эту проблему?
В Java нет такой вещи, как «исключение времени компиляции». – EJP