Maven: як перемогти залежність, яку додає бібліотека


116

Ось моя загальна проблема:

Мій проект P залежить від A, який залежить від B, який залежить від C, який залежить від версії 1.0.1 D.

Існує проблема з версією 1.0.1 D, і я хочу змусити використовувати інший модуль. Я не знаю, як заявити про це в програмах мого проекту, оскільки я не додав залежності від D безпосередньо. Це C, що оголосив залежність від D.

Важливо: У цьому випадку змінюється не тільки версія, але й група та артефакт. Тож справа не лише у відміні версії залежності, а, скоріше, у виключенні модуля та включенні іншого.

У конкретному випадку D - це StAX, у 1.0.1 якого є помилка . Відповідно до примітки про помилку, "проблеми були вирішені заміною stax-api-1.0.1 (maven GroupId = stax) на stax-api-1.0-2 (maven GroupId = javax.xml.stream)", так що я я намагаюся саме це.

Таким чином, D = stax: stax-api: jar: 1.0.1 і C = org.apache.xmlbeans: xmlbeans: jar: 2.3.0

Я використовую maven 2.0.9 на випадок, коли це має значення.

Вихід залежності від mvn: дерево "

mvn dependency:tree
[..snip..]
[INFO] +- org.apache.poi:poi-ooxml:jar:3.6:compile
[INFO] |  +- org.apache.poi:poi-ooxml-schemas:jar:3.6:compile
[INFO] |  |  +- org.apache.xmlbeans:xmlbeans:jar:2.3.0:compile
[INFO] |  |  |  \- stax:stax-api:jar:1.0.1:compile

У моєму проекті POM у мене є така залежність від "A":

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.6</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.6</version>
</dependency>

Заздалегідь спасибі.

Відповіді:


100

Просто вкажіть версію в поточній пам’яті. Вказана тут версія перевершить інші.

Форсування версії
Версія завжди буде шануватися, якщо вона буде оголошена в поточній POM з певною версією, однак, слід зазначити, що це вплине і на інших Poms нижче за течією, якщо вона сама залежатиме від використання перехідних залежностей.


Ресурси:


5
незрозуміло, як я можу вказати версію, оскільки я не декларую залежність від D. Крім того, перше надаване вами посилання містить "Цей документ описує решту вимог до управління залежностями, які ще не впроваджені для Maven 2.0, особливо щодо перехідних залежностей ". на вершині.
wishihadabettername

@ wishihadabettername, Як сказано в іншому документі: "Ви можете явно додати залежність до D 2.0 в A, щоб змусити використовувати D 2.0"
Колін Геберт

1
Ви насправді дублюєте той самий запис <dependence> у власній пам’яті. У залежності від вас вкажіть потрібний <перехід>. Це скасує будь-яку версію, яку використовують "глибші" залежності.
Кіт Тайлер

27

Крім того, ви можете просто виключити залежність, якої ви не хочете. STAX включений у JDK 1.6, тому якщо ви використовуєте 1.6, ви можете просто виключити його.

Мій приклад нижче для вас трохи неправильний - вам потрібно лише одне з двох виключень, але я не зовсім впевнений, який з них. Існують і інші версії Stax, що плавають, в моєму прикладі нижче я імпортував A, який імпортував B, імпортував C&D, кожен з яких (через ще більш транзитивні залежності) імпортував різні версії Stax. Тож у моїй залежності від "A" я виключив обидві версії Stax.

<dependency>
  <groupId>a.group</groupId>
  <artifactId>a.artifact</artifactId>
  <version>a.version</version>
  <exclusions>
    <!--  STAX comes with Java 1.6 -->
    <exclusion>
      <artifactId>stax-api</artifactId>
      <groupId>javax.xml.stream</groupId>
    </exclusion>
    <exclusion>
      <artifactId>stax-api</artifactId>
      <groupId>stax</groupId>
    </exclusion>
  </exclusions>
<dependency>

