ฉันสามารถเพิ่มไหใน maven 2 build classpath โดยไม่ต้องติดตั้งได้ไหม


700

Maven2 กำลังขับรถฉันบ้าในระหว่างการทดลอง / ขั้นตอนการพัฒนาจำลองที่รวดเร็วและสกปรก

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

ดูเหมือนว่ามันควรจะง่าย แต่ถ้าเป็นเช่นนั้นฉันก็ขาดอะไรไป

คำแนะนำใด ๆ เกี่ยวกับวิธีการทำเช่นนี้จะได้รับการชื่นชมอย่างมาก สั้น ๆ ถ้ามีวิธีง่าย ๆ ในการชี้ maven ไปยัง/libไดเรกทอรีและสร้างpom.xmljars ที่ล้อมรอบทั้งหมดที่แมปไปยังการพึ่งพาเดี่ยวซึ่งฉันสามารถตั้งชื่อ / ติดตั้งและเชื่อมโยงไปยังที่อยู่ในบัดดลได้


หากคุณใช้ Netbeans เพียงทำตามขั้นตอนเหล่านี้: [ฉันจะติดตั้งโมดูลลงในที่เก็บ Maven โดยใช้ Netbeans Embedded Maven ได้อย่างไร] [1] [1]: stackoverflow.com/a/339874/530153
Rajat Gupta

1
ฉันต้องการจะชี้ให้เห็นว่าการเชื่อมโยงstackoverflow.com/a/339874/530153นี้ดูเหมือนว่าจะทำงานสำหรับการติดตั้งขวดครั้งละ
พอล

คำตอบ:


601

ปัญหาของแนวทางที่นิยม

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

ทำไมคุณไม่ควรใช้วิธีการ "ติดตั้งกับ Repo ท้องถิ่น"

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

ทำไมคุณไม่ควรใช้แนวทาง "ขอบเขตระบบ"

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

โซลูชันพื้นที่เก็บข้อมูลแบบสแตติกในโครงการ

หลังจากใส่ลงไปในpom:

<repository>
    <id>repo</id>
    <releases>
        <enabled>true</enabled>
        <checksumPolicy>ignore</checksumPolicy>
    </releases>
    <snapshots>
        <enabled>false</enabled>
    </snapshots>
    <url>file://${project.basedir}/repo</url>
</repository>

สำหรับสิ่งประดิษฐ์แต่ละรายการที่มีรหัสกลุ่มของแบบฟอร์มx.y.zMaven จะรวมตำแหน่งต่อไปนี้ไว้ในโครงการของคุณในการค้นหาสิ่งประดิษฐ์:

repo/
| - x/
|   | - y/
|   |   | - z/
|   |   |   | - ${artifactId}/
|   |   |   |   | - ${version}/
|   |   |   |   |   | - ${artifactId}-${version}.jar

เพื่ออธิบายเพิ่มเติมเกี่ยวกับเรื่องนี้คุณสามารถอ่านโพสต์บล็อกนี้

ใช้ Maven เพื่อติดตั้งเพื่อทำโครงการ repo

แทนที่จะสร้างโครงสร้างนี้ขึ้นมาเองฉันแนะนำให้ใช้ Maven plugin เพื่อติดตั้งไหของคุณเป็นสิ่งประดิษฐ์ ดังนั้นเพื่อติดตั้งสิ่งประดิษฐ์ไปยังที่เก็บในโครงการภายใต้repoโฟลเดอร์ดำเนินการ:

mvn install:install-file -DlocalRepositoryPath=repo -DcreateChecksum=true -Dpackaging=jar -Dfile=[your-jar] -DgroupId=[...] -DartifactId=[...] -Dversion=[...]

หากคุณเลือกวิธีนี้คุณจะสามารถทำให้การประกาศในที่เก็บง่ายขึ้นpomเพื่อ:

<repository>
    <id>repo</id>
    <url>file://${project.basedir}/repo</url>
</repository>

สคริปต์ตัวช่วย

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

รวมการพึ่งพาในแพ็คเกจเป้าหมายของคุณ

เมื่อคุณสร้างที่เก็บในโครงการแล้วคุณจะได้แก้ไขปัญหาในการกระจายการอ้างอิงของโครงการกับแหล่งที่มาของมัน แต่ตั้งแต่นั้นสิ่งประดิษฐ์เป้าหมายของโครงการของคุณจะขึ้นอยู่กับขวดที่ไม่ได้เผยแพร่ดังนั้นเมื่อคุณติดตั้ง ไปยังที่เก็บข้อมูลซึ่งจะมีการอ้างอิงที่ไม่สามารถแก้ไขได้

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


3
ฉันคิดเสมอว่าคุณสามารถสร้างพื้นที่เก็บข้อมูลในโครงการในที่สุดก็ยืนยันได้ดีมาก!
albfan

19
สองสิ่งที่ควรทราบ: 1) ฉันแนะนำให้ใช้ "$ {project.baseUri} repo" แทน "file: // $ {project.basedir} / repo" เพื่อรับ URL ที่สอดคล้องกับ RFC บน Windows 2) ถ้าคุณจัดโครงสร้างโครงการเป็น submodules วิธีการนี้ดูเหมือนจะล้มเหลวเนื่องจาก $ {project.baseUri} ได้รับการแก้ไขไปยังไดเรกทอรีย่อยของโมดูล ความคิดวิธีการแก้ไขปัญหานี้?
โอลิเวอร์ Hanappi

8
เกือบจะถึงตัวฉันแล้ว - แต่สคริปต์ของ Nikita พยายามฉลาดเกินกว่าที่จะมีไฟล์ JAR ที่ชื่อฉันไม่ดี ดังนั้นฉันจึงสร้างเวอร์ชันที่ง่ายขึ้นซึ่งไม่ได้คาดเดาอะไรเลยสำหรับ groupId: github.com/carchrae/install-to-project-repo
Tom Carchrae

3
ช่างเป็นคำตอบที่ยอดเยี่ยม !! มีสองวิธีในการทำบางสิ่งบางอย่างวิธีที่ถูกต้องและวิธีการทำงานคุณจะทำอย่างถูกวิธี!
Panthro

1
ที่นี่คุณจะพบข้อมูลวิธีสร้างสิ่งประดิษฐ์โดยอัตโนมัติจากไฟล์ jar ของคุณ: devcenter.heroku.com/articles/local-maven-dependencies
Dirk

486

สำหรับการโยนรหัสเท่านั้น

กำหนดขอบเขตระบบ == และทำขึ้น groupId, artifactId และรุ่น

<dependency>
    <groupId>org.swinglabs</groupId>
    <artifactId>swingx</artifactId>
    <version>0.9.2</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/swingx-0.9.3.jar</systemPath>
</dependency>

หมายเหตุ: การอ้างอิงระบบจะไม่ถูกคัดลอกไปยัง jar / war ที่เป็นผลลัพธ์
(ดูวิธีการรวมการพึ่งพาระบบใน war ที่สร้างโดยใช้ maven )


