Maven parent pom เทียบกับโมดูล pom


284

ดูเหมือนจะมีหลายวิธีในการจัดโครงสร้างปอมปอมในโครงสร้างแบบมัลติโปรเจ็กต์และฉันสงสัยว่าถ้าใครมีความคิดเกี่ยวกับข้อดี / ข้อเสียของแต่ละวิธี

วิธีที่ง่ายที่สุดในการมี parent pom ก็คือการใส่ไว้ในรูทของโปรเจคเช่น

myproject/
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

โดยที่ pom.xml เป็นทั้งโปรเจ็กต์หลักรวมถึงอธิบายโมดูล -core -api และ -app

วิธีถัดไปคือการแยกพาเรนต์ออกเป็นไดเรกทอรีย่อยของตนเองเช่นเดียวกับใน

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/

ที่ซึ่งพาเรนต์ pom ยังคงมีโมดูล แต่มันสัมพันธ์กันเช่น ../myproject-core

ในที่สุดก็มีตัวเลือกที่คำนิยามโมดูลและผู้ปกครองจะถูกแยกออกเป็น

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

โดยที่ parent pom มีการกำหนดค่า "shared" ใด ๆ (dependencyManagement คุณสมบัติ ฯลฯ ) และ myproject / pom.xml มีรายการของโมดูล

ความตั้งใจที่จะปรับขนาดให้เป็นงานสร้างขนาดใหญ่ดังนั้นควรปรับขนาดให้กับโครงการและสิ่งประดิษฐ์จำนวนมาก

คำถามโบนัสสองสามข้อ:

  • ที่ที่ดีที่สุดในการกำหนดการกำหนดค่าที่ใช้ร่วมกันต่าง ๆ เช่นในการควบคุมแหล่งที่มาไดเรกทอรีการใช้งานปลั๊กอินทั่วไป ฯลฯ (ฉันสมมติว่าผู้ปกครอง แต่ฉันมักจะถูกกัดโดยสิ่งนี้และพวกเขาได้ลงเอยในแต่ละโครงการมากกว่า คนธรรมดาคนหนึ่ง)
  • ปลั๊กอิน maven-release, hudson และ nexus จะจัดการกับวิธีการที่คุณติดตั้งหลายโครงการของคุณได้อย่างไร (อาจเป็นคำถามที่ยิ่งใหญ่กว่านี้ถ้ามีใครถูกจับได้ว่าเมื่อมีการตั้งค่าการสร้างหลายโครงการ)?

แก้ไข: แต่ละโครงการย่อยมี pom.xml ของตัวเองฉันได้ปล่อยไว้เพื่อให้มันสั้น


แต่ละโมดูลมี pom ของตัวเองหรือไม่? โครงการของฉันมี parent pom แต่แต่ละโมดูลก็มี pom ด้วยเช่นกัน (อาจเป็นวิธีที่สี่ในการอธิบาย)
harschware

ใช่ฉันจะแก้ไขและอัปเดต แต่ละ submodules มี pom ของตัวเองเช่นกัน
Jamie McCrindle

3
เช่นเดียวกับการอัพเดตฉันสามารถเห็นข้อดีของตัวเลือกที่สองคือการจัดการใน Eclipse ได้ง่ายขึ้นโดยที่ root pom.xml ในตัวอย่างแรกและตัวที่สามจะยากที่จะรวมหากโมดูลย่อยแยกโครงการใน Eclipse
Jamie McCrindle

คำตอบ:


166

ในความคิดของฉันในการตอบคำถามนี้คุณต้องคิดในแง่ของวงจรชีวิตของโครงการและการควบคุมเวอร์ชัน กล่าวอีกนัยหนึ่งผู้ปกครอง pom มีวงจรชีวิตของตัวเองเช่นมันสามารถแยกออกจากโมดูลอื่น ๆ หรือไม่?

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

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
`-- projectA
    |-- branches
    |-- tags
    `-- trunk
        |-- module1
        |   `-- pom.xml
        |-- moduleN
        |   `-- pom.xml
        `-- pom.xml

svn:externalsนี้จะทำให้การชำระเงินบิตเจ็บปวดและวิธีการทั่วไปที่จะจัดการกับที่มีการใช้งาน ตัวอย่างเช่นเพิ่มtrunksไดเรกทอรี:

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
|-- projectA
|   |-- branches
|   |-- tags
|   `-- trunk
|       |-- module1
|       |   `-- pom.xml
|       |-- moduleN
|       |   `-- pom.xml
|       `-- pom.xml
`-- trunks

ด้วยคำจำกัดความ externals ต่อไปนี้:

parent-pom http://host/svn/parent-pom/trunk
projectA http://host/svn/projectA/trunk

การชำระเงินtrunksจะส่งผลให้โครงสร้างท้องถิ่นดังต่อไปนี้ (pattern # 2):

root/
  parent-pom/
    pom.xml
  projectA/

เป็นทางเลือกคุณยังสามารถเพิ่ม a pom.xmlในtrunksไดเร็กทอรี:

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
|-- projectA
|   |-- branches
|   |-- tags
|   `-- trunk
|       |-- module1
|       |   `-- pom.xml
|       |-- moduleN
|       |   `-- pom.xml
|       `-- pom.xml
`-- trunks
    `-- pom.xml

นี่pom.xmlคือ pom "ปลอม" ชนิดหนึ่ง: มันไม่เคยถูกปล่อยออกมา, มันไม่มีเวอร์ชั่นจริงเนื่องจากไฟล์นี้ไม่เคยถูกปล่อยออกมา, มันมีเพียงรายการโมดูลเท่านั้น ด้วยไฟล์นี้การชำระเงินจะส่งผลให้โครงสร้างนี้ (รูปแบบ # 3):

root/
  parent-pom/
    pom.xml
  projectA/
  pom.xml

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

หากคำตอบคือไม่ (กลับไปที่คำถามเริ่มต้น) ฉันคิดว่าคุณสามารถใช้ชีวิตด้วยรูปแบบ # 1 (ทำสิ่งที่ง่ายที่สุดที่อาจเป็นไปได้)

ตอนนี้เกี่ยวกับคำถามโบนัส:

  • ที่ที่ดีที่สุดในการกำหนดการกำหนดค่าที่ใช้ร่วมกันต่าง ๆ เช่นในการควบคุมแหล่งที่มาไดเรกทอรีการใช้งานปลั๊กอินทั่วไป ฯลฯ (ฉันสมมติว่าผู้ปกครอง แต่ฉันมักจะถูกกัดโดยสิ่งนี้และพวกเขาได้ลงเอยในแต่ละโครงการมากกว่า คนธรรมดาคนหนึ่ง)

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

  • ปลั๊กอิน maven-release, hudson และ nexus จะจัดการกับวิธีการที่คุณติดตั้งหลายโครงการของคุณได้อย่างไร (อาจเป็นคำถามที่ยิ่งใหญ่กว่านี้ถ้ามีใครถูกจับได้ว่าเมื่อมีการตั้งค่าการสร้างหลายโครงการ)?

การตั้งค่าที่ฉันใช้งานได้ดีไม่มีอะไรจะพูดถึง

อันที่จริงฉันสงสัยว่า maven-release-plugin เกี่ยวข้องกับ pattern # 1 (โดยเฉพาะกับ<parent>ส่วนเนื่องจากคุณไม่สามารถอ้างอิง SNAPSHOT ได้ในเวลาที่วางจำหน่าย) ฟังดูเหมือนปัญหาไก่หรือไข่ แต่ฉันจำไม่ได้ว่ามันใช้งานได้หรือไม่และขี้เกียจเกินกว่าที่จะทดสอบได้


มันดีมากที่ฉันเห็นว่ามันชั่งได้อย่างไร svn: externals ตอบข้อกังวลของฉันเกี่ยวกับมันยุ่งยาก
Jamie McCrindle

@jamie ดีใจที่คุณเห็นว่ามีประโยชน์
Pascal Thivent

1
คุณช่วยอธิบายวิธีการทำให้ "แฮ็ค" ทำงานได้อย่างไร ฉันมีโครงการกางเกงว่ายน้ำและคาดหวังว่าคุณจะกำหนดเป้าหมายตัวเลือก -pl ด้วย "การเปิดตัวเครื่องปฏิกรณ์" แต่สิ่งนี้นำเสนอเป็นปัญหาเมื่อทำการปล่อยโครงสร้างเนื่องจากตัวเลือกนี้ไม่ผ่านจากการสร้างที่ระดับรากไม่ ฉันสามารถวางไว้ในตัวเลือก <arguments /> ของ release-plugin ดังนั้นการปล่อย: ดำเนิน failes เพราะมันพยายามที่จะทำงานใน pom ระดับราก ...
ม.ค.

แฮ็ค svn: externals เป็นแฮ็ค svn ที่มีประโยชน์ที่สุดที่ฉันเคยเห็นมานาน มีประโยชน์มากกับโครงการที่มีสาขาต่อโครงการภายในพื้นที่เก็บข้อมูลเดียวกัน
omerkudat

1
สวัสดี Pascal คุณจะจัดการเวอร์ชัน # อย่างไรหากโครงการที่กล่าวถึงในส่วนโมดูลไม่ได้ใช้ parent-pom เป็น <parent> แต่ใช้กับ parent อื่น แต่ project-parent-pom-pom เราจะได้รับเวอร์ชันอะไรสำหรับสิ่งประดิษฐ์ของโครงการดังกล่าว (เวอร์ชัน # ของสิ่งประดิษฐ์ในส่วน <parent> ของโครงการเหล่านั้นหรือเวอร์ชัน # ของโครงการซึ่งแสดงรายการโครงการเหล่านี้เป็นโมดูล) stackoverflow.com/questions/25918593/…
AKS

34

จากประสบการณ์ของฉันและแนวทางปฏิบัติที่ดีที่สุดของ Maven มี "ปอมปอม" สองประเภท

  • "company" parent pom - pom นี้มีข้อมูลเฉพาะและการกำหนดค่าของ บริษัท ของคุณที่สืบทอดทุก pom และไม่จำเป็นต้องคัดลอก ข้อมูลเหล่านี้คือ:

    • ที่เก็บ
    • ส่วนการจัดการการกระจาย
    • การกำหนดค่าปลั๊กอินทั่วไป (เช่น maven-compiler-plugin ซอร์สและเวอร์ชันเป้าหมาย)
    • องค์กรนักพัฒนา ฯลฯ

    การเตรียม pom พาเรนต์นี้จำเป็นต้องดำเนินการด้วยความระมัดระวังเนื่องจาก poms ของ บริษัท ทั้งหมดของคุณจะได้รับสืบทอดดังนั้น pom นี้จะต้องมีความสมบูรณ์และมั่นคง (การปล่อย pom parent เวอร์ชันจะไม่ส่งผลกระทบต่อการปล่อยโปรเจ็กต์ บริษัท ของคุณทั้งหมด!)

  • pom parent ชนิดที่สองคือ parent หลายรูปแบบ ฉันชอบวิธีแก้ปัญหาแรกของคุณ - นี่คือการประชุม maven เริ่มต้นสำหรับหลายโมดูลโครงการมักแสดงถึงโครงสร้างรหัส VCS

ความตั้งใจที่จะปรับขนาดให้เป็นงานสร้างขนาดใหญ่ดังนั้นควรปรับขนาดให้กับโครงการและสิ่งประดิษฐ์จำนวนมาก

Mutliprojects มีโครงสร้างของต้นไม้ - ดังนั้นคุณจึงไม่ได้ลูกศรลงไปจนถึงระดับหนึ่งของ pom พาเรนต์ พยายามหาโครงการที่เหมาะสมสำหรับความต้องการของคุณ - ตัวอย่างคลาสสิกคือวิธีการแยกแยะโครงการ mutimodule

distibution/
documentation/
myproject/
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml
pom.xml

คำถามโบนัสสองสามข้อ:

  • ที่ที่ดีที่สุดในการกำหนดการกำหนดค่าที่ใช้ร่วมกันต่าง ๆ เช่นในการควบคุมแหล่งที่มาไดเรกทอรีการใช้งานปลั๊กอินทั่วไป ฯลฯ (ฉันสมมติว่าผู้ปกครอง แต่ฉันมักจะถูกกัดโดยสิ่งนี้และพวกเขาได้ลงเอยในแต่ละโครงการมากกว่า คนธรรมดาคนหนึ่ง)

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

  • ปลั๊กอิน maven-release, hudson และ nexus จะจัดการกับวิธีการที่คุณติดตั้งหลายโครงการของคุณได้อย่างไร (อาจเป็นคำถามที่ยิ่งใหญ่กว่านี้ถ้ามีใครถูกจับได้ว่าเมื่อมีการตั้งค่าการสร้างหลายโครงการ)?

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


1
เพื่อให้มีโปรเจ็กต์หลัก / poms สองประเภท หนึ่งรายการที่ไม่มี <modules> การประกาศ นี่คือสิ่งที่ใช้สำหรับมรดก และโครงการหลักที่มีการประกาศ <multimodule> นี่คือสิ่งที่ submodules ไม่สืบทอดมามันเป็นเพียงเพื่อจัดการการสร้างโครงการที่ค้างไว้ ฉันถูกไหม ?
lisak

22
  1. ผู้ปกครองอิสระคือแนวทางปฏิบัติที่ดีที่สุดสำหรับการแบ่งปันการกำหนดค่าและตัวเลือกต่าง ๆ สำหรับส่วนประกอบที่ไม่ได้แยกไว้ต่างหาก Apache มีโปรเจ็กต์ pom เพื่อแชร์ประกาศทางกฎหมายและตัวเลือกบรรจุภัณฑ์ทั่วไป

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

  3. รูปแบบทั่วไป (ไม่สนใจ # 1 ในขณะนี้) มีโปรเจ็กต์พร้อมรหัสใช้โปรเจ็กต์หลักเป็นพาเรนต์และให้ใช้ระดับบนสุดเป็นพาเรนต์ สิ่งนี้อนุญาตให้ทุกคนแบ่งปันสิ่งสำคัญ แต่หลีกเลี่ยงปัญหาที่อธิบายไว้ใน # 2

  4. ปลั๊กอินของไซต์จะสับสนมากหากโครงสร้างพาเรนต์ไม่เหมือนกับโครงสร้างไดเรกทอรี หากคุณต้องการสร้างเว็บไซต์รวมคุณจะต้องเล่นซอเพื่อทำสิ่งนี้

  5. Apache CXFเป็นตัวอย่างรูปแบบใน # 2


2
ฉันได้ดู ibilio และโครงการจำนวนมากดูเหมือนจะชอบ pom "อิสระ" หลัก Hibernate, ActiveMQ, Jetty, XStream ฯลฯ ซึ่งแสดงให้เห็นว่ามันเป็นกลไกการแยกส่วน
Jamie McCrindle

2
ข้อเสียอื่นของพาเรนต์อิสระดูเหมือนว่าปลั๊กอินการปล่อย maven ดูเหมือนจะต้องการให้พาเรนต์ไปยังเวอร์ชันก่อนที่มันจะทำการปล่อย อาจไม่เป็นปัญหามากนักเนื่องจากผู้ปกครองไม่ควรเปลี่ยนแปลงมากเกินไป
Jamie McCrindle

9

มีหนึ่งจับเล็กน้อยกับวิธีที่สามคือ เนื่องจาก POM รวม (myproject / pom.xml) มักจะไม่มีพาเรนต์เลยพวกเขาจึงไม่แชร์การกำหนดค่า นั่นหมายความว่า POM รวมเหล่านั้นทั้งหมดจะมีที่เก็บข้อมูลเริ่มต้นเท่านั้น

นั่นไม่ใช่ปัญหาหากคุณใช้ปลั๊กอินจากส่วนกลางเท่านั้น แต่สิ่งนี้จะล้มเหลวหากคุณเรียกใช้ปลั๊กอินโดยใช้ปลั๊กอิน: รูปแบบเป้าหมายจากที่เก็บข้อมูลภายในของคุณ ตัวอย่างเช่นคุณสามารถมีfoo-maven-pluginกับ groupID ของเป้าหมายการให้บริการorg.example generate-fooหากคุณพยายามเรียกใช้จากรูทโปรเจ็กต์โดยใช้คำสั่งเช่นmvn org.example:foo-maven-plugin:generate-fooนั้นจะไม่สามารถรันบนโมดูลรวม (ดูหมายเหตุความเข้ากันได้ )

การแก้ปัญหาหลายอย่างเป็นไปได้:

  1. ปรับใช้ปลั๊กอินกับ Maven Central (ไม่สามารถทำได้)
  2. ระบุส่วนพื้นที่เก็บข้อมูลใน POM รวมทั้งหมดของคุณ (แบ่งหลักการDRY )
  3. ตั้งค่าที่เก็บภายในนี้ไว้ใน settings.xml (ทั้งในการตั้งค่าท้องถิ่นที่ ~ / .m2 / settings.xml หรือในการตั้งค่าส่วนกลางที่ /conf/settings.xml) จะทำให้การสร้างล้มเหลวหากไม่มี settings.xml เหล่านั้น (อาจใช้ได้สำหรับโครงการขนาดใหญ่ที่ไม่ควรสร้างขึ้นนอก บริษัท )
  4. ใช้พาเรนต์พร้อมการตั้งค่าที่เก็บใน POM รวมของคุณ (อาจเป็น POM หลักมากเกินไปหรือไม่)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.