Как крупные компании решают проблему конфликта зависимостей пакетов? - PullRequest
0 голосов
/ 01 ноября 2018

enter image description here Как показано на рисунке, одно приложение (Java) ссылается на два сторонних jar-пакетов (packageA и packageB) и ссылается на packageC-0.1 и packageC-0.2 соответственно. Было бы хорошо работать, если packageC-0.2 был совместим с packageC-0.1. Однако иногда packageA использовал что-то, что не могло поддерживаться в packageC-0.2, а Maven может использовать только последнюю версию jar. Эта проблема также известна как «Jar Hell».

На практике было бы трудно переписать пакет А или заставить его разработчиков обновить пакет С до 0.2.

Как вы решаете эти проблемы? Это часто случается в крупных компаниях.

Я должен заявить, что эта проблема в основном возникает в БОЛЬШИХ компаниях из-за того, что у большой компании много отделов, и было бы очень дорого позволить всей компании обновлять одну зависимость каждый раз, когда определенные разработчики используют новые функции новая версия некоторых банок зависимостей. И это не страшно в небольших компаниях.

Любой ответ будет высоко оценен.

Позвольте мне выбросить кирпич, чтобы сначала получить драгоценный камень.

Alibaba является одним из крупнейших интернет-магазинов в мире. И мы решаем эти проблемы, создавая изолирующий контейнер с именем Pandora. Его принцип прост: упаковывать эти промежуточные продукты вместе и загружать их различными загрузчиками классов, чтобы они могли хорошо работать вместе, даже если они ссылались на одни и те же пакеты в разных версиях. Но для этого нужна среда выполнения, предоставляемая Pandora, которая работает как процесс tomcat. Я должен признать, что это тяжелый план. Pandora разработана на основе того факта, что JVM идентифицирует один класс по загрузчику классов и имени класса.

Если вы знаете, что кто-то, возможно, знает ответы, поделитесь ссылкой с ним / ней.

Ответы [ 6 ]

0 голосов
/ 02 ноября 2018

Позвольте мне выбросить кирпич, чтобы сначала получить драгоценный камень.

Alibaba является одним из крупнейших интернет-магазинов в мире. И мы решаем эти проблемы, создавая изолирующий контейнер с именем Pandora. Его принцип прост: упаковывать эти промежуточные продукты вместе и загружать их различными загрузчиками классов, чтобы они могли хорошо работать вместе, даже если они ссылались на одни и те же пакеты в разных версиях. Но для этого нужна среда выполнения, предоставляемая Pandora, которая работает как процесс tomcat. Я должен признать, что это тяжелый план.

Pandora разработана на основе того факта, что JVM идентифицирует один класс по загрузчику классов и имени класса.

0 голосов
/ 02 ноября 2018

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

Однако мы все используем библиотеки. И иногда мы сталкиваемся с проблемой, которую вы описываете, когда нам нужны две разные версии одной и той же библиотеки. Если библиотека «C» удалила и добавила несколько API-интерфейсов между двумя версиями, а удаленные API-интерфейсы нужны «A», а «B» нужны новые, у вас возникла проблема.

В моей компании мы запускаем наш Java-код внутри контейнера OSGi. Используя OSGi, вы можете модулировать свой код в «связки», которые являются файлами jar с некоторыми специальными директивами в их файле манифеста. Каждый пакет имеет свой собственный загрузчик классов, поэтому два пакета могут использовать разные версии одной и той же библиотеки. В вашем примере вы можете разделить код приложения, в котором используется «packageA», на один пакет, и код, который использует «packageB», в другой. Два пакета могут вызывать API-интерфейсы друг друга, и все будет работать нормально, если ваши пакеты не используют классы «packageC» в сигнатуре методов, используемых другим пакетом (известный как утечка API).

Чтобы начать работать с OSGi, вы можете, например, взгляните на OSGi enRoute .

0 голосов
/ 01 ноября 2018

Я согласен с ответом @JF Meier , В многомодульном проекте Maven узел управления зависимостями обычно определяется в родительском файле POM при выполнении унифицированного управления версиями. Содержание узла зависимостей, объявленного классом узла, относится к версии ресурса унифицированного определения. Ресурсы в узле напрямую определенных зависимостей не нужно вводить в фазу версии. Содержание таможни следующие:

в родительском поме

<dependencyManagement> 
    <dependencies > 
      <dependency > 
        <groupId>com.devzuz.mvnbook.proficio</groupId> 
        <artifactId>proficio-model</artifactId> 
        <version>${project.version}</version> 
      </dependency > 
    </dependencies > 
  </dependencyManagement>

в вашем модуле вам не нужно устанавливать версию

<dependencies > 
    <dependency > 
      <groupId>com.devzuz.mvnbook.proficio</groupId> 
       <artifactId>proficio-model</artifactId> 
    </dependency > 
  </dependencies > 

Это позволит избежать проблемы несоответствия.

0 голосов
/ 01 ноября 2018

Это распространенная проблема в мире Java.

Ваши лучшие варианты - регулярно поддерживать и обновлять зависимости для packageA и packageB.

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

Если как packageA, так и packageB используются для внутренних целей, вы можете использовать следующую практику: все внутренние проекты в вашей компании ссылаются на parent в maven pom.xml, который определяет «современные» версии часто используемых третьих партийные библиотеки.

Например:

    <framework.jersey>2.27</framework.jersey>
    <framework.spring>4.3.18.RELEASE</framework.spring>
    <framework.spring.security>4.2.7.RELEASE</framework.spring.security>

Поэтому, если ваш проект «A» использует spring, если они используют последнюю версию «родительского» pom вашей компании, они оба должны использовать 4.3.18.RELEASE.

Когда будет выпущена и желательна новая версия spring, вы обновите родительский pom своей компании и заставите все остальные проекты использовать эту последнюю версию.

Это решит многие из этих проблем несоответствия зависимостей.

Не волнуйтесь, это обычное явление в мире Java, вы не одиноки. Просто погуглите «jar hell», и вы поймете проблему в более широком контексте.

Кстати, mvn dependency:tree - ваш друг, который изолировал эти проблемы с зависимостями.

0 голосов
/ 01 ноября 2018

Мы большая компания, и у нас есть эта проблема много . У нас есть большие деревья зависимостей, которые объединяют несколько групп разработчиков. Что мы делаем:

  • Мы управляем версиями спецификаций (списками Maven dependencyManagement) «рекомендуемых версий», которые публикуются сопровождающими jar-файлов. Таким образом, мы гарантируем, что используются последние версии артефактов.

  • Мы пытаемся уменьшить большие деревья зависимостей, отделяя функциональность, которая используется внутри группы разработчиков, от функциональности, которую они предлагают другим группам.

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

0 голосов
/ 01 ноября 2018

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

Но чтобы ответить на ваш вопрос .. Простой ответ: не используйте две версии одной зависимости в одном модуле компиляции (обычно это модуль)

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

Но мое личное мнение таково, что в одном модуле не должно быть необходимости в этих конструкциях, потому что «один модуль» должен быть относительно небольшим, чтобы им можно было управлять. В противном случае это может быть сильным показателем того, что проект может использовать некоторый рефакторинг модульности. Тем не менее, я очень хорошо знаю, что некоторые проекты «крупных компаний» могут привести к большим беспорядкам, когда «хороший» вариант недоступен. Я предполагаю, что вы говорите о ситуации, когда packageA принадлежит другой команде, а не packageB ... и это, как правило, очень плохое проектное решение из-за отсутствия разделения и врожденных проблем с зависимостями.

...