Maven: เพิ่มการอ้างอิงไปยัง jar โดยพา ธ ที่สัมพันธ์กัน


232

ฉันมีโถที่เป็นกรรมสิทธิ์ที่ฉันต้องการเพิ่มลงใน Pom ของฉันเป็นการพึ่งพา

แต่ฉันไม่ต้องการเพิ่มลงในที่เก็บ เหตุผลคือฉันต้องการคำสั่ง maven ตามปกติของฉันเช่นmvn compileฯลฯ เพื่อทำงานนอกกรอบ (โดยไม่ต้องเรียกร้องจากนักพัฒนา a เพื่อเพิ่มไปยังที่เก็บข้อมูลด้วยตนเอง)

ฉันต้องการให้ขวดอยู่ใน lib ของบุคคลที่สามในการควบคุมแหล่งที่มาและเชื่อมโยงไปยังมันโดยเส้นทางสัมพัทธ์จากไฟล์ pom.xml

สามารถทำได้หรือไม่ อย่างไร?

คำตอบ:


343

ฉันต้องการให้ขวดอยู่ใน lib ของบุคคลที่สามในการควบคุมแหล่งที่มาและเชื่อมโยงไปยังมันโดยเส้นทางสัมพัทธ์จากไฟล์ pom.xml

หากคุณต้องการสิ่งนี้จริงๆ (เข้าใจถ้าคุณไม่สามารถใช้ที่เก็บข้อมูลขององค์กร) คำแนะนำของฉันคือการใช้ "ที่เก็บไฟล์" ในเครื่องของโครงการและไม่ใช้การsystemพึ่งพาขอบเขต systemควรหลีกเลี่ยงการกำหนดขอบเขตการพึ่งพาดังกล่าวทำงานได้ไม่ดีในหลาย ๆ สถานการณ์ (เช่นในชุดประกอบ) ทำให้เกิดปัญหามากกว่าผลประโยชน์

ดังนั้นให้ประกาศที่เก็บโลคัลให้กับโปรเจ็กต์แทน:

<repositories>
  <repository>
    <id>my-local-repo</id>
    <url>file://${project.basedir}/my-repo</url>
  </repository>
</repositories>

ติดตั้ง lib บุคคลที่สามของคุณโดยใช้install:install-fileกับlocalRepositoryPathพารามิเตอร์:

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<myGroup> \ 
                         -DartifactId=<myArtifactId> -Dversion=<myVersion> \
                         -Dpackaging=<myPackaging> -DlocalRepositoryPath=<path>

อัปเดต:ดูเหมือนว่าinstall:install-fileจะไม่สนใจlocalRepositoryPathเมื่อใช้ปลั๊กอินเวอร์ชัน 2.2 อย่างไรก็ตามมันใช้งานได้กับเวอร์ชั่น 2.3 และใหม่กว่าของปลั๊กอิน ดังนั้นใช้ชื่อเต็มของปลั๊กอินเพื่อระบุรุ่น:

mvn org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file \
                         -Dfile=<path-to-file> -DgroupId=<myGroup> \ 
                         -DartifactId=<myArtifactId> -Dversion=<myVersion> \
                         -Dpackaging=<myPackaging> -DlocalRepositoryPath=<path>

maven-install-plugin เอกสาร

ในที่สุดประกาศว่ามันเหมือนการพึ่งพาอื่น ๆ (แต่ไม่มีsystemขอบเขต):

<dependency>
  <groupId>your.group.id</groupId>
  <artifactId>3rdparty</artifactId>
  <version>X.Y.Z</version>
</dependency>

นี่คือ IMHO ทางออกที่ดีกว่าการใช้systemขอบเขตเนื่องจากการพึ่งพาของคุณจะได้รับการปฏิบัติเหมือนพลเมืองดี (เช่นจะรวมอยู่ในการประชุมและอื่น ๆ )