4
ขอบคุณสิ่งนี้อยู่ใกล้กับสิ่งที่ฉันต้องการจริงๆ มีวิธีใดที่จะเพิ่มพวกเขาทั้งหมดเป็นรายการเดียว? ว่าฉันมี / lib กับ 10 ขวดฉันสามารถเพิ่มพวกเขาทั้งหมดเช่นด้วย /some/path/*.jar สำหรับ systemPath? หรือฉันยังคงต้องปฏิบัติต่อกันในฐานะที่เป็นที่รู้จักกันดี? ยังคงใกล้กับสิ่งที่ฉันต้องการจริงๆขอบคุณ!

11
ใช้ systemPath แบบนี้: "<systemPath> $ {basedir} /lib/BrowserLauncher2-1_3.jar </systemPath>" $ {basedir} ชี้ไปที่รูทโครงการของคุณ
เฟรเดริก Morin

4
มันจะดีกว่าที่จะใช้โครงการ คำนำหน้าในเส้นทางของคุณเช่น: <systemPath> $ {project.basedir} /lib/AwesomeLib.jar </systemPath>
Matthew McCullough

76
ในขณะที่ฉันเข้าใจว่านี่คือสิ่งที่ OP ก็ขอให้ฉันยังคงต้องการที่จะขีดเส้นใต้ว่าการใช้systemขอบเขตคือการปฏิบัติที่น่ากลัวว่าจะหมดแรง ดูพึ่งพา + ขอบเขต
Pascal Thivent

6
@marioosh จำความตั้งใจดั้งเดิมของคำถามนั้นไว้เพื่อการทดลองที่รวดเร็ว หากคุณต้องการทำแพ็คเกจ mvn ให้ติดตั้ง jar ลงใน repo
Pyrolistical

64

คุณสามารถสร้างพื้นที่เก็บข้อมูลท้องถิ่นในโครงการของคุณ

ตัวอย่างเช่นถ้าคุณมีlibsโฟลเดอร์ในโครงสร้างโครงการ

  • ในlibsโฟลเดอร์คุณควรสร้างโครงสร้างไดเรกทอรีเช่น:/groupId/artifactId/version/artifactId-version.jar

  • ใน pom.xml ของคุณคุณควรลงทะเบียนที่เก็บ

    <repository>
        <id>ProjectRepo</id>
        <name>ProjectRepo</name>
        <url>file://${project.basedir}/libs</url>
    </repository>
  • และเพิ่มการพึ่งพาตามปกติ

    <dependency>
        <groupId>groupId</groupId>
        <artifactId>artifactId</artifactId>
        <version>version</version>
    </dependency>

นั้นคือทั้งหมด.

สำหรับข้อมูลโดยละเอียด: วิธีเพิ่มไลบรารีภายนอกใน Maven


1
คำตอบของคุณถูกต้องเกือบ groupId ควรจะแยกในไดเรกทอรีย่อยเซิร์ฟเวอร์
Peter Fortuin

5
แน่นอนถ้าคุณมี groupId ที่ซับซ้อนเช่น 'com.foo.bar' โครงสร้างไดเรกทอรีของคุณควรเป็น /com/foo/bar/artifactId/version/artifactId-verion.jar
Dmytro

นี่แตกต่างอย่างมากจากคำตอบเมื่อปีที่แล้วหรือไม่?
Joshua Taylor

ในไดเร็กทอรีสุดท้ายที่ไฟล์ jar ตั้งอยู่คุณต้องเพิ่มไฟล์ pom xml ที่เกี่ยวข้อง
Federico


15

นี่คือสิ่งที่ฉันได้ทำไปแล้วมันยังแก้ปัญหาแพ็กเกจและใช้ได้กับโค้ดที่เช็คเอาต์

ฉันสร้างโฟลเดอร์ใหม่ในโครงการในกรณีที่ฉันใช้repoแต่รู้สึกอิสระที่จะใช้src/repo

ใน POM ของฉันฉันมีการพึ่งพาที่ไม่ได้อยู่ในที่เก็บ Maven สาธารณะใด ๆ

<dependency>
    <groupId>com.dovetail</groupId>
    <artifactId>zoslog4j</artifactId>
    <version>1.0.1</version>
    <scope>runtime</scope>
</dependency>

ฉันสร้างไดเรกทอรีต่อไปนี้แล้ว repo/com/dovetail/zoslog4j/1.0.1และคัดลอกไฟล์ JAR ไปยังโฟลเดอร์นั้น

ฉันสร้างไฟล์ POM ต่อไปนี้เพื่อเป็นตัวแทนของไฟล์ที่ดาวน์โหลด (ขั้นตอนนี้เป็นทางเลือก แต่จะลบคำเตือน) และช่วยให้คนต่อไปรู้ว่าฉันได้ไฟล์มาที่ใด

<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.dovetail</groupId>
    <artifactId>zoslog4j</artifactId>
    <packaging>jar</packaging>
    <version>1.0.1</version>
    <name>z/OS Log4J Appenders</name>
    <url>http://dovetail.com/downloads/misc/index.html</url>
    <description>Apache Log4j Appender for z/OS Logstreams, files, etc.</description>
</project>

ไฟล์ทางเลือกสองไฟล์ที่ฉันสร้างคือการตรวจสอบ SHA1 สำหรับ POM และ JAR เพื่อลบคำเตือนเช็คซัมหายไป

shasum -b < repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.jar \
          > repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.jar.sha1

shasum -b < repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.pom \
          > repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.pom.sha1

ในที่สุดฉันก็เพิ่มแฟรกเมนต์ต่อไปนี้ใน pom.xml ของฉันซึ่งทำให้ฉันสามารถอ้างถึงที่เก็บในเครื่องได้

<repositories>
    <repository>
        <id>project</id>
        <url>file:///${basedir}/repo</url>
    </repository>
</repositories>

สวัสดีคุณใส่ไฟล์ pom ในที่เก็บในเครื่องหรือถัดจากไฟล์ jar ของคุณหรือไม่
Peymankh

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

ฉันยังคงต้องการโซลูชันที่ฉันโพสต์ที่นี่stackoverflow.com/questions/2229757/…
Archimedes Trajano

ฉันชอบวิธีนี้แม้ว่าฉันจะใช้ปลั๊กอินติดตั้ง mavenเพื่อทำการติดตั้ง jar ลงใน repo ในพื้นที่โดยอัตโนมัติ
Carl G

13

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


12

นี่คือวิธีที่เราเพิ่มหรือติดตั้ง jar ท้องถิ่น

    <dependency>
        <groupId>org.example</groupId>
        <artifactId>iamajar</artifactId>
        <version>1.0</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/lib/iamajar.jar</systemPath>
    </dependency>

ฉันให้ groupId เริ่มต้นและ artifactId บางอย่างเพราะจำเป็น :)


11

Maven install pluginมีการใช้บรรทัดคำสั่งเพื่อติดตั้ง jar ลงในที่เก็บโลคัล POM เป็นทางเลือก แต่คุณจะต้องระบุ GroupId, ArtifactId, Version และ Packaging (POM ทั้งหมด)


ที่จริงสิ่งที่เขา ment คือการที่คุณไม่ต้องสร้าง pom สำหรับไลบรารีที่คุณกำลังนำเข้าลงพื้นที่เก็บข้อมูลในท้องถิ่นของคุณ
เฟรเดริก Morin

5
-1 บางครั้งคุณแค่ต้องการเพิ่มไฟล์ jar โดยไม่มีปัญหาในการติดตั้ง
Leonel

8

การใช้<scope>system</scope>เป็นแนวคิดที่ไม่ดีด้วยเหตุผลที่ผู้อื่นอธิบายการติดตั้งไฟล์ด้วยตนเองไปยังที่เก็บในเครื่องของคุณทำให้การสร้างไม่สามารถพิสูจน์ได้และการใช้<url>file://${project.basedir}/repo</url>ไม่ใช่ความคิดที่ดีเพราะ (1) ที่อาจไม่ใช่fileURL ที่มีรูปแบบดี(เช่นถ้าโครงการ ถูกเช็กเอาต์ในไดเรกทอรีที่มีตัวอักษรผิดปกติ), (2) ผลลัพธ์ไม่สามารถใช้ได้ถ้า POM ของโครงการนี้ถูกใช้เป็นการอ้างอิงของโปรเจ็กต์ของบุคคลอื่น

สมมติว่าคุณไม่ต้องการอัปโหลดสิ่งประดิษฐ์ไปยังที่เก็บข้อมูลสาธารณะคำแนะนำของไซเมียนเกี่ยวกับโมดูลตัวช่วยจะทำงานได้ แต่ตอนนี้มีวิธีที่ง่ายกว่า ...

คำแนะนำ

ใช้ที่ไม่ใช่ Maven-ขวด Maven ปลั๊กอิน ทำสิ่งที่คุณขออย่างแน่นอนโดยไม่มีข้อเสียของวิธีการอื่น


นอกจากนี้ยังเห็นMaven ภายนอกพึ่งพาปลั๊กอินแม้ว่าไม่ใช่ Maven-ขวด Maven ปลั๊กอินดูเหมือนตรงไปตรงมามากขึ้นในการใช้งาน
Jesse Glick

8

ฉันพบวิธีอื่นในการทำเช่นนี้ดูที่นี่จากโพสต์ Heroku

เพื่อสรุป (ขออภัยเกี่ยวกับการคัดลอกและวาง)

  • สร้างrepoไดเรกทอรีภายใต้รูทโฟลเดอร์ของคุณ:
yourproject
+ - pom.xml
+ - src
+ - repo
  • เรียกใช้สิ่งนี้เพื่อติดตั้ง jar ไปยังไดเรกทอรี repo ท้องถิ่นของคุณ
mvn ปรับใช้: deploy-file -Durl = file: /// พา ธ / ไปยัง yourproject / repo / -Dfile = mylib-1.0.jar -DgroupId = com.example -DartifactId = mylib -Dpackaging = jar -Dversion = 1.0
  • เพิ่มของคุณpom.xml:
<repositories>
    <!--other repositories if any-->
    <repository>
        <id>project.local</id>
        <name>project</name>
        <url>file:${project.basedir}/repo</url>
    </repository>
</repositories>


<dependency>
    <groupId>com.example</groupId>
    <artifactId>mylib</artifactId>
    <version>1.0</version>  
</dependency>

6

หลังจากที่ได้พูดคุยกันเป็นเวลานานกับพวก CloudBees เกี่ยวกับบรรจุภัณฑ์ที่ถูกต้องของ JARs พวกเขาทำข้อเสนอที่ดีที่น่าสนใจสำหรับการแก้ปัญหา:

การสร้างโครงการ Maven ปลอมซึ่งแนบ JAR ที่มีอยู่แล้วเป็นสิ่งประดิษฐ์หลักซึ่งพบในการติดตั้ง POM ที่เป็นของ: การดำเนินการติดตั้งไฟล์ นี่คือตัวอย่างของ kinf ของ POM ดังกล่าว:

 <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <version>2.3.1</version>
            <executions>
                <execution>
                    <id>image-util-id</id>
                    <phase>install</phase>
                    <goals>
                        <goal>install-file</goal>
                    </goals>
                    <configuration>
                        <file>${basedir}/file-you-want-to-include.jar</file>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>${project.artifactId}</artifactId>
                        <version>${project.version}</version>
                        <packaging>jar</packaging>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

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

โครงการรูท (ซึ่งมีไฟล์พาเรนต์ POM รวมถึงโมดูลย่อยทั้งหมดที่มีโมดูลองค์ประกอบ XML ) (บรรจุภัณฑ์ POM)

JAR 1 wrapper โครงการ Maven child (บรรจุภัณฑ์ POM)

JAR 2 wrapper โครงการ Maven child (บรรจุภัณฑ์ POM)

โครงการหลัก Maven child ที่มีอยู่ (WAR, JAR, EAR .... บรรจุภัณฑ์)

เมื่อพาเรนต์ทำงานผ่าน mvn: ติดตั้งหรือ mvn: บรรจุภัณฑ์ถูกบังคับและโมดูลย่อยจะถูกดำเนินการ ที่อาจเกี่ยวข้องกับการลบที่นี่เนื่องจากโครงสร้างโครงการควรมีการเปลี่ยนแปลง แต่เสนอโซลูชันที่ไม่คงที่ในตอนท้าย


เป็นเพียงการสังเกต แต่ฉันไม่คิดว่าคุณจะต้องสร้าง POM ใหม่สำหรับ JAR แต่ละตัวที่คุณต้องการเพิ่ม มันควรจะเพียงพอที่จะสร้าง POM เดียวเพื่อเพิ่มJAR ทั้งหมดที่ให้คุณมีบล็อกการดำเนินการสำหรับแต่ละ jar ที่คุณต้องการเพิ่ม คุณต้องตรวจสอบให้แน่ใจว่าแต่ละบล็อคมีรหัสที่ไม่ซ้ำกัน ผลลัพธ์คือโมดูล Maven เดียวที่จะเพิ่ม JAR ทั้งหมดลงใน repo โลคอล (ตรวจสอบให้แน่ใจว่าพิกัด maven ไม่ได้ขัดแย้งกับสิ่งที่อาจมีอยู่แล้วหรืออาจถูกเพิ่มในภายหลัง!)
Stormcloud

พระเอก นี่คือสิ่งที่ฉันต้องการ นิสัยดีคนหนึ่ง ปี 2556 คงเป็นปีที่ดี;)
ndtreviv

5

สิ่งที่ง่ายที่สุดสำหรับฉันคือเพียงกำหนดค่า maven-compiler-plugin ของคุณเพื่อรวมไหที่กำหนดเองของคุณ ตัวอย่างนี้จะโหลดไฟล์ jar ใด ๆ ในไดเร็กทอรี lib

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <includes>
                    <include>lib/*.jar</include>
                </includes>
            </configuration>
        </plugin>

1
ถ้าฉันเพิ่ม maven นี้says nothing to complile!
Ravi Parekh

มันกำลังพูดall classes are up to date nothing to compileเพราะมันจะไม่ค้นหา*.javaอีกต่อไป <include>**/*.java</include>คุณสามารถเพิ่มพวกเขากลับมาใช้ ยังไม่ประสบความสำเร็จสำหรับฉันสำหรับขวด
Michael Laffargue

