Управление зависимостями больших Java-систем

new Thread() {
        public void run() {
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                System.out.println("Exception message: " + e.getMessage());
                System.out.println("Exception cause: " + e.getCause());
            }
        }
    }.start();

Это также один из примеров анонимного внутреннего типа с использованием thread

30
задан Jim Garrison 21 September 2009 в 18:36
поделиться

8 ответов

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

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

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

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


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

Ненужные пакеты

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

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

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

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

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

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

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

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

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

11
ответ дан 28 November 2019 в 00:24
поделиться

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

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

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

5
ответ дан 28 November 2019 в 00:24
поделиться

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

4
ответ дан 28 November 2019 в 00:24
поделиться

«Это текущее положение дел?»

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

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

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

2
ответ дан 28 November 2019 в 00:24
поделиться

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

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

3
ответ дан 28 November 2019 в 00:24
поделиться

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

  • org.apache.derby: derby
  • org.apache.geronimo.specs: geronimo-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

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

5
ответ дан 28 November 2019 в 00:24
поделиться

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

0
ответ дан 28 November 2019 в 00:24
поделиться

«Это текущее положение дел?»

Да.

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

Фреймворк с закрытым исходным кодом (т.е. .Net) будет решить все это за вас.

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

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

Однако велика вероятность того, что никакая упакованная конфигурация не соответствует вашим требованиям.

-5
ответ дан 28 November 2019 в 00:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: