วิธีการระบุการกระจายองค์กรการจัดการของ maven กว้าง?


110

ฉันกำลังพยายามหาวิธีจัดระเบียบโครงการ maven2 จำนวนมาก (ประมาณ 50+) เพื่อให้สามารถปรับใช้ในพื้นที่เก็บข้อมูลส่วนกลาง เมื่อใช้mvn deployเป้าหมายเราจำเป็นต้องระบุเป้าหมายในแท็ก distributionManagement ดังนี้:

<distributionManagement>
   <repository>
      <id>nexus-site</id>
        <url>http://central_nexus/server</url>
   </repository>
</distributionManagement>

ตอนนี้ฉันไม่ต้องการให้ทุก ๆ pom.xml (ของ 50+) มีบล็อกนี้ซ้ำแล้วซ้ำเล่า แม้ว่าสิ่งแรกของฉันจะเป็นsettings.xmlไฟล์ แต่ดูเหมือนว่าจะไม่สามารถกำหนดได้ (โดยการออกแบบ) คำถามแรกคือทำไมถึงเป็นเช่นนั้น? ถ้าเป็นไปได้ฉันสามารถระบุได้ใน settings.xml ในการแจกจ่าย maven2 ซึ่งสามารถแจกจ่ายให้กับนักพัฒนาทุกคนได้

ทางออกเดียวที่เป็นไปได้ที่ฉันพบคือการสร้างโปรเจ็กต์ master-pom สำหรับทั้งองค์กรที่มีการตั้งค่าเหล่านี้และทำให้ pom.xml อื่น ๆ ทั้งหมดขึ้นอยู่กับ master-pom นี้ผ่าน<parent>แท็ก แต่สิ่งนี้ดูแปลก ๆ ในการสร้างหลายโมดูล:

- master configuration POM (pm)
- Project 1 parent pom (p1 with module 1 and module 2 as modules)
    - Project 1 module pom (with pm as parent)
    - Project 2 module pom (with pm as parent)

โดยปกติฉันอ่านเอกสารทั้งหมดว่าโมดูลปอมควรใช้ปอมแม่ไม่ใช่บางตัวที่แตกต่างกัน แต่หลังจากอ่านเว็บไซต์ maven เกี่ยวกับ Inheritance v. Aggregation ก็เขียนว่าเป็นไปได้แน่นอน

ปัญหาหนึ่งที่ฉันพบคือการสร้างไซต์ maven ซึ่งดูเหมือนจะมีปัญหากับการตั้งค่านี้ (โมดูลไม่ได้รับการเชื่อมโยงอย่างถูกต้องหากไม่มีการอ้างอิงย้อนกลับโดยตรง)

นี่เป็นแนวทางที่ถูกต้องหรือไม่? วิธีอื่นที่ชัดเจนและง่ายกว่าสำหรับปัญหานี้หรือไม่?



5
@OhadR: พวกเขาเขียนวิธีการเขียนไว้ในโครงการเดียวเท่านั้น ประเด็นคือฉันไม่ต้องการทำซ้ำประมาณ 500 ครั้ง ...
mglauche

1
ฉันเห็น. จุดที่ถ่าย ดังที่ผู้ตอบกล่าวว่าคุณสามารถมี pom หลักสำหรับโครงการซึ่งจะมี 'distributionMngmnt' ...
OhadR

คำตอบ:


144

ทางออกที่ดีที่สุดคือสร้างโปรเจ็กต์ไฟล์พาเรนต์แบบง่าย (พร้อมแพ็กเกจ 'ปอม') สำหรับโปรเจ็กต์ทั้งหมดจากองค์กรของคุณ

<?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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>your.company</groupId>
    <artifactId>company-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <distributionManagement>
        <repository>
            <id>nexus-site</id>
            <url>http://central_nexus/server</url>
        </repository>
    </distributionManagement>

</project>

สิ่งนี้สามารถสร้างปล่อยและปรับใช้กับ Nexus ในพื้นที่ของคุณเพื่อให้ทุกคนสามารถเข้าถึงสิ่งประดิษฐ์ได้

ตอนนี้สำหรับทุกโครงการที่คุณต้องการใช้เพียงรวมส่วนนี้:

<parent>
  <groupId>your.company</groupId>
  <artifactId>company-parent</artifactId>
  <version>1.0.0</version>
</parent>

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

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

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

- pom.xml (aggregator)
    - project-parent
    - project-module1
    - project-module2

สิ่งที่คุณทำกับโครงสร้างนี้คือรวมโมดูลหลักของคุณในตัวรวบรวมและสร้างทุกอย่างด้วยmvn installจากไดเร็กทอรีราก

เราใช้โซลูชันที่แน่นอนนี้ในองค์กรของฉันและได้รับการทดสอบมาแล้วและได้ผลดีสำหรับเรา


นี่คือคำตอบอื่นที่ฉันอธิบายการสืบทอดโครงการโดยละเอียดและวิธีจัดการความซับซ้อนที่สืบทอดมาโดยไม่ต้องให้อภัยปุน ;) stackoverflow.com/questions/6347913
Jesse Webb

7
เพียงแค่โน้ตเล็ก ๆ สำหรับเหตุผลที่ว่าทำไมบริษัท แม่คือทางออกที่ดีที่สุดให้ดูที่การอภิปรายไม่สามารถระบุ distributionManagement ใน settings.xmlจากรายการผู้ใช้ Maven ของ
Premek Brada

ในรูปแบบการให้คำปรึกษาแบบคลาสสิกโดยที่ "ลูกค้าเป็นเจ้าของรหัส" ทีมพัฒนาของฉันจะต้องทำงานในโครงการนอกสถานที่จากนั้นนำโค้ดล่าสุดไปที่ไซต์ไคลเอ็นต์และสร้างอีกครั้ง ในสถานการณ์ของฉันทำงานกับโครงการหลายโมดูลถ้าฉันอ้างอิง POM ของ บริษัท ใน POM แม่ของโครงการฉันจะต้องอัปเดตการอ้างอิงนั้นเพื่อชี้ไปที่ POM บริษัท ของลูกค้า ฉันอยากจะพยายามรักษาการตั้งค่าเฉพาะสภาพแวดล้อมทั้งหมดใน settings.xml ถ้าฉันสามารถช่วยได้ แนวทางที่แนะนำสำหรับสถานการณ์ของฉันคืออะไร?
ผู้ใช้เว็บ

2
@WebUser ปัญหาของคุณดูเหมือนสถานการณ์ที่คุณต้องการค่าที่แตกต่างกันในไฟล์ POM ของคุณซึ่งตรงข้ามกับที่อยู่คำตอบนี้: หลีกเลี่ยงการตั้งค่าที่ซ้ำกันในหลายโมดูล ฉันคิดว่าคุณควรจะลองฉีดคุณสมบัติผ่านทางไฟล์ settings.xml หากยังไม่ได้ผลโปรดถามคำถามใหม่ที่ SO ลิงก์ไปที่นี่แล้วเราจะพยายามช่วยเหลือคุณต่อไป
Jesse Webb

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

36

ไม่จำเป็นต้องมี POM ผู้ปกครอง

คุณสามารถละเว้นส่วน distributionManagement ทั้งหมดใน poms ของคุณและตั้งค่าบนเซิร์ฟเวอร์ build ของคุณหรือใน settings.xml

หากต้องการทำบนเซิร์ฟเวอร์บิลด์เพียงส่งmvnคำสั่ง:

-DaltSnapshotDeploymentRepository=snapshots::default::https://YOUR_NEXUS_URL/snapshots
-DaltReleaseDeploymentRepository=releases::default::https://YOUR_NEXUS_URL/releases

โปรดดูhttps://maven.apache.org/plugins/maven-deploy-plugin/deploy-mojo.htmlสำหรับรายละเอียดที่สามารถตั้งค่าตัวเลือกต่างๆได้

นอกจากนี้ยังสามารถตั้งค่านี้ในsettings.xmlไฟล์.

เพียงสร้างโปรไฟล์ที่นั่นซึ่งเปิดใช้งานและมีคุณสมบัติ

ตัวอย่าง settings.xml:

<settings>
[...]
  <profiles>
    <profile>
      <id>nexus</id>
      <properties>
        <altSnapshotDeploymentRepository>snapshots::default::https://YOUR_NEXUS_URL/snapshots</altSnapshotDeploymentRepository>
        <altReleaseDeploymentRepository>releases::default::https://YOUR_NEXUS_URL/releases</altReleaseDeploymentRepository>
      </properties>
    </profile>
  </profiles>

  <activeProfiles>
    <activeProfile>nexus</activeProfile>
  </activeProfiles>

</settings>

ตรวจสอบให้แน่ใจว่าข้อมูลรับรองสำหรับ "สแนปชอต" และ "รีลีส" อยู่ใน<servers>ส่วนของ settings.xml ของคุณ

คุณสมบัติ altSnapshotDeploymentRepository และ altReleaseDeploymentRepository ถูกนำมาใช้กับ maven-deploy-plugin เวอร์ชัน 2.8 เวอร์ชันเก่าจะล้มเหลวโดยมีข้อความแสดงข้อผิดพลาด

Deployment failed: repository element was not specified in the POM inside distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter

ในการแก้ไขปัญหานี้คุณสามารถบังคับใช้ปลั๊กอินเวอร์ชันที่ใหม่กว่าได้:

        <build>
          <pluginManagement>
            <plugins>
              <plugin>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.8</version>
              </plugin>
            </plugins>
          </pluginManagement>
        </build>

ฉันพยายามแก้ปัญหานี้อย่างต่อเนื่อง แต่มีเพียงคุณสมบัติaltDeploymentRepositoryเท่านั้นที่ใช้งานได้ altReleaseDeploymentRepositoryและaltSnapshotDeploymentRepositoryไม่รู้จักและฉันได้รับข้อผิดพลาดนี้: การปรับใช้ล้มเหลว: องค์ประกอบที่เก็บไม่ได้ระบุไว้ใน POM ภายในองค์ประกอบ distributionManagement หรือใน -DaltDeploymentRepository = id :: layout :: url paramete ข้อเสนอแนะใด ๆ ที่จะช่วยได้ ขอบคุณ
Shabirmean

@Shabirmean เหตุผลคือปลั๊กอินปรับใช้เวอร์ชันเก่าเกินไป ฉันได้ขยายคำตอบพร้อมวิธีแก้ปัญหา
Michael Wyraz

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