maven ระหว่างการพึ่งพาและแท็กปลั๊กอินใน pom xml แตกต่างกันอย่างไร


118

ฉันยังใหม่กับเครื่องมือ maven ฉันได้สร้างโปรเจ็กต์ด้วย Spring และ Hibernate และมีการกำหนดค่าใน pom.xml เป็นปลั๊กอิน แต่ JUnit ถูกแท็กภายใต้การพึ่งพา คำถามของฉันคืออะไรคือตรรกะที่อยู่เบื้องหลังหนึ่งในฐานะปลั๊กอินและอีกอย่างหนึ่งเป็นการพึ่งพา?

คำตอบ:


213

ทั้งปลั๊กอินและการอ้างอิงคือไฟล์ Jar

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

ตัวอย่างเช่นคุณใช้คอมไพเลอร์ปลั๊กอินเพื่อคอมไพล์ไฟล์ java คุณไม่สามารถใช้คอมไพเลอร์ - ปลั๊กอินเป็นการอ้างอิงได้เนื่องจากจะเพิ่มปลั๊กอินลงในคลาสพา ธ เท่านั้นและจะไม่ทริกเกอร์การคอมไพเลอร์ใด ๆ ไฟล์ Jar ที่จะเพิ่มไปยัง classpath ขณะคอมไพล์ไฟล์จะถูกระบุเป็นการอ้างอิง

เช่นเดียวกันกับสถานการณ์ของคุณ คุณต้องใช้ spring-plugin เพื่อเรียกใช้งาน spring executables [ฉันไม่แน่ใจว่า spring-plugin ใช้สำหรับอะไร ฉันแค่เดาที่นี่] แต่คุณต้องการการอ้างอิงเพื่อเรียกใช้ไฟล์ปฏิบัติการเหล่านั้น และ Junit ถูกแท็กภายใต้การพึ่งพาเนื่องจากถูกใช้โดย surefire-plugin สำหรับการดำเนินการทดสอบหน่วย

ดังนั้นเราสามารถพูดได้ว่าปลั๊กอินเป็นไฟล์ Jar ที่ดำเนินการกับงานและการพึ่งพาคือ Jar ซึ่งให้ไฟล์คลาสเพื่อดำเนินการกับงาน

หวังว่าจะตอบคำถามของคุณ!


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

@taymedee คำถาม SO นี้อธิบายความแตกต่าง: stackoverflow.com/questions/16205778/…
dev_feed

1
@ r981 คำตอบของคุณต้องชัดเจนมากขึ้น คำตอบนี้ดีกว่า: stackoverflow.com/questions/26292073/…
Digital Impermanence

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

3
@MichaelPacheco สิ่งที่ฉันหมายถึงคือ spring-plugin จะทำงานบางอย่างในการเรียกใช้ชุดรหัสซึ่งอาจขึ้นอยู่กับบางไลบรารีซึ่งจะระบุโดย 'การอ้างอิง' ยกตัวอย่างอื่น: คุณต้องมีคอมไพเลอร์เพื่อรันโค้ด ที่นี่คอมไพเลอร์ของคุณคือปลั๊กอินและโค้ดของคุณคือไฟล์ปฏิบัติการ คอมไพเลอร์ของคุณเพียงอย่างเดียวสามารถเรียกใช้โค้ดใด ๆ ได้ แต่โค้ดของคุณอาจขึ้นอยู่กับไลบรารีกล่าวว่า apache commons ซึ่งจะเป็นการอ้างอิง คอมไพเลอร์ของคุณสามารถคอมไพล์โค้ดได้ก็ต่อเมื่อมีการอ้างอิงอยู่ใน classpath ฉันหวังว่าตอนนี้จะชัดเจน
r9891

37

Maven สามารถอธิบายได้ว่าเป็นเครื่องเตรียมอาหารซึ่งมีหน่วยต่างๆมากมายที่สามารถใช้เพื่อทำงานต่าง ๆ ได้ หน่วยเหล่านั้นเรียกว่าปลั๊กอิน ตัวอย่างเช่นในการรวบรวมโครงการของคุณใช้maven-compiler-pluginเพื่อเรียกใช้การทดสอบ -maven-surefire-pluginและอื่น ๆ

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


ขอบคุณสำหรับการตอบกลับอย่างรวดเร็วขออภัย แต่ฉันยังสับสนเพราะฉันรู้ว่า JUnit เป็นเฟรมเวิร์กและ (ไฮเบอร์เนตสปริง) ก็มาภายใต้เฟรมเวิร์กเท่านั้นดังนั้นในกรณี (ไฮเบอร์เนตสปริง) ก็สามารถกำหนดค่าได้ในแท็กอ้างอิง ? ฉันหวังว่าคุณจะมีคำถามของฉัน
Coral

