Подтвердить что ты не робот

Большое управление зависимостями системы Java

У нас есть большая ( > 500 000 LOC) Java-система, которая зависит от 40-50 OSS пакеты. Система построена с помощью Ant, а управление зависимостями - обрабатываются вручную в настоящее время. Я изучаю Айви и/или Maven для автоматизировать зависимости. Мы рассмотрели Maven как автоматизацию построения системы в прошлом году и отклонил его, потому что это потребовало бы полностью реструктурируя нашу систему в соответствии с архитектурой Maven. Теперь я чтобы автоматизировать только задачи управления зависимостями.

Я провел несколько экспериментов с Ivy, но столкнулся с проблемами. Например, когда я указываю ActiveMQ как зависимость и скажу Ivy использовать POM в репозитории Maven для спецификации зависимостей, Ivy извлекает кучу пакетов (Jetty, Derby и Geronimo для экземпляр), которые, как мне известно, не нужны, просто используйте ActiveMQ.

Если я устанавливаю usepoms = "false" в файле ivysettings.xml, он выбирает только activemq.jar, но это, кажется, побеждает цель Айви и переносит его на простой кувшинщик с зависимой от вручную зависимостью технические характеристики.

Там больше проблема, что раньше называлось "DLL Hell" в Окна. В некоторых случаях две прямые зависимости первого уровня будут указывают на разные версии одной и той же транзитивной зависимости (для экземпляр log4j.jar). Только один log4j.jar может быть в пути к классам, поэтому разрешение зависимостей включает в себя ручное определение, какая версия совместимый со всеми своими клиентами в нашей системе.

Я думаю, все это сводится к качеству каждой зависимости пакета спецификации (POM). В случае ActiveMQ нет области декларации, поэтому любая ссылка на ActiveMQ будет загружать все ее за исключением случаев, когда мы вручную исключаем те, которые, как мы знаем, не хотите.

В случае log4j требуется автоматическое разрешение зависимостей что все клиенты log4j (другие пакеты, зависящие от log4j) утвердить все предыдущие версии log4j и предоставить диапазон (или список) совместимых версий log4j в POM. Возможно, это тоже много спросить.

Это текущее состояние дел, или я чего-то не хватает?

4b9b3361

Ответ 1

Вы абсолютно правы, говоря, что

Я думаю, все это сводится к качеству каждой спецификации зависимости пакета (POM).

Единственное, что я хотел бы добавить, - это просмотреть POM или любую другую форму метаданных в качестве отправной точки. Это весьма полезно, например, ActiveMQ предоставляет все зависимости для вас, но вам решать, действительно ли это соответствует вашему проекту.

В конце концов, даже принимая во внимание версию log4j, у вас есть внешние зависимости, выберите версию или выберите версию, которую вы знаете, для вас?


Что касается того, как вы можете выбирать зависимости от зависимостей, вот что вы можете сделать с Айви:

Необработанные пакеты

Ivy извлекает кучу пакетов (например, Jetty, Derby и Geronimo), которые, как мне известно, не нужны, просто используйте ActiveMQ.

Это обычно происходит из-за плохой модульности в приложении. Некоторым частям приложения требуется, например, Jetty, но вы получаете эту транзитивную зависимость, даже если вы ее не используете.

Вероятно, вы захотите изучить механизм ivy exclude:

<dependency name="A" rev="1.0">
  <exclude module="B"/>
</dependency>

версии зависимостей

В пути к классам может быть только один log4j.jar, поэтому разрешение зависимостей включает в себя ручное определение, какая версия совместима со всеми своими клиентами в нашей системе.