1
Необхідно зазначити, що цю перехідну залежність можна використовувати, і виключення може спричинити збій у побудові, якщо вона потребує.
Бернхард Колбі

Якщо ви використовуєте сучасний JDK (тобто 1.6+) і вам потрібна значно старша версія stax, включена через перехідну залежність, ви, ймовірно, зіткнетеся з усілякими жахливими проблемами завантажувача класу виконання. Моя порада: використовуйте цю в JDK. Якщо ви отримали "збій у збірці", ви покладаєтесь на стародавній API певної форми, який слід оновити. Або: поверніть JDK до 1.5. Удачі з цим.
шотландський

11

Те, що ви помістите всередину </dependencies>тегу кореневої пом, буде включено до всіх дочірніх модулів кореневої пом. Якщо всі ваші модулі використовують цю залежність, це шлях.

Однак якщо лише 3 з 10 модулів вашої дитини використовують певну залежність, ви не хочете, щоб ця залежність була включена у всі ваші дочірні модулі. У такому випадку ви можете просто поставити залежність всередині </dependencyManagement>. Це переконається, що будь-який дочірній модуль, якому потрібна залежність, повинен оголосити його у власному файлі pom, але вони використовуватимуть ту саму версію цієї залежності, що вказана у вашому </dependencyManagement>тезі.

Ви також можете скористатись </dependencyManagement>для зміни версії, що використовується у перехідних залежностях, оскільки версія, оголошена у верхньому найпомітнішому файлі, є тією, яка буде використовуватися. Це може бути корисно, якщо ваш проект A включає зовнішній проект B v1.0, який включає інший зовнішній проект C v1.0. Іноді трапляється, що порушення проекту виявляється в проекті C v1.0, який виправлено в v1.1, але розробники B повільно оновлюють свій проект, щоб використовувати v1.1 C. В такому випадку ви можете просто заявити залежність від C v1.1 в кореневій пам’яті вашого проекту всередині `, і все буде добре (якщо припустити, що B v1.0 все ще зможе компілювати з C v1.1).


10

У мене також виникли проблеми з перевищенням залежності в бібліотеці третьої сторони. Я використовував підхід Скота з виключенням, але я також додав залежність з новою версією в пом. (Я використовував Maven 3.3.3)

Так для прикладу stAX це виглядатиме так:

<dependency>
  <groupId>a.group</groupId>
  <artifactId>a.artifact</artifactId>
  <version>a.version</version>
  <exclusions>
    <!--  STAX comes with Java 1.6 -->
    <exclusion>
      <artifactId>stax-api</artifactId>
      <groupId>javax.xml.stream</groupId>
    </exclusion>
    <exclusion>
      <artifactId>stax-api</artifactId>
      <groupId>stax</groupId>
    </exclusion>
  </exclusions>
<dependency>

<dependency>
    <groupId>javax.xml.stream</groupId>
    <artifactId>stax-api</artifactId>
    <version>1.0-2</version>
</dependency>

1

Прийнята відповідь правильна, але я хотів би додати свої два центи. Я зіткнувся з проблемою, коли у мене був проект A, який мав проект B як залежність. Обидва проекти використовують slf4j, але проект B використовує log4j, тоді як проект A використовує зворотний зв'язок. Проект B використовує slf4j 1.6.1, тоді як проект A використовує slf4j 1.7.5 (через вже включену залежність від 1.2.3).

Проблема: Проект A не зміг знайти функцію, яка існує на slf4j 1.7.5, після перевірки вкладки ієрархії залежності eclipe я виявив, що під час складання він використовував slf4j 1.6.1 з проекту B, замість того, щоб використовувати slf4j 1.7.5 журналу .

Я вирішив цю проблему, змінивши порядок залежностей від проекту A pom, коли я перемістив запис проекту B під запис входу, тоді Maven почав будувати проект, використовуючи slf4j 1.7.5.

Редагувати: Додавання залежності slf4j 1.7.5 до того, як також працювала залежність проекту B.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.