ใช่และเท่าที่ฉันรู้ว่าไม่มีสิ่งที่เรียกว่าปลั๊กอิน Spring maven โดยปกติแล้ว Spring libs (หรือ Hibernate หรือ JUnit หรือ TestNG เป็นต้น) จะถูกประกาศว่าเป็นการอ้างอิงสำหรับโปรเจ็กต์ของคุณ ถ้าคุณยังใหม่กับ Maven ผมอยากแนะนำให้อ่านนี้หนังสือที่ดีมาก
Andrew Logvinov

@AndrewLogvinov - ฉันมีโครงการ multi pom สำหรับการทดสอบ api อัตโนมัติ หนึ่งในโครงการ maven มีการทดสอบระบบอัตโนมัติ ส่วนบิลด์ของโปรเจ็กต์ปอมมีปลั๊กอินเพียง 1 ตัวเท่านั้น - ปลั๊กอิน Surefire ที่มีการอ้างอิงถึงชุด แท็กรุ่นทั้งหมดถูกลบออก คุณช่วยบอกฉันได้ไหมว่านี่หมายถึงอะไร? ขอบคุณ
MasterJoe

15

ปลั๊กอินและการอ้างอิงเป็นสิ่งที่แตกต่างกันมากและเป็นส่วนเสริม

ปลั๊กอินคืออะไร?

ปลั๊กอินทำงานสำหรับ Maven build สิ่งเหล่านี้ไม่ได้บรรจุในแอปพลิเคชัน

สิ่งเหล่านี้คือหัวใจหลักของ Maven งานใดดำเนินการโดยผู้เชี่ยวชาญจะดำเนินการโดยปลั๊กอิน

มีสองประเภทของปลั๊กอินเป็นและปลั๊กอิน :buildreporting

  • ปลั๊กอิน Build จะถูกเรียกใช้งานระหว่างการสร้างและควรกำหนดค่าในไฟล์ <build/>องค์ประกอบจาก POM
  • ปลั๊กอินการรายงานจะดำเนินการในระหว่างการสร้างไซต์และควรกำหนดค่าใน<reporting/องค์ประกอบ> จาก POM

ตามเป้าหมายของผู้เชี่ยวชาญที่ระบุไว้ในบรรทัดคำสั่ง (ตัวอย่างเช่นmvn clean, mvn clean packageหรือmvn site) วงจรชีวิตที่เฉพาะเจาะจงจะถูกใช้และชุดเฉพาะของเป้าหมายปลั๊กอินจะถูกดำเนินการ
มีสามตัวในการสร้างวงจรชีวิต: default, และclean วงจรการจัดการการใช้งานโครงการของคุณทำความสะอาดโครงการวงจรจับในขณะที่sitedefaultcleansiteจับวงจรการสร้างเอกสารโครงการของคุณ

เป้าหมายของปลั๊กอินอาจถูกผูกไว้กับช่วงเฉพาะของช่วงชีวิตที่เฉพาะเจาะจง
ตัวอย่างเช่นmaven-compiler-pluginผูกโดยเริ่มต้นเป้าหมายเฟสวงจร:compile ปลั๊กอิน maven ส่วนใหญ่ (ทั้งปลั๊กอินหลักและปลั๊กอินของบุคคลที่สาม) ชอบการประชุมมากกว่าการกำหนดค่า ดังนั้นโดยทั่วไปแล้วสิ่งเหล่านี้จะผูกเป้าหมายของปลั๊กอินกับเฟสเฉพาะเพื่อให้การใช้งานง่ายขึ้น compile

ที่ดีกว่าและมีโอกาสเกิดข้อผิดพลาดน้อยกว่า:

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.7.0</version>
</plugin>

กว่า:

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.7.0</version>
  <executions>
    <execution>
        <phase>compile</phase>
        <goals>
            <goal>compile</goal>
        </goals>
    </execution>
  </executions>
</plugin>

การพึ่งพาคืออะไร?

การพึ่งพาเป็นสิ่งประดิษฐ์ / ส่วนประกอบ Maven ที่จำเป็นใน classpath ระหว่างการสร้าง Maven
สิ่งเหล่านี้อาจบรรจุในแอปพลิเคชัน แต่ไม่จำเป็นต้องใช้ (ดูscopeด้านล่าง)

การอ้างอิงส่วนใหญ่คือ jar แต่สิ่งเหล่านี้อาจเป็นไฟล์เก็บถาวรประเภทอื่น ๆ เช่น war, ear, test-jar, ejb-client ... หรือยังคงเป็น POM หรือ BOM
ใน pom.xml การอ้างอิงอาจระบุได้หลายตำแหน่ง: <build><dependencies>ส่วนdependencies managementหนึ่งส่วนหรือยังคงอยู่ในการpluginประกาศ ! แน่นอนปลั๊กอินบางตัวอาจต้องมีการอ้างอิงบางอย่างใน classpath ระหว่างการดำเนินการ นั่นไม่ใช่เรื่องธรรมดา แต่อาจเกิดขึ้นได้
นี่คือตัวอย่างจากเอกสารที่แสดงให้เห็นว่าpluginและdependencyอาจทำงานร่วมกัน:

