ความแตกต่างระหว่างการรวบรวมขอบเขต maven และจัดทำขึ้นสำหรับบรรจุภัณฑ์ JAR


260

อะไรคือความแตกต่างระหว่างขอบเขต maven compileและprovidedเมื่อสิ่งประดิษฐ์ถูกสร้างขึ้นเป็น JAR? ถ้าเป็น WAR ฉันก็จะเข้าใจ - จะมีการรวมสิ่งประดิษฐ์ไว้หรือไม่ใน WEB-INF / lib แต่ในกรณีของ JAR มันไม่สำคัญ - ไม่รวมการพึ่งพา พวกเขาจะต้องอยู่บน classpath เมื่อขอบเขตของพวกเขาคือหรือcompile providedฉันรู้ว่าการprovidedพึ่งพาไม่ได้สกรรมกริยา - แต่มันเป็นเพียงความแตกต่างเพียงอย่างเดียว?

คำตอบ:


289

จากMaven Doc :

  • รวบรวม

    นี่เป็นขอบเขตเริ่มต้นใช้หากไม่มีการระบุไว้ รวบรวมพึ่งพามีอยู่ใน classpaths ทั้งหมดของโครงการ นอกจากนี้การอ้างอิงเหล่านั้นจะแพร่กระจายไปยังโครงการขึ้นอยู่กับ

  • ให้

    นี่เป็นเหมือนการคอมไพล์ แต่บ่งบอกว่าคุณคาดหวังว่า JDK หรือคอนเทนเนอร์เพื่อให้การอ้างอิงที่รันไทม์ ตัวอย่างเช่นเมื่อสร้างเว็บแอ็พพลิเคชันสำหรับ Java Enterprise Edition คุณจะต้องตั้งค่าการพึ่งพาบน Servlet API และ Java EE API ที่เกี่ยวข้องกับขอบเขตที่จัดเตรียมไว้เนื่องจากเว็บคอนเทนเนอร์จัดเตรียมคลาสเหล่านั้น ขอบเขตนี้มีให้เฉพาะในการคอมไพล์และทดสอบ classpath เท่านั้นและไม่สามารถส่งผ่านได้

สรุป:

  • การพึ่งพาไม่ใช่สกรรมกริยา (ตามที่คุณกล่าวถึง)
  • ขอบเขตที่มีให้มีให้เฉพาะในการรวบรวมและทดสอบ classpath ในขณะที่ขอบเขตการรวบรวมนั้นมีอยู่ใน classpaths ทั้งหมด
  • การอ้างอิงที่ให้ไว้จะไม่ได้รับการบรรจุ

5
ใช่ฉันรู้. แต่ฉันไตร่ตรองเกี่ยวกับความแตกต่างในขอบเขตในJAR packagingบริบท Maven doc ไม่ได้พูดถึงมัน ฉันใช้ Maven มาระยะหนึ่งแล้ว แต่ฉันเพิ่งถามตัวเองไปแล้ว :) ดังนั้นดูเหมือนว่าในJAR packagingบริบทนั้นไม่มีความแตกต่างระหว่างcompileและprovided(ยกเว้นการเปลี่ยนแปลงจากการพึ่งพา) ฉันถูกไหม?
emstol

3
@Jacob มีความหมายอย่างไร "ในขณะที่ขอบเขตคอมไพล์มีอยู่ในclasspaths ทั้งหมด "
Geek

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

2
ฉันคิดว่าความแตกต่างอยู่ที่ระยะบรรจุภัณฑ์ ด้วยการคอมไพล์มันจะรวม jar ในสงครามครั้งสุดท้ายหรือ jar (เช่น jar executable spring boot) และอาจไม่ส่งผลให้ เนื่องจาก jar ที่ระบุอาจมีให้โดยเว็บคอนเทนเนอร์ (เช่นใส่ในโฟลเดอร์ ext lib) ดังนั้นจึงไม่ได้อยู่ในแพ็คเกจสงครามถ้าไม่ได้พึ่งพาขอบเขตอื่น ๆ คอมไพล์รันไทม์อื่น ๆ
Addo Zhang

1
@emstol กลับไปที่คำถามเดิมของคุณคุณมีสิทธิ์ที่ในกรณีของ JAR การอ้างอิงจะไม่ได้รับการบรรจุภายใน JAR เอง แต่ใน Maven แพ็คเกจ JAR หมายถึงคุณต้องการให้มันใช้เป็นห้องสมุด เร็วที่สุดเท่าที่คุณนำเข้าในโครงการ Maven อื่น ๆ พึ่งพาสกรรมกริยาจะถูกนำถ้าขอบเขตและจะไม่เป็นถ้าขอบเขตcompile provided
LeoLuz

291

การรวบรวมหมายความว่าคุณต้องการ JAR สำหรับการรวบรวมและเรียกใช้แอป สำหรับเว็บแอ็พพลิเคชันตัวอย่าง JAR จะถูกวางในไดเร็กทอรี WEB-INF / lib

