Maven: วิธีลบล้างการอ้างอิงที่เพิ่มโดยไลบรารี


116

นี่คือปัญหาทั่วไปของฉัน:

โครงการ P ของฉันขึ้นอยู่กับ A ซึ่งขึ้นอยู่กับ B ซึ่งขึ้นอยู่กับ C ซึ่งขึ้นอยู่กับเวอร์ชัน 1.0.1 ของ D

มีปัญหากับเวอร์ชัน 1.0.1 ของ D และฉันต้องการบังคับให้ใช้โมดูลอื่น ฉันไม่รู้ว่าจะประกาศสิ่งนี้อย่างไรใน POM ของโปรเจ็กต์ของฉันเนื่องจากฉันไม่ได้เพิ่มการพึ่งพา 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: tree "

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>

ขอบคุณล่วงหน้า.

คำตอบ:


101

เพียงระบุเวอร์ชันในปอมปัจจุบันของคุณ เวอร์ชันที่ระบุที่นี่จะแทนที่เวอร์ชันอื่น ๆ

การบังคับเวอร์ชัน
A จะได้รับเกียรติเสมอหากมีการประกาศใน POM ปัจจุบันด้วยเวอร์ชันเฉพาะอย่างไรก็ตามควรสังเกตว่าสิ่งนี้จะส่งผลกระทบต่อ poms downstream อื่น ๆ ด้วยหากขึ้นอยู่กับการใช้การอ้างอิงแบบสกรรมกริยา


แหล่งข้อมูล:


5
ยังไม่ชัดเจนว่าฉันจะระบุเวอร์ชันได้อย่างไรเนื่องจากฉันไม่ได้ประกาศการพึ่งพา D. นอกจากนี้ลิงก์แรกที่คุณให้มี "เอกสารนี้อธิบายข้อกำหนดที่เหลือสำหรับการจัดการการพึ่งพาที่ยังไม่ได้นำมาใช้สำหรับ Maven 2.0 โดยเฉพาะอย่างยิ่งในเรื่องการพึ่งพาสกรรมกริยา " ที่ด้านบน.
wishihadabettername

@wishihadabettername ตามที่กล่าวไว้ในเอกสารอื่น: "คุณสามารถเพิ่มการพึ่งพา D 2.0 ใน A อย่างชัดเจนเพื่อบังคับให้ใช้ D 2.0"
Colin Hebert

1
คุณทำซ้ำรายการ <dependency> ที่เหมือนกันในปอมของคุณเอง ในการอ้างอิงของคุณระบุ <version> ที่คุณต้องการ ซึ่งจะแทนที่เวอร์ชันใด ๆ ที่ใช้โดยการอ้างอิง "ที่ลึกกว่า"
Keith Tyler

27

หรือคุณสามารถยกเว้นการอ้างอิงที่คุณไม่ต้องการได้ STAX รวมอยู่ใน JDK 1.6 ดังนั้นหากคุณใช้ 1.6 คุณสามารถยกเว้นทั้งหมดได้

ตัวอย่างด้านล่างของฉันผิดเล็กน้อยสำหรับคุณ - คุณต้องการเพียงหนึ่งในสองการยกเว้น แต่ฉันไม่แน่ใจว่าอันไหน มีเวอร์ชันอื่น ๆ ของ Stax ที่ลอยอยู่ในตัวอย่างของฉันด้านล่างฉันกำลังนำเข้า A ซึ่งนำเข้า B ซึ่งนำเข้า C & D ซึ่งแต่ละตัว (ผ่านการอ้างอิงแบบ transitive มากขึ้น) นำเข้า 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
จำเป็นต้องทราบว่าสามารถใช้การพึ่งพาสกรรมกริยานี้ได้และการยกเว้นอาจทำให้บิวด์ล้มเหลวได้หากจำเป็น
Bernhard Colby

หากคุณกำลังใช้ JDK ที่ทันสมัย ​​(เช่น 1.6+) และคุณต้องการเวอร์ชันที่เก่ากว่ามากที่รวมอยู่ในการพึ่งพาแบบสกรรมกริยาคุณอาจจะพบปัญหาตัวโหลดคลาสรันไทม์ที่น่ากลัวทุกประเภท คำแนะนำของฉัน: ใช้คำแนะนำใน JDK หากคุณได้รับ "ความล้มเหลวในการสร้าง" แสดงว่าคุณต้องใช้ API โบราณของรูปแบบบางอย่างที่ควรอัปเกรด หรือ: ย้อนกลับ JDK ของคุณเป็น 1.5 ขอให้โชคดี
scot

11

สิ่งที่คุณใส่ไว้ใน</dependencies>แท็กของ root pom จะรวมอยู่ในโมดูลลูกทั้งหมดของ root pom หากโมดูลทั้งหมดของคุณใช้การพึ่งพานั้นนี่คือหนทางที่จะไป

อย่างไรก็ตามหากมีเพียง 3 ใน 10 โมดูลลูกของคุณเท่านั้นที่ใช้การพึ่งพาบางส่วนคุณไม่ต้องการให้การอ้างอิงนี้รวมอยู่ในโมดูลลูกทั้งหมดของคุณ ในกรณีนั้นคุณสามารถใส่การอ้างอิงภายในไฟล์</dependencyManagement>. สิ่งนี้จะทำให้แน่ใจว่าโมดูลลูกใด ๆ ที่ต้องการการอ้างอิงต้องประกาศในไฟล์ pom ของตนเอง แต่จะใช้การอ้างอิงนั้นในเวอร์ชันเดียวกันตามที่ระบุไว้ใน</dependencyManagement>แท็กของคุณ

นอกจากนี้คุณยังสามารถใช้</dependencyManagement>เพื่อแก้ไขเวอร์ชันที่ใช้ในการอ้างอิงแบบทรานซิทีฟเนื่องจากเวอร์ชันที่ประกาศในไฟล์ pom ส่วนใหญ่เป็นเวอร์ชันที่จะใช้ สิ่งนี้จะมีประโยชน์ถ้าโครงการ 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

ฉันยังมีปัญหาในการแก้ไขการอ้างอิงในไลบรารีของบุคคลที่สาม ฉันใช้วิธีการของ scot กับการยกเว้น แต่ฉันยังเพิ่มการพึ่งพาด้วยเวอร์ชันที่ใหม่กว่าใน pom (ฉันใช้ 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 (เนื่องจากการพึ่งพา logback 1.2.3 ที่รวมอยู่แล้ว)

ปัญหา:โครงการ A ไม่พบฟังก์ชันที่มีอยู่ใน slf4j 1.7.5 หลังจากตรวจสอบแท็บลำดับชั้นการพึ่งพาของ eclipe ฉันพบว่าในระหว่างการสร้างนั้นใช้ slf4j 1.6.1 จากโครงการ B แทนที่จะใช้ slf4j 1.7.5 ของ logback .

ฉันแก้ไขปัญหาโดยการเปลี่ยนลำดับของการอ้างอิงบนโปรเจ็กต์ A pom เมื่อฉันย้ายรายการโปรเจ็กต์ B ด้านล่างรายการบันทึกกลับจากนั้น maven เริ่มสร้างโปรเจ็กต์โดยใช้ slf4j 1.7.5

แก้ไข: การ เพิ่มการพึ่งพา slf4j 1.7.5 ก่อนการพึ่งพาโครงการ B ก็ใช้ได้เช่นกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.