ตัวอย่างเช่น Maven Antrun Plugin เวอร์ชัน 1.2 ใช้ Ant เวอร์ชัน 1.6.5 หากคุณต้องการใช้ Ant เวอร์ชันล่าสุดเมื่อเรียกใช้ปลั๊กอินนี้คุณต้องเพิ่ม<dependencies>องค์ประกอบดังต่อไปนี้:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.2</version>
        ...
        <dependencies>
          <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.7.1</version>
          </dependency>
          <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant-launcher</artifactId>
            <version>1.7.1</version>
          </dependency>
         </dependencies>
      </plugin>
    </plugins>
  </build>
  ...
</project>

ใน Maven
groupId:artifactId:packaging:classifier:versionอ้างอิงมีการอ้างอิงในรูปแบบที่เฉพาะเจาะจง:
โดยJARทั่วไปจะไม่มีการระบุลักษณนาม (ซึ่งเป็นทางเลือก) และบรรจุภัณฑ์ ( โดยค่าเริ่มต้น) ดังนั้นรูปแบบที่พบในการประกาศค่อนข้าง:dependency นี่คือตัวอย่างของการพึ่งพาที่ประกาศในส่วน:groupId:artifactId:version
<build><dependencies>

<build>
   <dependencies>
      <dependency>
         <groupId>org.hibernate</groupId>
         <artifactId>hibernate-core</artifactId>
         <version>5.2.14.Final</version>
      </dependency>
   <dependencies>
</build>

ตรงกันข้ามกับปลั๊กอินการพึ่งพามีขอบเขต ขอบเขตเริ่มต้นคือ
compileนั่นคือขอบเขตที่จำเป็นที่สุด (การประชุมมากกว่าการกำหนดค่าอีกครั้ง) ขอบเขตหมายความว่าการพึ่งพามีอยู่ใน classpaths ทั้งหมดของโครงการ
compile

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

ตัวอย่างเช่นก่อนหน้านี้เราได้กำหนด Hibernate เป็นการcompileอ้างอิงตามที่เราต้องการทุกที่: การคอมไพล์ซอร์สการคอมไพล์การทดสอบรันไทม์และอื่น ๆ สำหรับ ....
แต่เราไม่ต้องการให้ไลบรารีการทดสอบนั้นถูกบรรจุในแอปพลิเคชันหรืออ้างอิงในซอร์สโค้ด . ดังนั้นเราจึงระบุtestขอบเขตสำหรับพวกเขา:

<build>
   <dependencies>
     <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.1.0</version>
        <scope>test</scope>
     </dependency>
   <dependencies>
</build>

คำอธิบายที่ยอดเยี่ยม! เนื่องจากฉันไม่ชำนาญกับการตั้งค่าการอ้างอิงใน Java ฉันยังคงมีข้อสงสัยฉันกำลังทำงานใน IntelliJ และสร้างโครงการ maven เมื่อฉันพยายามรวมwebdriver-ieฉันมีสองตัวเลือกเช่นรวมเป็นpluginsหรือdependencyฉันรวมทั้งสองอย่างเพื่อเปรียบเทียบ & สังเกตว่าทั้งสองอย่างมีgroupIdความแตกต่างกันเพียงอย่างเดียวคือpluginsไม่ได้มาพร้อมกับรุ่นที่เฉพาะเจาะจง แต่มาพร้อมกับdependency 0.6.685คุณช่วยอธิบายในคำว่าคนธรรมดาได้ไหม (เกี่ยวกับตัวอย่างนี้) ว่าอะไรคือความแตกต่างซึ่งจะใช้เมื่อใด ข้อเสนอแนะใด ๆ ?
อนุ

1
ยากที่จะให้คำตอบที่แน่นอนที่สุดโดยไม่ต้องเห็นpom.xmlไฟล์. แต่สิ่งที่คุณควรสนใจก็คือการระบุเวอร์ชันการพึ่งพานั้นเป็นข้อบังคับ (ใน pom ปัจจุบันหรือใน pom แม่หากเป็นการพึ่งพาที่สืบทอดมา) ในเวอร์ชัน Maven ใด ๆ ในขณะที่ตั้งแต่ Maven 3 (อาจเป็นความคิดที่ไม่ดีในฐานะคุณลักษณะ) การระบุเวอร์ชันปลั๊กอินเป็นทางเลือก Maven จะใช้เวอร์ชันล่าสุดที่มีอยู่ในที่เก็บรีลีสที่ Maven พบ (1/2)
davidxxx