@Imiguelmh ด้วยเหตุผลใด ๆ ที่ว่าทำไมมันถึงใช้งานไม่ได้กับไห
kisna

4

ปัญหาsystemPathคือขวดของการพึ่งพาจะไม่ได้รับการแจกจ่ายไปพร้อมกับสิ่งประดิษฐ์ของคุณเป็นการพึ่งพาสกรรมกริยา ลองสิ่งที่ฉันโพสต์ที่นี่: วิธีที่ดีที่สุดในการ Mavenize ไฟล์ jar โครงการของคุณหรือวางไว้ใน WEB-INF / lib?

จากนั้นประกาศการขึ้นต่อเนื่องตามปกติ

และโปรดอ่านหมายเหตุท้ายกระดาษ


3

ทางออกที่แปลกที่ฉันพบ:

ใช้ Eclipse

  • สร้างโปรเจ็กต์ Java แบบง่าย (ไม่ใช่ maven)
  • เพิ่มคลาสหลัก
  • เพิ่มไหทั้งหมดไปที่ classpath
  • เอ็กซ์พอร์ต Runnable JAR (สำคัญเพราะไม่มีวิธีอื่นที่จะทำ)
  • เลือกแตกไลบรารีที่จำเป็นออกเป็น JAR ที่สร้างขึ้น
  • ตัดสินใจเกี่ยวกับปัญหาลิขสิทธิ์
  • tadammm ... ติดตั้ง jar ที่สร้างไปยัง m2repo ของคุณ
  • เพิ่มการพึ่งพาเดี่ยวนี้ให้กับโครงการอื่น ๆ ของคุณ