ตอนนี้ฉันต้องพูดถึงว่า "วิธีที่ถูกต้อง" เพื่อจัดการกับสถานการณ์นี้ในสภาพแวดล้อมขององค์กร (อาจไม่ใช่กรณีที่นี่) จะใช้พื้นที่เก็บข้อมูลขององค์กร


2
นี่เป็นความคิดที่ดี แต่ใน Maven 2.2.1 ดูเหมือนว่าปลั๊กอินการติดตั้งจะไม่สนใจlocalRepositoryPath...
Jake

1
ทำไมถึงต้องซื้อ repo ในพื้นที่ ทำไมไม่ปล่อยให้มันเข้าไปใน ~ / .m2 / กับที่เหลือ
Leif Gruenwoldt

6
@ leif81 เพราะจากนั้น repo และไลบรารีจะถูกตรวจสอบในที่เก็บ SCM -> ทุกคนที่ทำการชำระเงินต้นทางมีทุกสิ่งที่พวกเขาต้องการในการสร้างสำเนาของไลบรารี / แอปพลิเคชัน
Darth Android

6
ฉันมีปัญหาเช่นเดียวกับ @lemon ซึ่งฉันแก้ไขด้วยการbasedir/./my-local-repoใช้ซิงเกิ้ล.แทน
Brian

2
บรรจุภัณฑ์จะต้องเป็นขวดดังนั้น
Danila Piatov

127

การใช้systemขอบเขต ${basedir}เป็นไดเรกทอรีของ pom ของคุณ

<dependency>
    <artifactId>..</artifactId>
    <groupId>..</groupId>
    <scope>system</scope>
    <systemPath>${basedir}/lib/dependency.jar</systemPath>
</dependency>

อย่างไรก็ตามขอแนะนำให้คุณติดตั้ง jar ของคุณในที่เก็บและอย่าส่งมอบให้กับ SCM - หลังจากทั้งหมดนั่นคือสิ่งที่ maven พยายามกำจัด


15
ระบบขอบเขตจะต้องหลีกเลี่ยงทุกที่ที่เป็นไปได้ ติดตั้ง JAR ในที่เก็บเป็นทางออกที่ดีกว่า ...
Gandalf StormCrow

14
ใช่ถ้าเป็นไปได้ เขาพูดอย่างชัดเจนว่าเขาไม่ต้องการใส่ไว้ในที่เก็บ ฉันเพิ่มความคิดเห็นเพื่อชี้ให้เห็นว่านี่ไม่ใช่วิธีปฏิบัติที่ดี แต่มันได้ผล
Bozho

Groovy วิธีการแก้ปัญหาของคุณเป็นที่ยอมรับมากที่สุดจนถึงตอนนี้ฉันเดาว่า .. ฉันอ่านคำถามผิดไปหมดแล้ว
มด

ใช่ - คำถามนั้นไม่รวมคำตอบที่ดีที่สุด การวางทุกสิ่งในเซิร์ฟเวอร์ตัวควบคุมแหล่งเดียวของคุณนั้นมีส่วนเกี่ยวข้องกับ "การสร้างนอกกรอบ" เพียงเล็กน้อย ค่อนข้างทุกอย่างจะต้องมี "ควบคุม" ทำการเช็คอิน pom's & settings.xml (ชี้ไปที่repo ภายใน ) และใช้เซิร์ฟเวอร์สองเครื่องสำหรับโครงการของคุณ: (1) การควบคุมแหล่ง (2) การควบคุมสิ่งประดิษฐ์ที่สร้างขึ้น มันทำให้การตรวจสอบในไหมากเท่าที่จะตรวจสอบใน dll ของ (corp เก่าของฉันจริง ๆ แล้วไม่ได้เช็คอินไห & lib.a / .so / .dll ของเซิร์ฟเวอร์ p4 ของเราช้ามากหลังจากนั้นบางคนแอบใช้ hg สำหรับวัน ทำงานประจำวันแก้ไขปัญหาได้ไหม
ไมเคิล