Возможно, я неправильно понимаю это, но в решении проблемы с плюсом нет ручного элемента. Список менеджеров конфликтов по умолчанию:

  • all: этот менеджер конфликтов разрешает конфликты, выбирая все изменения. Также называется NoConflictManager, он вытесняет любой модуль.
  • новейший: этот менеджер конфликтов выбирает только "последнюю" версию, последняя из которых определяется как самая последняя. Обратите внимание, что самые последние во времени дорогостоящие вычисления, поэтому предпочитайте последнюю версию, если сможете.
  • последняя версия: этот менеджер конфликтов выбирает только последнюю версию, последнюю из которых определяется строковым сравнением версий.
  • новейшая совместимая: этот менеджер конфликтов выбирает последнюю версию в конфликтах, которая может привести к совместимому набору зависимостей. Это означает, что в конечном итоге этот менеджер конфликтов не разрешает конфликтов (например, строгий менеджер конфликтов), за исключением того, что он следует стратегии лучших усилий, чтобы попытаться найти набор совместимых модулей (в соответствии с ограничениями версии);
  • strict: этот конфликтный менеджер выдает исключение (т.е. вызывает сбой сборки) всякий раз, когда обнаружен конфликт.

При необходимости вы можете предоставить свой собственный менеджер конфликтов.

Ответ 2

Это в значительной степени. Система зависимостей maven (которая более или менее соответствует Ivy) оставляет за собой отдельные проекты, чтобы сделать хорошую работу по добавлению необходимых метаданных для их зависимостей. Большинство нет.

Если вы идете по этому маршруту, рассчитывайте потратить время на настройку исключений.

К плакатам, рекомендующим OSGi, OP сказал, что он не желает перепроектировать свою систему сборки для Maven, я бы не подумал, что он захочет перестроить свое приложение как совместимое с OSGi. Кроме того, многие проекты OSS, совместимые с OSGi (и их не так много, как вы надеялись), имеют как плохие, так и худшие метаданные, чем в Maven

Ответ 3

Из списков зависимостей, перечисленных ниже, optional в папке activemq-core (также см. соответствующий раздел из книги Maven).

  • org.apache.derby: котелок
  • org.apache.geronimo.specs: Джеронимо-jta_1.0.1B_spec

Я не видел прямой зависимости от Jetty, поэтому он может быть транзитно включен из одной из необязательных зависимостей.

В Maven необязательные зависимости обрабатываются автоматически. По существу, любая зависимая, которая объявляется необязательной, должна быть обновлена ​​в вашем pom для ее использования. Из приведенной выше документации:

Необязательные зависимости используются, когда это невозможно (по какой-либо причине) разбить проект на подмодули. Идея состоит в том, что некоторые из зависимостей используются только для определенных функций в проекте и не понадобятся, если эта функция не используется. В идеале такая функция будет разделена на подмодуль, зависящий от основного функционального проекта... этот новый подпроект будет иметь только необязательные зависимости, так как они вам понадобятся, если вы решили использовать подпроект.

Однако, поскольку проект нельзя разделить (опять же, по какой-либо причине), эти зависимости объявляются необязательными. Если пользователь хочет использовать функциональные возможности, связанные с дополнительной зависимостью, им придется обновлять эту необязательную зависимость в своем собственном проекте. Это не самый ясный способ справиться с этой ситуацией, но опять же, как необязательные зависимости, так и исключения зависимостей являются решениями стоп-зазора.

Я не уверен, что вы можете настроить Ivy на игнорирование необязательных зависимостей, но вы можете настроить его на исключить зависимости. Например:

<dependency name="A" rev="1.0">
  <exclude module="B"/>
</dependency>

Это не совсем удовлетворительно, я знаю. Возможно, что Ivy поддерживает необязательные зависимости (я буду искать и обновлять, если найду что-нибудь), но механизм исключений, по крайней мере, позволяет вам управлять ими.


Относительно последней части вашего вопроса. Maven разрешит версии зависимостей для log4j, и если версии совместимы, он автоматически выберет "ближайший" из перечисленных версий.