หมายความว่าคุณต้องมี JAR สำหรับการรวบรวม แต่ในขณะดำเนินการมี JAR ที่จัดเตรียมโดยสภาพแวดล้อมดังนั้นคุณจึงไม่จำเป็นต้องใช้ชุดโปรแกรมนี้ในแอปของคุณ สำหรับเว็บแอปหมายความว่าไฟล์ JAR จะไม่ถูกวางในไดเร็กทอรี WEB-INF / lib

สำหรับเว็บแอปหากเซิร์ฟเวอร์แอปมี JAR (หรือฟังก์ชันการทำงาน) แล้วให้ใช้ "ที่มีให้" หรือใช้ "คอมไพล์"

นี่คือการอ้างอิง


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

ฉันสามารถใช้ให้ถ้าฉันอ้างอิง JAR อื่นปรับใช้บนเซิร์ฟเวอร์แอปพลิเคชันเดียวกัน ??
Samy Omar

1
ดังนั้นเพื่อความชัดเจนการอ้างอิงที่ให้ไว้จะไม่ถูกเพิ่มไปยัง classpath เมื่อmvn exec:javaรัน แต่การอ้างอิงที่คอมไพล์คือ
Jamie

ฉันถามคำถามนี้ - stackoverflow.com/questions/37360132/…ปัญหาได้รับการแก้ไขโดยการเปลี่ยนขอบเขตจากที่ให้ไว้เพื่อรวบรวม แต่ฉันไม่เห็นความแตกต่างระหว่าง jar ที่คอมไพล์ด้วยขอบเขต "ที่ให้" และ jar ที่คอมไพล์ด้วยขอบเขต "compile" คุณช่วยอธิบายได้ไหม
Pavel_K


22

หากคุณวางแผนที่จะสร้างไฟล์ JAR ไฟล์เดียวที่มีการอ้างอิงทั้งหมด (โดยทั่วไปคือ xxxx-all.jar) ดังนั้นจึงจัดเตรียมขอบเขตเรื่องไว้เนื่องจากคลาสภายในขอบเขตนี้จะไม่เป็นแพ็กเกจใน JAR ที่ได้รับผล

ดู maven-assembly-plugin สำหรับข้อมูลเพิ่มเติม


7
ให้การอ้างอิง ==> การอ้างอิงจะไม่ถูกบรรจุ
Gab 是好人

3
ความสับสนของ OP ได้รับการแก้ไขอย่างชัดเจนเมื่อคุณจัดทำแพ็กเกจด้วยmaven-assembly-pluginน่าสนใจว่าคำตอบที่ได้รับการโหวตมากที่สุดนั้นไม่ได้กล่าวถึง
Henrique G. Abreu

ฉันไม่เข้าใจคำตอบนี้ ดูเหมือนความคิดเห็นเพิ่มเติม
reinierpost

11
  • รวบรวม

ทำให้พร้อมใช้งานในคลาสพา ธ อย่าเพิ่มการพึ่งพานี้ลงใน jar ขั้นสุดท้ายหากเป็น jar ปกติ แต่เพิ่ม jar นี้ลงใน jar หาก jar สุดท้ายเป็น jar เดียว (ตัวอย่างเช่น jar ที่รันได้)

  • ให้

การพึ่งพาจะพร้อมใช้งานในสภาพแวดล้อมรันไทม์ดังนั้นอย่าเพิ่มการพึ่งพานี้ในทุกกรณี แม้จะไม่ได้อยู่ในโถเดียว


3

สำหรับไฟล์ jar ความแตกต่างอยู่ใน classpath ที่แสดงรายการในไฟล์ MANIFEST.MF ที่รวมอยู่ใน jar หาก addClassPath ถูกตั้งค่าเป็น true ในการกำหนดค่า maven-jar-plugin 'การคอมไพล์' การพึ่งพาจะปรากฏในไฟล์ Manifest การอ้างอิงแบบ 'ให้' จะไม่เกิดขึ้น

หนึ่งในสัตว์เลี้ยงของฉันคือคำสองคำนี้ควรมีความตึงเครียดเหมือนกัน รวบรวมและจัดเตรียมหรือรวบรวมและจัดเตรียม


0

เมื่อคุณตั้งค่าขอบเขต maven เป็นprovidedหมายความว่าเมื่อปลั๊กอินทำงานเวอร์ชันการอ้างอิงจริงที่ใช้จะขึ้นอยู่กับเวอร์ชันของ Apache Maven ที่คุณติดตั้ง


0

หากไฟล์ jar นั้นเหมือนกับไฟล์ jar boot ของฤดูใบไม้ผลิที่ปฏิบัติการได้ขอบเขตของการอ้างอิงทั้งหมดจะต้องcompileรวมไฟล์ jar ทั้งหมด

แต่ถ้าไฟล์ jar ที่ใช้ในแพ็คเกจหรือแอปพลิเคชั่นอื่น ๆ นั้นไม่จำเป็นต้องรวมการอ้างอิงทั้งหมดในไฟล์ jar เนื่องจากแพ็กเกจหรือแอ็พพลิเคชันเหล่านี้สามารถให้การอ้างอิงอื่น ๆ ได้เอง

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