ไชโย


3

หากคุณต้องการวิธีแก้ปัญหาที่รวดเร็วและสกปรกคุณสามารถทำสิ่งต่อไปนี้ได้ (แม้ว่าฉันจะไม่แนะนำสิ่งนี้ยกเว้นโครงการทดสอบ แต่ Maven จะบ่นยาวเกินไปว่าสิ่งนี้ไม่เหมาะสม)

เพิ่มรายการการพึ่งพาสำหรับไฟล์ jar แต่ละไฟล์ที่คุณต้องการโดยเฉพาะอย่างยิ่งด้วยสคริปต์ perl หรือสิ่งที่คล้ายกันและคัดลอก / วางลงในไฟล์ pom ของคุณ

#! /usr/bin/perl

foreach my $n (@ARGV) {

    $n=~s@.*/@@;

    print "<dependency>
    <groupId>local.dummy</groupId>
    <artifactId>$n</artifactId>
    <version>0.0.1</version>
    <scope>system</scope>
    <systemPath>\${project.basedir}/lib/$n</systemPath>
</dependency>
";

ใช่นี่คือสิ่งที่ฉันกำลังมองหา วิธีที่จะผลักดันให้ผ่านรหัสการทดสอบการวิจัย ไม่มีอะไรแฟนซี ใช่ฉันรู้ว่านั่นคือสิ่งที่พวกเขาทั้งหมดพูด :) โซลูชั่นปลั๊กอิน maven ต่าง ๆ ดูเหมือนจะ overkill สำหรับวัตถุประสงค์ของฉัน ฉันมีไหที่มอบให้ฉันในฐานะบุคคลที่สามพร้อมกับไฟล์ปอม ฉันต้องการให้คอมไพล์ / รันอย่างรวดเร็ว วิธีแก้ปัญหาที่ฉันปรับให้เข้ากับงูหลามนั้นเป็นสิ่งมหัศจรรย์สำหรับฉัน ตัดและวางลงในปอมของฉัน
พอล