วิธีใดที่จะระบุไดเรกทอรีที่มี jars แทนดังนั้นเราไม่จำเป็นต้องเพิ่มแต่ละอันที่ gradle สามารถทำได้?
Dean Hiller

29

นี่เป็นวิธีอื่นที่นอกเหนือจากคำตอบก่อนหน้าของฉันที่ฉันสามารถเพิ่มไหใน maven 2 build classpath โดยไม่ต้องติดตั้ง

สิ่งนี้จะได้รับการ จำกัด เมื่อใช้หลายโมดูลโดยเฉพาะอย่างยิ่งถ้า JAR ที่ดาวน์โหลดมาถูกอ้างถึงในโครงการลูกนอกแม่ สิ่งนี้ยังลดการตั้งค่าโดยการสร้างไฟล์ POM และ SHA1 ซึ่งเป็นส่วนหนึ่งของบิลด์ นอกจากนี้ยังอนุญาตให้ไฟล์อยู่ที่ใดก็ได้ในโครงการโดยไม่ต้องแก้ไขชื่อหรือติดตามโครงสร้างที่เก็บ maven

สิ่งนี้ใช้ maven-install-plugin เพื่อให้สามารถใช้งานได้คุณจะต้องตั้งค่าโครงการหลายโมดูลและมีโครงการใหม่ที่แสดงถึงการสร้างเพื่อติดตั้งไฟล์ลงในที่เก็บในเครื่องและตรวจสอบให้แน่ใจว่าเป็นอย่างแรก

คุณโมดูลหลายโครงการ pom.xml จะมีลักษณะเช่นนี้:

<packaging>pom</packaging>
<modules>
<!-- The repository module must be first in order to ensure
     that the local repository is populated -->
    <module>repository</module>
    <module>... other modules ...</module>
</modules>

ไฟล์ที่เก็บ / pom.xml จะมีคำจำกัดความเพื่อโหลด JAR ที่เป็นส่วนหนึ่งของโครงการของคุณ ต่อไปนี้เป็นตัวอย่างของไฟล์ pom.xml

<artifactId>repository</artifactId>
<packaging>pom</packaging>

บรรจุภัณฑ์ pom ป้องกันไม่ให้ทำการทดสอบหรือรวบรวมหรือสร้างไฟล์ jar ใด ๆ เนื้อของ pom.xml อยู่ในส่วนบิลด์ที่ใช้ maven-install-plugin

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <executions>
                <execution>
                        <id>com.ibm.db2:db2jcc</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>install-file</goal>
                        </goals>
                        <configuration>
                            <groupId>com.ibm.db2</groupId>
                            <artifactId>db2jcc</artifactId>
                            <version>9.0.0</version>
                            <packaging>jar</packaging>
                            <file>${basedir}/src/jars/db2jcc.jar</file>
                            <createChecksum>true</createChecksum>
                            <generatePom>true</generatePom>
                        </configuration>
                </execution>
                <execution>...</execution>
            </executions>
        </plugin>
    </plugins>
</build>

หากต้องการติดตั้งมากกว่าหนึ่งไฟล์เพียงเพิ่มการดำเนินการเพิ่มเติม


นี่เป็นสิ่งเดียวที่ทำงานสำหรับโครงการหลายโมดูลของฉัน แนวทาง <repository> ในพื้นที่ด้วยเหตุผลที่ไม่ทราบสาเหตุไม่ทำงาน ขอบคุณมาก!
Lonzak

10

นี่ใช้งานได้สำหรับฉัน: สมมติว่าฉันมีการพึ่งพานี้

<dependency>
    <groupId>com.company.app</groupId>
    <artifactId>my-library</artifactId>
    <version>1.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/my-library.jar</systemPath>
</dependency>

จากนั้นเพิ่มคลาสพา ธ สำหรับการพึ่งพาระบบของคุณแบบนี้