Из Введение в механизм зависимостей:

  • Согласование зависимостей - это определяет, какая версия зависимости будет использоваться, когда встречаются несколько версий артефакта. В настоящее время Maven 2.0 поддерживает только "ближайшее определение", что означает, что он будет использовать версию ближайшей зависимости от вашего проекта в дереве зависимостей. Вы всегда можете гарантировать версию, объявив ее явно в своем проекте POM. Обратите внимание: если две версии зависимостей находятся на одной и той же глубине в дереве зависимостей, пока Maven 2.0.8 не будет определен, какой из них будет побежден, но поскольку Maven 2.0.9 это порядок в объявлении, который считается: первое объявление выигрывает.

    • "ближайшее определение" означает, что используемая версия будет самой близкой к вашему проекту в дереве зависимостей, например. если зависимости для A, B и C определены как A → B → C → D 2.0 и A → E → D 1.0, тогда D 1.0 будет использоваться при построении A, поскольку путь от A до D через E короче. Вы можете явно добавить зависимость от D 2.0 в A, чтобы принудительно использовать D 2.0

Если версии несовместимы, у вас есть большая проблема, чем разрешение зависимостей. Я считаю, что Айви работает на аналогичной модели, но я не эксперт.

Ответ 4

Я думаю, что это действительно текущее положение дел. OSGi и предлагаемая новая система упаковки для java 1.7 (есть обсуждение того, что вы уже пришли к выводу?) - попытки зафиксировать на по крайней мере, в зависимости от различий в версии для библиотеки, но я не думаю, что они смогут исправить вашу проблему прямо сейчас.

Ответ 5

В настоящее время я использую Ivy для управления более чем 120 OSS и проприетарными библиотеками для нескольких проектов (некоторые автономные, некоторые иждивенцы). Еще в 2005 году (когда Айви все еще была из Jayasoft) я решил (или должен был) написать файлы ivy.xml для каждого интегрированного пакета.

Самое большое преимущество в том, что я полностью контролирую различные конфигурации. Это может показаться излишним для некоторых, но наша система сборки надежно работает уже более 4 лет, а добавление новой библиотеки обычно составляет 5 минут.

Ответ 6

"Это текущее состояние дел?"

Не с OSGi. Вы можете посмотреть контейнеры и пакеты OSGi. Пакет подобен файлу jar, но он поддерживает метаданные, детализирующие его версию, и версии связанных пакетов, которые он требует (путем размещения атрибутов в файле META-INF). Таким образом, ваш логарифм log4j будет указывать его версию, а зависимые пакеты будут подробно описывать, какие версии log4j они требуют.

Кроме того, поддерживается неиерархический механизм загрузчика классов, так что вы можете загружать несколько версий log4j, а разные узлы могут указывать и связывать эти разные версии.

Javaworld имеет очень хорошее представление здесь.

Ответ 7

Существует вся идея инъекции зависимостей, что неизменно приводит к необходимости реструктуризации программы. Я слышал некоторый шум о том, что GUICE хорош в этом отношении. В перспективе развертывания я имел разумный успех при развертывании только .jar, который мы построили с использованием зависимостей .jars, которые извлекаются из исходных проектов через jnlp. Система сборки позади этого включала ручное отслеживание новых версий зависимостей и обновление в системе сборки.

Ответ 8

"Это текущее состояние дел"

Да.

Это компромисс с открытым исходным кодом.

Структура с закрытым исходным кодом (т.е..Net) решит все это для вас.

Решение с открытым исходным кодом означает, что вам нужно постоянно его решать (и разрешать).

Возможно, вам удастся найти некоторые предварительно сконфигурированные конфигурации и заплатить кому-то, чтобы они были в курсе последних событий. Например, вы можете выбрать Red Hat Enterprise Linux. Если вы придерживаетесь того, что они поддерживают (и не более того), то конфигурация будет решена.

Коэффициенты хорошие, однако, что никакая упакованная конфигурация не отвечает вашим требованиям.