3

รวดเร็วและสกปรกแก้ปัญหาชุด (ขึ้นอยู่กับคำตอบของอเล็กซ์):

libs.bat

@ECHO OFF
FOR %%I IN (*.jar) DO (
echo ^<dependency^>
echo ^<groupId^>local.dummy^</groupId^>
echo ^<artifactId^>%%I^</artifactId^>
echo ^<version^>0.0.1^</version^>
echo ^<scope^>system^</scope^>
echo ^<systemPath^>${project.basedir}/lib/%%I^</systemPath^>
echo ^</dependency^>
)

libs.bat > libs.txtดำเนินการเช่นนี้ จากนั้นเปิดlibs.txtและคัดลอกเนื้อหาเป็นการอ้างอิง

ในกรณีของฉันฉันต้องการไลบรารีเพื่อรวบรวมรหัสของฉันเท่านั้นและวิธีนี้เป็นวิธีที่ดีที่สุดสำหรับจุดประสงค์นั้น


2

แม้ว่ามันจะไม่ตรงกับปัญหาของคุณฉันจะดร็อปที่นี่ ความต้องการของฉันคือ:

  1. ขวดที่ไม่สามารถพบได้ในที่เก็บ maven ออนไลน์ควรอยู่ใน SVN
  2. หากผู้พัฒนารายหนึ่งเพิ่มห้องสมุดอื่นผู้พัฒนารายอื่นไม่ควรกังวลกับการติดตั้งด้วยตนเอง
  3. IDE (NetBeans ในกรณีของฉัน) ควรจะสามารถค้นหาแหล่งที่มาและ javadocs เพื่อให้การเติมข้อความอัตโนมัติและความช่วยเหลือ

มาพูดคุยเกี่ยวกับ (3) ก่อน: แค่เอาไหในโฟลเดอร์แล้วเอาไปรวมไว้ในโหลสุดท้ายจะใช้ไม่ได้เพราะ IDE จะไม่เข้าใจสิ่งนี้ หมายความว่าต้องติดตั้งไลบรารีทั้งหมดอย่างถูกต้อง อย่างไรก็ตามฉันไม่ต้องการให้ทุกคนติดตั้งโดยใช้ "mvn install-file"

ในโครงการของฉันฉันต้องการ metawidget ไปเลย:

  1. สร้างโครงการ maven ใหม่ (ตั้งชื่อเป็น "shared-libs" หรืออะไรทำนองนั้น)
  2. ดาวน์โหลด metawidget และแตก zip ลงใน src / main / lib
  3. โฟลเดอร์ doc / api มี javadocs สร้าง zip ของเนื้อหา (doc / api / api.zip)
  4. แก้ไข pom แบบนี้
  5. สร้างโครงการและไลบรารีจะถูกติดตั้ง
  6. เพิ่มไลบรารีเป็นการพึ่งพาโครงการของคุณหรือ (ถ้าคุณเพิ่มการพึ่งพาในโครงการ shared-libs) เพิ่ม shared-libs เป็นการอ้างอิงเพื่อรับไลบรารีทั้งหมดในครั้งเดียว

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


