Вы спрашиваете, что является «лучшей практикой» для этой проблемы. Я собираюсь предположить, что под «этой проблемой» вы подразумеваете проблему обновлений сторонних библиотек, а именно, эти два вопроса:
Когда вы должны обновить?
Что вы должны сделать, чтобы защитить себя от неудачных обновлений (например, об ошибке в кодексе commons-codec, упомянутой в вашем примере)?
Чтобы ответить на первый вопрос, «когда вам следует обновиться?», В промышленности существует множество стратегий. В большей части коммерческого мира Java я считаю, что в настоящее время доминирующая практика заключается в том, что «вы должны обновиться, когда будете к этому готовы». Другими словами, как разработчик, вы сначала должны осознать, что доступна новая версия библиотеки (для каждой из ваших библиотек!), Затем вам нужно интегрировать ее в свой проект, и вы тот, кто делает окончательный вариант решение go / no-go, основанное на вашем собственном тестовом стенде - юнит, регрессия, ручное тестирование и т. д. - что бы вы ни делали, чтобы гарантировать качество. Maven облегчает этот подход (я называю это «закреплением» версии), делая несколько версий самых популярных библиотек доступными для автоматической загрузки в вашу систему сборки, и молча поощряя эту традицию «закрепления».
Но существуют и другие практики, например, в дистрибутиве Debian Linux теоретически возможно делегировать большую часть этой работы сопровождающим пакетов Debian. Вы просто наберете свой уровень комфорта в соответствии с 4 уровнями, которые предоставляет Debian, выбирая новизну вместо риска, или наоборот. Доступные Debian 4 уровня: OLDSTABLE, STABLE, TESTING, UNSTABLE. Unstable является удивительно стабильным, несмотря на свое название, и OLDSTABLE предлагает библиотеки, которые могут устареть на три года по сравнению с последними и лучшими версиями, доступными на их исходных веб-сайтах проекта «upstream».
Что касается 2-го вопроса, как защитить себя, я думаю, что текущая «лучшая практика» в отрасли двояка: выбирайте свои библиотеки на основе репутации (у Apache, как правило, неплохо), и немного подождите, прежде чем обновлять Не всегда спешите быть на последнем и величайшем. Возможно, выберите публичный выпуск библиотеки, который уже доступен через 3–6 месяцев, в надежде, что любые критические ошибки были устранены и исправлены с момента первоначального выпуска.
Вы можете пойти дальше, написав тесты JUnit, которые специально защищают поведение, на которое вы полагаетесь в своих зависимостях. Таким образом, когда вы отключите более новую версию библиотеки, ваш JUnit сразу же потерпит неудачу, предупреждая вас о проблеме. Но я не вижу много людей, делающих это, по моему опыту. И часто трудно понять точное поведение, на которое вы полагаетесь.
И, кстати, я Юлий, парень, ответственный за эту ошибку! Пожалуйста, примите мои извинения за эту проблему. Вот почему я думаю, что это произошло. Я буду говорить только за себя. Чтобы узнать, что думают другие члены команды apache commons-codec, вам нужно спросить их сами (например, ggregory, sebb).
Когда я работал над Base64 в версиях 1.4 и 1.5, я был очень сосредоточен на основной проблеме Base64, а именно на кодировании двоичных данных в младшем 127 ASCIi и декодировании их обратно в двоичный .
Так что, на мой взгляд (и здесь я ошибся), разница между "aGk = \ r \ n" и "aGk =" не имеет значения. Они оба декодируют с одинаковым двоичным результатом!
Но, подумав об этом в более широком смысле после прочтения вашей публикации в стеке, я понимаю, что, вероятно, существует очень популярный вариант использования, который я никогда не рассматривал. То есть проверка пароля по таблице зашифрованных паролей в базе данных. В этом случае вы, вероятно, делаете следующее:
// a. store user's password in the database
// using encryption and salt, and finally,
// commons-codec-1.4.jar (with "\r\n").
//
// b. every time the user logs in, encrypt their
// password using appropriate encryption alg., plus salt,
// finally base64 encode using latest version of commons-codec.jar,
// and then check against encrypted password in the database
// to see if it matches.
Так что, конечно, этот сценарий использования завершится неудачно, если commons-codec.jar изменит свое поведение кодирования даже несущественными способами в соответствии со спецификацией base64. Мне очень жаль!
Я думаю, что даже со всеми "лучшими практиками", которые я изложил в начале этого поста, все еще высока вероятность того, что он облажается.Тестирование Debian уже содержит commons-codec-1.5, версию с ошибкой, и исправить эту ошибку, по сути, означает, что нужно поиметь людей, которые использовали версию 1.5 вместо версии 1.4, где вы это сделали.Но я постараюсь разместить некоторую документацию на веб-сайте apache, чтобы предупредить людей.Спасибо за упоминание этого здесь о переполнении стека (я прав насчет варианта использования?).
ps.Я думал, что решение Пола Грайма было довольно изящным, но я подозреваю, что оно основано на том, что проекты помещают информацию о версии в файл META-INF/MANIFEST.MF
Jar.Я думаю, что все библиотеки Apache Java делают это, но другие проекты не могут.Этот подход - хороший способ привязать себя к версиям во время сборки: вместо того, чтобы понять, что вы зависите от "\ r \ n", и написать JUnit, который защищает от этого, вы можете вместо этого написать гораздо более простой JUnit:assertTrue(desiredLibVersion.equals(actualLibVersion))
.
(Предполагается, что библиотеки времени выполнения не меняются по сравнению с библиотеками времени сборки!)