<Class-Path>libs/my-library-1.0.jar</Class-Path>

กำหนดค่าแบบเต็ม:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <manifestEntries>
                <Build-Jdk>${jdk.version}</Build-Jdk>
                <Implementation-Title>${project.name}</Implementation-Title>
                <Implementation-Version>${project.version}</Implementation-Version>
                <Specification-Title>${project.name} Library</Specification-Title>
                <Specification-Version>${project.version}</Specification-Version>
                <Class-Path>libs/my-library-1.0.jar</Class-Path>
            </manifestEntries>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>com.company.app.MainClass</mainClass>
                <classpathPrefix>libs/</classpathPrefix>
            </manifest>
        </archive>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.5.1</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/libs/</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

9

ก่อนหน้านี้ฉันเคยเขียนเกี่ยวกับรูปแบบการทำสิ่งนี้

มันคล้ายกับโซลูชันที่เสนอโดย Pascal แม้ว่ามันจะย้ายการพึ่งพาดังกล่าวทั้งหมดไปยังโมดูลที่เก็บข้อมูลเฉพาะเพื่อที่คุณจะได้ไม่ต้องทำซ้ำทุกที่ที่การพึ่งพาถูกใช้หากมันเป็นโมดูลหลายโมดูล


6

โดยทั่วไปเพิ่มสิ่งนี้ใน pom.xml:

...

<repositories>
   <repository>
       <id>lib_id</id>
       <url>file://${project.basedir}/lib</url>
   </repository>
</repositories>

...

<dependencies>
  ...
  <dependency>
      <groupId>com.mylibrary</groupId>
      <artifactId>mylibraryname</artifactId>
      <version>1.0.0</version>
  </dependency>
  ...
</dependencies>

4

เราเปลี่ยนไปใช้การไล่ระดับเสียงและสิ่งนี้ทำงานได้ดีขึ้นในการไล่ระดับ;) เราเพียงแค่ระบุโฟลเดอร์ที่เราสามารถวางไหสำหรับสถานการณ์ชั่วคราวเช่นนั้น เรายังคงมีไหส่วนใหญ่ที่เรากำหนดไว้ในหมวดการจัดการการพึ่งพาทั่วไป (เช่นเดียวกับ maven) นี่เป็นอีกหนึ่งการพึ่งพาที่เรากำหนด

ดังนั้นโดยพื้นฐานแล้วตอนนี้เราสามารถวางขวดใด ๆ ที่เราต้องการลงไปใน lib dir ของเราเพื่อทำการทดสอบชั่วคราวถ้ามันไม่ได้อยู่ในที่เก็บของ


1
คุณยกตัวอย่างวิธีที่คุณทำสิ่งนี้?
โทมัส

2

อีกหนึ่งการแก้ปัญหาเล็ก ๆ ที่โพสต์โดย Pascal

เมื่อฉันตามเส้นทางนี้ฉันพบข้อผิดพลาดใน Maven ขณะติดตั้งขวด ojdbc

[INFO] --- maven-install-plugin:2.5.1:install-file (default-cli) @ validator ---
[INFO] pom.xml not found in ojdbc14.jar

หลังจากเพิ่ม -DpomFile ปัญหาได้รับการแก้ไข

$ mvn install:install-file -Dfile=./lib/ojdbc14.jar -DgroupId=ojdbc \
   -DartifactId=ojdbc -Dversion=14 -Dpackaging=jar -DlocalRepositoryPath=./repo \
   -DpomFile=~/.m2/repository/ojdbc/ojdbc/14/ojdbc-14.pom

0

คุณสามารถใช้ eclipse เพื่อสร้างไฟล์ Jar ที่รันได้: ส่งออก / รันได้ Jar


ไม่แน่ใจว่าเป็นการตอบคำถาม เขามีไฟล์เป็นขวดแล้ว
Johannes Jander

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