คุณอาจต้องการตรวจสอบMaven: เพิ่มการพึ่งพาให้ขวดโดยทางญาติ (ซึ่งเป็น IMHO เป็นทางเลือกที่ดีกว่า)
Pascal Thivent

มันจะดีกว่าถ้าคุณสามารถมั่นใจได้ว่าที่เก็บในเครื่องมีเส้นทางสัมพัทธ์เดียวกันกับโครงการเสมอ ถ้าฉันมีหลายโครงการ (หรือสาขาแตกต่างกัน) ในสถานที่ต่างกันสิ่งนี้จะไม่ทำงาน
Cephalopod

คำตอบของฉันมีวิธีที่จะบอก pom.xml เกี่ยวกับขวดในโครงการของคุณ ทำไมไม่ทำอย่างนั้นและชี้ไปที่ไหใน $ {basedir} / lib?
Ed Brannin

1
@Ed เพราะนั่นไม่ใช่ขอบเขตของระบบการพึ่งพาขอบเขตของระบบจึงมีผลข้างเคียงมากมาย นี่เป็นวิธีปฏิบัติที่น่ากลัวที่ควรถูกห้ามโดยสิ้นเชิง
Pascal Thivent

2

ในการติดตั้ง jar บุคคลที่สามซึ่งไม่ได้อยู่ในที่เก็บ maven ให้ใช้ maven-install-plugin

ด้านล่างเป็นขั้นตอน:

  1. ดาวน์โหลดไฟล์ jar ด้วยตนเองจากแหล่งที่มา (เว็บไซต์)
  2. สร้างโฟลเดอร์และวางไฟล์ jar ของคุณไว้
  3. เรียกใช้คำสั่งด้านล่างเพื่อติดตั้ง jar ของบุคคลที่สามในที่เก็บ maven ท้องถิ่นของคุณ

mvn ติดตั้ง: install-file -Dfile = -DgroupId = -DartifactId = -Dversion = -Dpackaging =

ด้านล่างเป็นตัวอย่างที่ฉันใช้สำหรับ simonsite log4j

mvn ติดตั้ง: install-file -Dfile = / Users / athanka / git / MyProject / repo / log4j-rolling-appender.jar -DgroupId = uk.org.simonsite -DartifactId = log4j-rolling-appender -Dversion = 20150607-2059 - Dpackaging = ขวด

  1. ใน pom.xml รวมถึงการพึ่งพาดังต่อไปนี้

      <dependency> 
            <groupId>uk.org.simonsite</groupId>
            <artifactId>log4j-rolling-appender</artifactId>
            <version>20150607-2059</version> 
      </dependency>
  2. รันคำสั่ง mvn clean install เพื่อสร้างแพ็กเกจของคุณ

ด้านล่างคือลิงค์อ้างอิง:

https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html


นี้เป็นเส้นเขตแดนคำตอบการเชื่อมโยงเท่านั้น คุณควรขยายคำตอบเพื่อรวมข้อมูลให้มากที่สุดที่นี่และใช้ลิงก์เพื่อการอ้างอิงเท่านั้น
Goodbye StackExchange

2

