Вы должны предоставить зависимые библиотеки в клиентском фляге?
Мы предоставляем клиентский jar для других внутренних приложений для подключения к REST API нашего приложения. Наш API зависит от нескольких стандартных библиотек Джакарты. Рекомендуется ли включать эти JAR-файлы в наш клиентский JAR-файл? Или вы просто документируете зависимости, и клиенты сами должны убедиться, что у них есть эти файлы в их пути к классам?
5 ответов
Вы не должны связывать любые сторонние jar-файлы в свой jar-файл как uber jar, но было бы хорошо включить копию всех jar-файлов, которые требуются в вашем дистрибутиве, например, в каталог lib или что-либо еще.
Основная причина этого заключается в том, что ваши клиенты могут использовать какую-то форму системы управления зависимостями (maven / ivy и т. Д.), А предоставление пакетов и классов, которые на самом деле не принадлежат вашему проекту, лишит законной силы эти схемы.
Существует одна альтернатива - использовать плагин maven shade для перемещения ваших зависимостей в пространство имен вашего пакета. Это, конечно, имеет недостаток, заключающийся в том, что вы увеличите размер кода своей библиотеки, но, с другой стороны, вы можете почти гарантировать версии своих зависимостей, не влияя на любые другие библиотеки, которые могут использовать ваши клиенты.
РЕДАКТИРОВАТЬ: в ответ на комментарий Маркуса Леона:
Возможные решения без комплектации / перемещения:
- Документация, убедитесь, что вы документируете свои зависимости и любые известные конфликты с предыдущими версиями - на самом деле никто не читает
- Распространяйте свою библиотеку через управляемую систему зависимостей... как репозиторий maven или ivy, они позволяют вам задокументировать очень специфический набор (включая верхний), каковы ваши зависимости - все еще могут быть переопределены, только ваши клиенты будут знать, что они делаем это
- Добавить информацию OSGi в MANIFEST.MF - полезно только если ваши клиенты действительно используют OSGi
- Если ваши зависимости были построены с использованием maven или в файлах манифеста есть информация о версии, вы можете написать какую-то процедуру проверки, которая сканирует путь к классам для них и проверяет там версии - немного экстремально
В конце концов, чрезвычайно трудно убедиться, что у вас есть зависимости, которые вы хотите, поскольку java - язык с поздним связыванием, возможно, что ваши зависимости (даже если они связаны) будут переопределены кем-то, включая другую версию, перед вашей на пути к классам.
Примечание. Недавно я провел очень плохой день, пытаясь выяснить, почему одному из наших приложений не удалось найти новую версию log4j. причина: кто-то пытался быть полезным, сложил его в случайную, совершенно не связанную банку.
Вы должны включить любые банки, от которых вы зависите. Если вы разрешаете клиенту предоставлять стандартные файлы jar, вы полагаетесь на них, чтобы предоставить правильную версию. Для вас обоих будет гораздо более безболезненно, если вы включите версии, с которыми работает ваше приложение.
Преимущества упаковки в одну банку:
- простота для клиента
Минусы комплектации:
- невозможность обновления версий зависимых библиотек
- сокрытие необходимых библиотек может фактически привести к потенциальным конфликтам в клиенте с этими дополнительными библиотеками
- сложность для вас в процессе сборки (но способы сделать это довольно легко в Ant/Maven)
- некоторые библиотеки с манифестами не могут быть просто разобраны и перезаписаны - вам нужно объединить информацию манифеста. Хотя Ant и Maven поддерживают это.
Другой вариант - использовать один основной jar (ваш код) с атрибутом манифеста class-path, установленным для всасывания других jar. Лично мне это не нравится, так как эти полупрозрачные зависимости действительно легко пропустить.
В конце концов, если вы говорите только об одной или двух банках, я бы оставил их разделенными. Если вы говорите 10 или 15, вы можете рассмотреть возможность комплектации.
Вы должны включить эти банки, если вы развертываете приложение как отдельное приложение. Если вы развертываете исходный код для сборки, и вы предоставляете файл maven pom, то вам не обязательно это нужно.
Вы выражаете нервозность по поводу очень специфических зависимостей версий библиотеки (и я могу понять, что, учитывая, насколько тесно, скажем, Hibernate находится между различными модулями - только некоторые версии Hibernate-аннотаций работают с одним ядром hibernate, который, в свою очередь, в свою очередь, должен использоваться с определенным hibernate-валидатором).
Если вы знаете, что пакет должен работать как часть гораздо более крупной платформы (скажем, как плагин к платформе, которая может загружать свои собственные jar-файлы), вам действительно нужна более мощная мульти-версия загрузки классов OSGI (она же JSR). -291): технология OSGI
С помощью среды с поддержкой OSGI, такой как Spring, Eclipse, Jonas или Glassfish, вы можете указать в файле XML ваши конкретные зависимости от версии, и если вы зависите от пакета libfoo-1.1.4, тогда как другой плагин зависит от libfoo-2.0 а, менеджер зависимостей OSGI обеспечит загрузку каждой верной версии.