มีคนบอกความแตกต่างระหว่าง Ant กับ Maven ให้ฉันได้ไหม ฉันไม่เคยใช้อย่างใดอย่างหนึ่ง ฉันเข้าใจว่าพวกเขาใช้ในการสร้างโครงการ Java โดยอัตโนมัติ แต่ฉันไม่ทราบว่าจะเริ่มจากที่ใด
มีคนบอกความแตกต่างระหว่าง Ant กับ Maven ให้ฉันได้ไหม ฉันไม่เคยใช้อย่างใดอย่างหนึ่ง ฉันเข้าใจว่าพวกเขาใช้ในการสร้างโครงการ Java โดยอัตโนมัติ แต่ฉันไม่ทราบว่าจะเริ่มจากที่ใด
คำตอบ:
ในMaven: แตกหักคู่มือผมเขียนเกี่ยวกับความแตกต่างระหว่าง Maven และมดในการแนะนำชื่อส่วนคือ"ความแตกต่างระหว่างมดและ Maven" ต่อไปนี้เป็นคำตอบที่เป็นการรวมกันของข้อมูลในบทนำที่มีหมายเหตุเพิ่มเติมบางประการ
เปรียบเทียบง่าย ๆ
ฉันแค่แสดงให้คุณเห็นเพื่อแสดงให้เห็นถึงความคิดที่ว่าในระดับพื้นฐานที่สุด Maven มีการประชุมในตัว นี่คือไฟล์ Ant build อย่างง่าย:
<project name="my-project" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src/main/java"/>
<property name="build" location="target/classes"/>
<property name="dist" location="target"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file
-->
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>
<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>
ในตัวอย่าง Ant ง่าย ๆ นี้คุณสามารถดูว่าคุณต้องบอก Ant อย่างไรว่าต้องทำอย่างไร มีเป้าหมายการคอมไพล์ซึ่งรวมถึงงาน javac ที่รวบรวมซอร์สในไดเร็กทอรี src / main / java ไปยังไดเร็กทอรี target / classes คุณต้องบอก Ant อย่างชัดเจนว่าแหล่งที่มาของคุณอยู่ที่ไหนที่คุณต้องการให้โค้ดไบต์ผลลัพธ์ถูกจัดเก็บและวิธีการแพคเกจทั้งหมดนี้ให้เป็นไฟล์ JAR ในขณะที่มีการพัฒนาเมื่อเร็ว ๆ นี้ที่ช่วยลดขั้นตอน Ant แต่ประสบการณ์ของนักพัฒนาเกี่ยวกับ Ant อยู่ในการเข้ารหัสภาษาขั้นตอนที่เขียนใน XML
ตัดกันตัวอย่าง Ant ก่อนหน้านี้ด้วยตัวอย่าง Maven ใน Maven เพื่อสร้างไฟล์ JAR จากแหล่ง Java บางส่วนสิ่งที่คุณต้องทำคือสร้าง pom.xml แบบง่ายวางรหัสต้นฉบับของคุณใน $ {basedir} / src / main / java จากนั้นเรียกใช้การติดตั้ง mvn จากบรรทัดคำสั่ง . ตัวอย่าง Maven pom.xml ที่ให้ผลลัพธ์เดียวกัน
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
</project>
นั่นคือทั้งหมดที่คุณต้องการใน pom.xml ของคุณ การรันการติดตั้ง mvn จากบรรทัดคำสั่งจะประมวลผลทรัพยากรรวบรวมแหล่งดำเนินการทดสอบหน่วยสร้าง JAR และติดตั้ง JAR ในที่เก็บภายในเพื่อนำมาใช้ใหม่ในโครงการอื่น หากไม่มีการแก้ไขคุณสามารถเรียกใช้ไซต์ mvn แล้วค้นหาไฟล์ index.html ในเป้าหมาย / ไซต์ที่มีลิงก์ไปยัง JavaDoc และรายงานบางอย่างเกี่ยวกับซอร์สโค้ดของคุณ
เป็นที่ยอมรับว่าเป็นโครงการตัวอย่างที่ง่ายที่สุดที่เป็นไปได้ โปรเจ็กต์ที่มีซอร์สโค้ดเท่านั้นและสร้าง JAR โครงการที่ติดตามการประชุม Maven และไม่ต้องการการพึ่งพาหรือการปรับแต่งใด ๆ ถ้าเราต้องการที่จะเริ่มต้นปรับแต่งพฤติกรรม pom.xml ของเราจะเติบโตในขนาดและในโครงการที่ใหญ่ที่สุดที่คุณสามารถเห็นคอลเลกชันของ POM Maven ซับซ้อนมากซึ่งมีการปรับแต่งปลั๊กอินและการประกาศพึ่งพา แต่แม้ว่าไฟล์ POM ของโปรเจ็กต์ของคุณจะมีความสำคัญมากกว่านั้นพวกเขาเก็บข้อมูลประเภทต่าง ๆ ทั้งหมดจากไฟล์บิลด์ของโปรเจ็กต์ขนาดใกล้เคียงกันโดยใช้ Ant Maven POM มีการประกาศ: "นี่คือโครงการ JAR" และ "ซอร์สโค้ดอยู่ใน src / main / java" Ant build files มีคำแนะนำที่ชัดเจน: "นี่คือโครงการ", "src/main/java
"," เรียกใช้javac
กับไดเรกทอรีนี้ "," ใส่ผลลัพธ์ในtarget/classses
"," สร้าง JAR จาก .... ", ฯลฯ โดยที่ Ant ต้องมีความชัดเจนเกี่ยวกับกระบวนการมีบางอย่าง" ในตัว "เพื่อ Maven ที่เพิ่งรู้ว่าซอร์สโค้ดอยู่ที่ไหนและควรประมวลผลอย่างไร
การเปรียบเทียบระดับสูง
ความแตกต่างระหว่าง Ant และ Maven ในตัวอย่างนี้คืออะไร? มด...
ที่ Maven ...
mvn install
มีวงจรชีวิตที่คุณเรียกเมื่อคุณดำเนินการ คำสั่งนี้บอกให้ Maven ดำเนินการลำดับขั้นตอนต่อเนื่องจนกว่าจะครบวงจร ในฐานะที่เป็นผลข้างเคียงของการเดินทางครั้งนี้ผ่านวงจรชีวิต Maven ดำเนินการเป้าหมายปลั๊กอินเริ่มต้นจำนวนหนึ่งซึ่งทำสิ่งต่าง ๆ เช่นรวบรวมและสร้าง JARแล้ว Ivy ล่ะ?
ใช่แล้วบางคนอย่าง Steve Loughran จะอ่านการเปรียบเทียบนั้นและเรียกว่าเหม็น เขาจะพูดถึงว่าคำตอบนั้นละเว้นอะไรบางอย่างที่เรียกว่า Ivy ได้อย่างไรและข้อเท็จจริงที่ว่า Ant สามารถนำมาใช้ในการสร้างตรรกะใน Ant ล่าสุดได้ นี่เป็นเรื่องจริง หากคุณมีกลุ่มคนฉลาดที่ใช้ Ant + antlibs + Ivy คุณจะพบกับโครงสร้างที่ออกแบบมาอย่างดี แม้ว่าฉันจะเชื่อว่า Maven เหมาะสม แต่ฉันก็ใช้ Ant + Ivy อย่างมีความสุขกับทีมงานโครงการที่มีวิศวกรสร้างที่เฉียบคมมาก ที่ถูกกล่าวว่าฉันคิดว่าคุณจะพลาดปลั๊กอินที่มีค่าจำนวนมากเช่นปลั๊กอิน Jetty และคุณจะต้องทำงานทั้งหมดที่คุณไม่จำเป็นต้องทำเมื่อเวลาผ่านไป
สำคัญกว่า Maven vs. Ant
Maven เป็น Framework, Ant เป็น Toolbox
Maven เป็นรถยนต์บนท้องถนนที่สร้างไว้ล่วงหน้าในขณะที่ Ant เป็นชุดชิ้นส่วนรถยนต์ ด้วย Ant คุณต้องสร้างรถของคุณเอง แต่อย่างน้อยถ้าคุณจำเป็นต้องขับรถออฟโรดคุณก็สามารถสร้างรถประเภทที่เหมาะสมได้
เพื่อนำไปใช้ในวิธีอื่น Maven เป็นกรอบงานในขณะที่ Ant เป็นกล่องเครื่องมือ หากคุณพอใจกับการทำงานภายในขอบเขตของกรอบ Maven จะทำได้ดี ปัญหาสำหรับฉันคือฉันยังคงชนเข้ากับขอบเขตของกรอบและมันจะไม่ปล่อยให้ฉันออกไป
XML Verbosity
tobrien เป็นคนที่รู้มากเกี่ยวกับ Maven และฉันคิดว่าเขาให้การเปรียบเทียบที่ดีและซื่อสัตย์ของสองผลิตภัณฑ์ เขาเปรียบเทียบ Maven pom.xml แบบง่ายกับไฟล์ Ant build แบบง่ายและเขาพูดถึงว่าโครงการ Maven สามารถซับซ้อนได้อย่างไร ฉันคิดว่ามันคุ้มค่าที่จะดูการเปรียบเทียบไฟล์สองสามไฟล์ที่คุณมีแนวโน้มที่จะเห็นในโครงการจริงที่เรียบง่าย ไฟล์ด้านล่างแสดงโมดูลเดียวในโครงสร้างหลายโมดูล
ก่อนอื่นไฟล์ Maven:
<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-4_0_0.xsd">
<parent>
<groupId>com.mycompany</groupId>
<artifactId>app-parent</artifactId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>persist</artifactId>
<name>Persistence Layer</name>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>common</artifactId>
<scope>compile</scope>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>domain</artifactId>
<scope>provided</scope>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>${hibernate.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>${spring.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>2.2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>${commons-dbcp.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc</artifactId>
<version>${oracle-jdbc.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>${easymock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
และไฟล์ Ant ที่เทียบเท่า:
<project name="persist" >
<import file="../build/common-build.xml" />
<path id="compile.classpath.main">
<pathelement location="${common.jar}" />
<pathelement location="${domain.jar}" />
<pathelement location="${hibernate.jar}" />
<pathelement location="${commons-lang.jar}" />
<pathelement location="${spring.jar}" />
</path>
<path id="compile.classpath.test">
<pathelement location="${classes.dir.main}" />
<pathelement location="${testng.jar}" />
<pathelement location="${dbunit.jar}" />
<pathelement location="${easymock.jar}" />
<pathelement location="${commons-dbcp.jar}" />
<pathelement location="${oracle-jdbc.jar}" />
<path refid="compile.classpath.main" />
</path>
<path id="runtime.classpath.test">
<pathelement location="${classes.dir.test}" />
<path refid="compile.classpath.test" />
</path>
</project>
tobrien ใช้ตัวอย่างของเขาเพื่อแสดงว่า Maven มีแบบแผนในตัว แต่นั่นไม่ได้แปลว่าคุณจะเขียน XML น้อยลง ฉันได้พบสิ่งที่ตรงกันข้ามกับความจริง pom.xml นั้นยาวกว่า build.xml 3 เท่าและนั่นคือโดยไม่มีการหลงทางจากอนุสัญญา ในความเป็นจริงตัวอย่าง Maven ของฉันจะแสดงโดยไม่ต้องมี 54 บรรทัดพิเศษที่จำเป็นในการกำหนดค่าปลั๊กอิน pom.xml นั้นมีไว้สำหรับโครงการอย่างง่าย XML เริ่มเติบโตอย่างมีนัยสำคัญเมื่อคุณเริ่มเพิ่มข้อกำหนดพิเศษซึ่งไม่ธรรมดาสำหรับโครงการหลายโครงการ
แต่คุณต้องบอกมดว่าจะทำอย่างไร
ตัวอย่าง Ant ของฉันด้านบนยังไม่สมบูรณ์ เรายังคงต้องกำหนดเป้าหมายที่ใช้ในการทำความสะอาดรวบรวมทดสอบ ฯลฯ สิ่งเหล่านี้ถูกกำหนดไว้ในไฟล์บิลด์ทั่วไปที่นำเข้าโดยโมดูลทั้งหมดในโครงการหลายโมดูล ซึ่งนำฉันไปยังจุดที่เกี่ยวกับสิ่งนี้ทั้งหมดจะต้องมีการเขียนอย่างชัดเจนใน Ant ในขณะที่มันเป็นประกาศใน Maven
ความจริงมันจะช่วยฉันประหยัดเวลาถ้าฉันไม่ต้องเขียนเป้าหมาย Ant เหล่านี้อย่างชัดเจน แต่เวลาเท่าไหร่ ไฟล์ build ทั่วไปที่ฉันใช้ตอนนี้คือไฟล์ที่ฉันเขียนเมื่อ 5 ปีก่อนโดยมีการปรับแต่งเล็กน้อยตั้งแต่นั้นมา หลังจากการทดลอง 2 ปีกับ Maven ฉันดึงไฟล์ Ant build เก่าออกจากตู้แล้วปัดฝุ่นออกและนำกลับมาใช้ใหม่ สำหรับฉันค่าใช้จ่ายที่ต้องบอก Ant อย่างชัดเจนว่าต้องทำอะไรเพิ่มขึ้นน้อยกว่าหนึ่งสัปดาห์ในระยะเวลา 5 ปี
ความซับซ้อน
ความแตกต่างที่สำคัญต่อไปที่ฉันอยากพูดถึงคือความซับซ้อนและผลกระทบที่เกิดขึ้นจริงในโลกแห่งนี้ Maven ถูกสร้างขึ้นด้วยความตั้งใจในการลดภาระงานของนักพัฒนาที่มอบหมายให้สร้างและจัดการกระบวนการสร้าง เพื่อที่จะทำสิ่งนี้จะต้องมีความซับซ้อน น่าเสียดายที่ความซับซ้อนมีแนวโน้มที่จะปฏิเสธเป้าหมายที่ตั้งไว้
เมื่อเทียบกับ Ant คนสร้างในโครงการ Maven จะใช้เวลามากขึ้น:
ในทางตรงกันข้าม:
ความคุ้นเคย
ความแตกต่างก็คือความคุ้นเคย นักพัฒนาใหม่ต้องใช้เวลาในการเร่งความเร็ว ความคุ้นเคยกับผลิตภัณฑ์ที่มีอยู่ช่วยในเรื่องนั้นและผู้สนับสนุน Maven อ้างอย่างถูกต้องว่านี่คือประโยชน์ของ Maven แน่นอนความยืดหยุ่นของ Ant หมายความว่าคุณสามารถสร้างสิ่งที่คุณต้องการได้ ดังนั้นการประชุมที่ฉันใช้คือการวางไฟล์ต้นฉบับของฉันในชื่อไดเรกทอรี src / main / java คลาสที่คอมไพล์ของฉันไปยังไดเรกทอรีที่ชื่อเป้าหมาย / คลาส ฟังดูคุ้น ๆ ใช่มั้ย
ฉันชอบโครงสร้างไดเรกทอรีที่ Maven ใช้ ฉันคิดว่ามันสมเหตุสมผล นอกจากนี้ยังมีวงจรการสร้างของพวกเขา ดังนั้นฉันจึงใช้หลักการเดียวกันใน Ant builds ของฉัน ไม่ใช่เพียงเพราะมันสมเหตุสมผล แต่เพราะจะคุ้นเคยกับทุกคนที่เคยใช้ Maven มาก่อน
pom.xml
s ฉันสร้างส่วนใหญ่ผ่าน XSLT
มดเป็นเครื่องมือสร้าง
Maven เป็นเครื่องมือการจัดการโครงการและการอ้างอิง (ซึ่งแน่นอนว่าจะสร้างโครงการของคุณเช่นกัน)
Ant + Ivyเป็นการผสมผสานที่ดีถ้าคุณต้องการหลีกเลี่ยง Maven
เพียงเพื่อแสดงความแตกต่างเพิ่มเติม:
ปรับปรุง:
นี้มาจากMaven: คู่มือการแตกหัก ขออภัยฉันลืมอ้างอิงโดยสิ้นเชิง
Maven หรือ Ant? เป็นคำถามที่คล้ายกันมากสำหรับคำถามนี้ซึ่งจะช่วยคุณตอบคำถาม
Maven คืออะไร บนเว็บไซต์อย่างเป็นทางการ
แก้ไข:สำหรับโครงการใหม่ / กรีนฟิลด์ฉันขอแนะนำให้ใช้ Maven: "การประชุมผ่านการกำหนดค่า" จะช่วยให้คุณประหยัดเวลาอันมีค่าในการเขียนและตั้งค่าสคริปต์การสร้างและการปรับใช้ เมื่อคุณใช้ ant สคริปต์สร้างจะมีความยาวและความซับซ้อนเพิ่มขึ้นเมื่อเวลาผ่านไป สำหรับโครงการที่มีอยู่อาจเป็นเรื่องยากที่จะปิดกั้นการกำหนดค่า / โครงร่างในระบบ Maven
Maven ทำหน้าที่เป็นทั้งเครื่องมือการจัดการการพึ่งพา - สามารถใช้เพื่อดึงไหจากที่เก็บส่วนกลางหรือจากที่เก็บที่คุณตั้งค่า - และเป็นเครื่องมือสร้างประกาศ ความแตกต่างระหว่างเครื่องมือสร้าง "ที่เปิดเผย" และเครื่องมือดั้งเดิมเช่น ant หรือ make คือคุณกำหนดค่าสิ่งที่จำเป็นต้องทำไม่ใช่วิธีการทำ ตัวอย่างเช่นคุณสามารถพูดในสคริปต์ maven ว่าโครงการควรได้รับการบรรจุเป็นไฟล์ WAR และ maven รู้วิธีจัดการกับมัน
Maven อาศัยข้อตกลงเกี่ยวกับวิธีการจัดทำไดเรกทอรีโครงการเพื่อให้บรรลุ "การเสื่อมสภาพ" ตัวอย่างเช่นมีข้อตกลงว่าจะวางรหัสหลักของคุณที่ใดให้วาง web.xml หน่วยทดสอบของคุณและอื่น ๆ แต่ยังให้ความสามารถในการเปลี่ยนได้หากคุณต้องการ
คุณควรจำไว้ว่ามีปลั๊กอินสำหรับเรียกใช้คำสั่ง ant จากภายใน maven:
http://maven.apache.org/plugins/maven-ant-plugin/
นอกจากนี้ต้นแบบของ maven ก็ช่วยให้เริ่มต้นโครงการได้อย่างรวดเร็ว ตัวอย่างเช่นมี Wicket archetype ซึ่งจัดเตรียมคำสั่ง maven ที่คุณรันเพื่อรับโปรเจ็กต์ Hello world แบบพร้อมใช้งานทั้งหมด
ฉันสามารถใช้คนที่ไม่เคยเห็น Ant - มันbuild.xml
เขียนได้ดีพอสมควร - และพวกเขาสามารถเข้าใจสิ่งที่เกิดขึ้น ฉันสามารถใช้บุคคลเดียวกันนี้และแสดงให้พวกเขาเห็น MOM POM และพวกเขาจะไม่มีความคิดใด ๆ ว่าเกิดอะไรขึ้น
ในองค์กรด้านวิศวกรรมที่มีขนาดใหญ่มากผู้คนเขียนเกี่ยวกับไฟล์ Ant ที่มีขนาดใหญ่และไม่สามารถจัดการได้ ฉันเขียนประเภทเหล่านั้นและล้างสคริปต์ Ant เป็นการเข้าใจถึงสิ่งที่คุณต้องทำในอนาคตและออกแบบชุดแม่แบบที่สามารถตอบสนองต่อการเปลี่ยนแปลงและปรับขนาดได้ในระยะเวลา 3 ปีขึ้นไป
นอกจากว่าคุณจะมีโครงการง่าย ๆ การเรียนรู้การประชุม Maven และวิธี Maven เกี่ยวกับการทำสิ่งต่างๆให้สำเร็จนั้นเป็นงานที่ค่อนข้างน้อย
ในตอนท้ายของวันคุณไม่สามารถพิจารณาการเริ่มต้นโครงการกับ Ant หรือ Maven เป็นปัจจัย: จริง ๆ แล้วมันเป็นต้นทุนรวมในการเป็นเจ้าของ สิ่งที่องค์กรต้องใช้ในการรักษาและขยายระบบการสร้างในช่วงไม่กี่ปีเป็นหนึ่งในปัจจัยหลักที่ต้องพิจารณา
สิ่งสำคัญที่สุดของระบบการสร้างคือการจัดการการพึ่งพาและความยืดหยุ่นในการแสดงสูตรการสร้าง มันจะต้องค่อนข้างใช้งานง่ายเมื่อทำได้ดี
ฉันจะบอกว่ามันขึ้นอยู่กับขนาดของโครงการของคุณ ... โดยส่วนตัวแล้วฉันจะใช้ Maven สำหรับโครงการง่าย ๆ ที่ต้องมีการรวบรวมบรรจุภัณฑ์และการใช้งานที่ตรงไปตรงมา ทันทีที่คุณต้องทำสิ่งที่ซับซ้อนมากขึ้น (การอ้างอิงจำนวนมากการสร้างไฟล์การแมป ... ) ฉันจะเปลี่ยนเป็น Ant ...
Maven ยังเป็นที่เก็บของโครงการโอเพ่นซอร์สขนาดใหญ่ที่ใช้กันทั่วไป ในระหว่างการสร้าง Maven สามารถดาวน์โหลดการพึ่งพาเหล่านี้สำหรับคุณ (รวมถึงการพึ่งพาของคุณ :)) เพื่อให้ส่วนหนึ่งของการสร้างโครงการนี้จัดการได้ง่ายขึ้นเล็กน้อย