สำหรับผู้ที่ไม่พบคำตอบที่ดีนี่คือสิ่งที่เรากำลังทำเพื่อให้ได้ขวดที่มีการพึ่งพาที่จำเป็นทั้งหมดในนั้น คำตอบนี้ ( https://stackoverflow.com/a/7623805/1084306 ) กล่าวถึงการใช้ Maven Assembly plugin แต่ไม่ได้ให้ตัวอย่างในคำตอบ และถ้าคุณไม่อ่านจนจบคำตอบ (มันค่อนข้างยาว) คุณอาจจะพลาด การเพิ่มด้านล่างให้กับ pom.xml ของคุณจะสร้างขึ้นtarget/${PROJECT_NAME}-${VERSION}-jar-with-dependencies.jar

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.4.1</version>
            <configuration>
                <!-- get all project dependencies -->
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <!-- MainClass in mainfest make a executable jar -->
                <archive>
                  <manifest>
                    <mainClass>my.package.mainclass</mainClass>
                  </manifest>
                </archive>

            </configuration>
            <executions>
              <execution>
                <id>make-assembly</id>
                <!-- bind to the packaging phase -->
                <phase>package</phase> 
                <goals>
                    <goal>single</goal>
                </goals>
              </execution>
            </executions>
        </plugin>

1

ฉันพูดถึงรหัสไพ ธ อนบางส่วนในความคิดเห็นต่อคำตอบจาก @alex lehmann's ดังนั้นโพสต์ไว้ที่นี่

def AddJars(jarList):
  s1 = ''
  for elem in jarList:
   s1+= """
     <dependency>
        <groupId>local.dummy</groupId>
        <artifactId>%s</artifactId>
        <version>0.0.1</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/manual_jars/%s</systemPath>
     </dependency>\n"""%(elem, elem)
  return s1

0

สิ่งนี้ไม่ตอบวิธีเพิ่มลงใน POM ของคุณและอาจไม่ใช่เกมง่ายๆ แต่จะเพิ่ม lib dir ให้กับ classpath ของคุณหรือไม่ ฉันรู้ว่าเป็นสิ่งที่ฉันทำเมื่อฉันต้องการไหภายนอกที่ฉันไม่ต้องการเพิ่มลงใน repos Maven ของฉัน

หวังว่านี่จะช่วยได้


1
นี่คือสิ่งที่ฉันกำลังทำอยู่และมันใช้งานได้ แต่มันก็ส่งผลเสียต่อเส้นทางการเรียนระดับโลกและฉันก็พยายามหลีกหนีจากมัน ขอบคุณ!

@Purple วิธีที่คุณทำเช่นนั้น?
TheRealChx101

0

สิ่งที่ทำงานในโครงการของเราคือสิ่งที่ Archimedes Trajano เขียน แต่เรามีใน. m2 / settings.xml ของเราดังนี้:

 <mirror>
  <id>nexus</id>
  <mirrorOf>*</mirrorOf>
  <url>http://url_to_our_repository</url>
 </mirror>

และ * ควรเปลี่ยนเป็นส่วนกลาง ดังนั้นหากคำตอบของเขาไม่ได้ผลสำหรับคุณคุณควรตรวจสอบ settings.xml ของคุณ


0

ฉันต้องการวิธีแก้ปัญหาที่รวดเร็วและสกปรก ... ฉันไม่สามารถเรียกใช้สคริปต์จาก Nikita Volkov: ข้อผิดพลาดทางไวยากรณ์ + ต้องใช้รูปแบบที่เข้มงวดสำหรับชื่อ jar

ฉันสร้างสคริปต์ Perl นี้ซึ่งทำงานกับรูปแบบอะไรก็ได้สำหรับชื่อไฟล์ jar และสร้างการอ้างอิงใน xml เพื่อให้สามารถคัดลอกวางได้โดยตรงใน pom

หากคุณต้องการใช้งานตรวจสอบให้แน่ใจว่าคุณเข้าใจสิ่งที่สคริปต์กำลังทำอยู่คุณอาจต้องเปลี่ยนlibโฟลเดอร์และค่าสำหรับgroupIdหรือartifactId...

#!/usr/bin/perl

use strict;
use warnings;

open(my $fh, '>', 'dependencies.xml') or die "Could not open file 'dependencies.xml' $!";
foreach my $file (glob("lib/*.jar")) {
    print "$file\n";
    my $groupId = "my.mess";
    my $artifactId = "";
    my $version = "0.1-SNAPSHOT";
    if ($file =~ /\/([^\/]*?)(-([0-9v\._]*))?\.jar$/) {
        $artifactId = $1;
        if (defined($3)) {
            $version = $3;
        }
        `mvn install:install-file -Dfile=$file -DgroupId=$groupId -DartifactId=$artifactId -Dversion=$version -Dpackaging=jar`;
        print $fh "<dependency>\n\t<groupId>$groupId</groupId>\n\t<artifactId>$artifactId</artifactId>\n\t<version>$version</version>\n</dependency>\n";
        print " => $groupId:$artifactId:$version\n";
    } else {
        print "##### BEUH...\n";
    }
}
close $fh;

0

วิธีแก้ปัญหาสำหรับ scope = 'system' approach ใน Java:

public static void main(String[] args) {
        String filepath = "/Users/Downloads/lib/";
        try (Stream<Path> walk = Files.walk(Paths.get(filepath))) {

        List<String> result = walk.filter(Files::isRegularFile)
                .map(x -> x.toString()).collect(Collectors.toList());

                String indentation = "    ";
                for (String s : result) {
                    System.out.println(indentation + indentation + "<dependency>");
                    System.out.println(indentation + indentation + indentation + "<groupId>"
                            + s.replace(filepath, "").replace(".jar", "")
                            + "</groupId>");
                    System.out.println(indentation + indentation + indentation + "<artifactId>"
                            + s.replace(filepath, "").replace(".jar", "")
                            + "</artifactId>");
                    System.out.println(indentation + indentation + indentation + "<version>"
                            + s.replace(filepath, "").replace(".jar", "")
                            + "</version>");
                    System.out.println(indentation + indentation + indentation + "<scope>system</scope>");
                    System.out.println(indentation + indentation + indentation + "<systemPath>" + s + "</systemPath>");
                    System.out.println(indentation + indentation + "</dependency>");
                }

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