1
โปรดทราบว่าการระบุปลั๊กอินเป็นวิธีที่ไม่ดี ไม่ทำให้บิวด์ของคุณทำซ้ำได้ตลอดเวลา ( cwiki.apache.org/confluence/display/MAVEN/… ) คุณควรเห็นคำเตือนในบิลด์ แล้ว "ต่างกันอย่างไร". ปลั๊กอินทำงานสำหรับ Maven build ในขณะที่การพึ่งพาคือไลบรารี (jar หรืออะไรก็ได้) ที่จำเป็นใน classpath ระหว่างการสร้าง หากโครงสร้างของโครงการของคุณเหมือนกันไม่ว่าในกรณีใด ๆ (โดยใช้ไลบรารีหรือวิธีปลั๊กอิน) หมายความว่าปลั๊กอินนั้นหมดประโยชน์เนื่องจากไม่ได้ใช้ (2/2)
davidxxx

6

หากคุณมาจากพื้นหลังส่วนหน้าเช่นฉันและคุ้นเคยกับ Grunt และ npm ให้คิดแบบนี้:

ก่อนอื่นคุณจะวิ่งพูดnpm install grunt-contrib-copy --save-dev. นี่เหมือนมาเวน<dependency></dependency>นี้เป็นเหมือนผู้เชี่ยวชาญของจะดาวน์โหลดไฟล์ที่จำเป็นในการดำเนินงานสร้าง

จากนั้นคุณจะกำหนดค่างานใน Gruntfile.js

copy: {
  main: {
    src: 'src/*',
    dest: 'dest/',
  },
}

<plugin>/<plugin>นี้เป็นเหมือนผู้เชี่ยวชาญของ คุณกำลังบอกเครื่องมือสร้างว่าจะทำอย่างไรกับโค้ดที่ดาวน์โหลดโดย npm /<dependency></dependency> /

แน่นอนว่านี่ไม่ใช่การเปรียบเทียบที่แน่นอน แต่ใกล้มากพอที่จะช่วยโอบรอบศีรษะได้


4

ปลั๊กอินใช้สำหรับเพิ่มฟังก์ชันการทำงานให้กับMavenตัวมันเอง (เช่นการเพิ่มการeclipseสนับสนุนหรือSpringBootการสนับสนุนMavenเป็นต้น) ซอร์สโค้ดจำเป็นต้องมีการพึ่งพาเพื่อส่งผ่านเฟส Maven ( compileหรือtestตัวอย่าง) ในกรณีJUnitที่รหัสทดสอบนั้นเป็นส่วนหนึ่งของฐานรหัสของคุณและคุณเรียกJUnitใช้คำสั่งเฉพาะภายในชุดทดสอบและคำสั่งเหล่านั้นจะไม่ได้รับการจัดเตรียมโดยJava SDKดังนั้นจึงJUnitต้องมีอยู่ในขณะที่Mavenอยู่ในช่วงทดสอบและสิ่งนี้ได้รับการจัดการโดยการกล่าวถึงJUnitการพึ่งพา ในpom.xmlไฟล์ของคุณ


1

หัวใจหลักของ Maven คือกรอบการทำงานของปลั๊กอิน - ตามคำจำกัดความที่กะทัดรัดและเป็นทางการ เพื่อให้ชัดเจนยิ่งขึ้นคำสั่งที่คุณใช้เช่นmaven-install/clean/compile/build etcการสร้าง / เรียกใช้งาน jars ซึ่งบางครั้งเราก็เรียกใช้ด้วยตนเองเช่นกัน ดังนั้นสิ่งที่คุณต้องการเรียกใช้ (หรือกำหนดค่าหรือดำเนินการ) โดยทั่วไปคุณจะวางไว้ในแท็กการพึ่งพาของ mavens pom และคำตอบว่าใครจะเรียกใช้การอ้างอิงเหล่านี้ (จำเป็นสำหรับการตั้งค่าสภาพแวดล้อม) เป็นปลั๊กอิน

        javac (compiler) dependency.java (dependency) 

1

คำตอบหนึ่งบรรทัด - ความเข้าใจพื้นฐาน

ปลั๊กอินเป็นเครื่องมือที่คุณใช้ในการทำงานของ maven build ของคุณ

Dependencyหมายถึงไลบรารีใด ๆ ที่คุณจะใช้ในโค้ดของคุณ


0

ปลั๊กอินเป็นส่วนเสริมของ Maven ซึ่งเป็นสิ่งที่ใช้ในการสร้างสิ่งประดิษฐ์ของคุณ (ตัวอย่างเช่น maven-jar-plugin ใช้สำหรับคุณเดาว่าสร้าง jar จากคลาสและทรัพยากรที่รวบรวมไว้ของคุณ)

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

ปลั๊กอินและการพึ่งพา

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