مسعود دباغی
مسعود دباغی
خواندن ۱۰ دقیقه·۱ سال پیش

مقایسه ANT vs Maven vs Gradle

در این مقاله به بررسی سه ابزار اتوماسیون ساخت جاوا خواهیم پرداخت که بر اکوسیستم JVM تسلط دارند:

Ant & Maven & Gradle

در ادامه به معرفی هر یک از آن ها می پردازیم و نحوه تکامل ابزارهای اتوماسیون ساخت جاوا را بررسی می کنیم.

قبل از ورود به ANT، Maven یا Gradle، ابتدا باید چند نکته مرتبط با آن ها را درک کنیم.

وابستگی (Dependency): به طور کلی، وابستگی به زمانی اطلاق می شود که چیزی برای اجرای خود به چیز دیگری نیاز دارد. به بیان ساده، "A" وابستگی به "B" دارد اگر "A" برای اجرای موفقیت آمیز خود به "B" نیاز داشته باشد. در دنیای نرم افزار، وابستگی چیزی است که اپلیکیشن شما برای اجرای موفقیت آمیز آن به آن نیاز دارد. در واقع هر کتابخانه پشتیبانی خارجی مورد نیاز برنامه است. از جمله می توان به zuul، hystrix، lombok، jdbc و... اشاره کرد.


در ابتدا وابستگی ها را به صورت زیر مدیریت می کردیم:

  • دانلود فایل JAR کتابخانه مورد نیاز به صورت دستی از اینترنت و اضافه کردن آن به پروژه ی مان.
  • نوشتن اسکریپتی که کتابخانه را به صورت خودکار از یک منبع خارجی روی شبکه دانلود کند.

مشکلات پیش روی این ابزارها:

  • اضافه کردن وابستگی ها با دانلود دستی آن ها از اینترنت کار بسیار خسته کننده ای است.
  • اگر URL منبع خارجی در اینترنت تغییر کند، اسکریپت های ما ممکن است خراب شوند.
  • شناسایی و مدیریت وابستگی های گذرا (transitive dependencies) در برنامه ما بسیار دشوار است.


ابزار مدیریت وابستگی (Dependency management tool): وابستگی های مورد نیاز برنامه را حل و مدیریت می کند.

ابزار ساخت (Build tool): ایجاد برنامه های قابل اجرا از کد منبع را خودکار می کند. Building شامل کامپایل (compiling)، پیوند (linking) و بسته بندی (packaging) کد در یک فرم قابل استفاده یا اجرایی است.


اتوماسیون ساخت شامل موارد زیر است:

1) دانلود وابستگی ها (Downloadingdependencies)

2) کامپایل کد منبع به کد باینری (Compiling source code into binary code)

3) بسته بندی آن کد باینری (Packaging that binary code)

4) آزمون های در حال اجرا (Runningtests)

5) استقرار در سیستم های تولید (Deployment to production systems)


مدیریت وابستگی و ابزارهای ساخت در جاوا:

  • ANT + Ivy (2000/2004)
  • Maven (2004)
  • Gradle (2012)


Apache ANT

Apache ANT مخفف (Another Neat Tool) یک پروژه متن باز توسط Apache است که در سال ۲۰۰۰ منتشر شد. این یک کتابخانه جاوا است که برای خودکارسازی فرآیندهای ساخت برنامه های جاوا استفاده می شود. همچنین، می توان از آن برای ساخت برنامه های غیر Java استفاده کرد. این قانون از اصل "پیکربندی بر روی قرارداد (Configuration over convention)" پیروی می کند. در Ant، ​​مراحل مختلف فرآیند ساخت "Targets" نامیده می شود. فایل‌های ساخت ANT به زبان XML نوشته می‌شوند و طبق قرارداد، به آنها "build.xml" می‌گویند. این شامل سه عنصر است: پروژه، هدف و وظیفه. هر فایل ساخت شامل یک پروژه است. هر چیزی که در build.xml وجود دارد تحت عنصر پروژه است. پروژه شامل حداقل یک هدف (پیش فرض)است. هدف شامل مجموعه ای از وظایف درون خود است و حالت خاصی از فرآیند ساخت را تعریف می کند. وظیفه یک قطعه کد است که می تواند اجرا شود. هر گره می تواند دارای ویژگی های مرتبط با آنها باشد:


ویژگی های Project:

  • نام (Name): نام project.
  • Basedir: پوشه root برای project و اختیاری است.
  • پیش فرض (Default): target پیش فرض برای build. پروژه می تواند یک یا چند target داشته باشد. از آن برای مشخص کردن target پیش فرض پروژه استفاده می شود.

ویژگی های Target:

  • Name: نام target.
  • Description: توضیحاتی درباره target.
  • Depends: فهرستی از تمام target ها که توسط کاما از هم جدا شده اند که این target به آن ها بستگی دارد.
  • If: ـ target در صورتی اجرا می شود که مشخصه درست باشد.
  • Unless: اگر مشخصه تنظیم نشده باشد هدف اجرا می شود.


Build.xml example:
Build.xml example:
Add dependency in Ant + Ivy:
Add dependency in Ant + Ivy:


مزیت اصلی Ant انعطاف پذیری آن است. Ant هیچ قرارداد کدنویسی یا ساختار پروژه ای را به توسعه دهنده تحمیل نمی کند. در نتیجه، این بدان معناست که Ant از توسعه دهندگان می خواهد که تمام دستورها را خودشان بنویسند، که گاهی اوقات منجر به فایل های build بزرگ می شود و نگهداری از آن ها دشوار است. در ابتدا، Ant هیچ پشتیبانی داخلی برای مدیریت وابستگی نداشت. بعدها Apache Ivy را به عنوان یک پروژه فرعی از پروژه Apache Ant با هدف مدیریت وابستگی توسعه یافته بود، پذیرفت.



Apache Maven

این یک ابزار مدیریت وابستگی و یک ابزار اتوماسیون ساخت است که در سال ۲۰۰۴ منتشر شد. این روش همچنان از XML استفاده می کند اما اشکالات را با پیروی از اصل "کنوانسیون بر پیکربندی (Convention over configuration)" برطرف می کند. این سیستم بر کنوانسیون ها متکی است و دستورها (اهداف) از پیش تعریف شده را ارائه می دهد. فایل پیکربندی آن که حاوی دستورالعمل های ساخت (build) و مدیریت وابستگی (dependency management) است، به صورت قراردادی "pom.xml" نامیده می شود و در پوشه ریشه (root folder) پروژه وجود دارد.

Maven workflow
Maven workflow


موتور Maven، ـ pom.xml و پروژه را به عنوان ورودی در نظر می گیرد. فایل pom.xml را می خواند و وابستگی های ذکر شده در آن را به عنوان فایل jar در مخزن محلی دانلود می کند. سپس، چرخه های حیات (life cycles)، مراحل ساخت (build) و پلاگین ها را اجرا می کند. در پایان، یک آرتیفکت بسته بندی شده و تست شده تولید می شود.

pom.xml example:
pom.xml example:


برخی از تگ های مهم در فایل pom.xml:

  • ـ groupId: نشان دهنده سازمانی است که پروژه به آن تعلق دارد.
  • ـ artifactId: نام این پروژه است.
  • ـ version: نشان دهنده نسخه پروژه است.
  • ـ packaging: شکل نهایی ساخت پروژه را نشان می دهد. به عنوان مثال jar, war.


مخزن ماون (Maven repository)

مخزن یک دایرکتوری است که در آن تمام فایل های jar بسته بندی شده به همراه فایل های pom خودشان وجود دارند. این فایل های pom شامل وابستگی های خارجی آن پروژه هستند. به این ترتیب maven وابستگی های پروژه خود را به صورت بازگشتی دانلود می کند تا زمانی که تمام وابستگی های مورد نیاز در مخزن محلی شما وجود داشته باشد. سه نوع مخزن در maven وجود دارد:

1) مخزن محلی (Local repository): مخزنی است که در خود ماشین توسعه دهنده وجود دارد.

2) مخزن از راه دور / سطح سازمان (Organisation level/remote repository): مخزن موجود در سازمان است.

3) مخزن مرکزی (Central repository): یک مخزن بر روی اینترنت است که توسط جامعه maven ایجاد و نگهداری می شود.

Maven
Maven

هرگاه یک وابستگی در فایل pom.xml یک پروژه مشخص شود، Maven آن را در مخزن محلی (local repository) جستجو می کند. اگر در آنجا یافت نشد، آن را در مخزن remote/org-wide جستجو می کند. اگر حتی در آنجا هم وجود نداشته باشد، آن را در مخزن مرکزی (central repository) جستجو می کند.


معایب Maven:

1) مدیریت وابستگی (Dependency management) تضادهای بین نسخه های مختلف یک کتابخانه را به خوبی مدیریت نمی کند.

2) سفارشی سازی اهداف سخت است.



Gradle

این یک ابزار مدیریت وابستگی متن باز و اتوماسیون ساخت است که در سال ۲۰۱۲ منتشر شد. این زبان بخش های خوب Apache Ant و Apache Maven را ترکیب می کند و بر روی آن ها می سازد و به جای XML از یک زبان خاص دامنه (براساس Groovy)استفاده می کند. این شرکت انعطاف پذیری را از Ant و چرخه حیات آن را از Maven گرفت. همچنین از اصل "کنوانسیون بر پیکره بندی (Convention over configuration)" پیروی می کند. از مخازن Maven و Ivy برای بازیابی وابستگی ها پشتیبانی می کند. فایل پیکربندی آن به صورت قراردادی با نام "build.gradle" شناخته می شود و در پوشه ریشه (اصلی) پروژه وجود دارد. Gradle نام مراحل ساخت خود را " Tasks" گذاشت، برخلاف " targets" Ant یا " phases" Maven. گوگل از Gradle به عنوان ابزار ساخت (build) پیش فرض برای سیستم عامل اندروید استفاده کرد.

ـ Gradle از XML استفاده نمی کند. در عوض، زبان مخصوص دامنه خود را براساس Groovy (یکی از زبان های JVM)دارد. در نتیجه اسکریپت های ساخت Gradle بسیار کوتاه تر و واضح تر از اسکریپت های نوشته شده برای Ant یا Maven هستند. مقدار کد با Gradle بسیار کم تر است.


پیکربندی های Gradle (Gradle configurations)

  • ـ implementation (پیاده سازی): برای اعلام وابستگی استفاده می شود.
  • ـ api: برای اعلام وابستگی هایی استفاده می شود که بخشی از API ما هستند، یعنی وابستگی هایی که ما به صراحت می خواهیم آن ها را در معرض مصرف کنندگان خود قرار دهیم.
  • ـ compileOnly: به ما این امکان را می دهد وابستگی هایی را اعلام کنیم که تنها باید در زمان کامپایل در دسترس باشند، اما در زمان اجرا مورد نیاز نیستند. یک مورد استفاده نمونه برای این پیکربندی یک annotation processor مانند Lombok است که بایت کد را در زمان کامپایل اصلاح می کند. پس از کامپایل دیگر نیازی به آن نیست، بنابراین وابستگی در زمان اجرا در دسترس نیست.
  • ـ RuntimeOnly: به ما این امکان را می دهد وابستگی هایی را اعلام کنیم که در زمان کامپایل مورد نیاز نیستند، اما در زمان اجرا در دسترس خواهند بود.
  • ـ testImplementation: مشابه implementation ، اما وابستگی های اعلام شده با testImplementation تنها در طول کامپایل و زمان اجرای تست ها در دسترس هستند. ما می توانیم از آن برای اعلام وابستگی به چارچوب های تست مانند JUnit یا Mockito استفاده کنیم که تنها در تست ها به آن نیاز داریم و نباید در کد تولید موجود باشد.
  • ـ testCompileOnly: مشابه compileOnly، اما وابستگی های اعلام شده با testCompileOnly تنها در طول کامپایل تست ها در دسترس هستند و نه در زمان اجرا.
  • ـ testRuntimeOnly: مشابه runtimeOnly، اما وابستگی های اعلام شده با testRuntimeOnly تنها در طول زمان اجرای تست ها در دسترس هستند و نه در زمان کامپایل.


پروژه ها و وظایف (Projects and tasks) در Gradle

هر Gradle build شامل یک یا چند پروژه است. هر پروژه شامل مجموعه ای از وظایف است. هر وظیفه نشان دهنده یک قطعه کار است که یک build انجام می دهد به عنوان مثال تولید JavaDoc، انتشار برخی آرشیوها در یک مخزن و غیره.

build.gradle example
build.gradle example

مخزن Gradle (Gradle repository):

نام مستعار (aliases) در Gradle برای اضافه کردن مخازن Maven به build پروژه ما استفاده می شود.این اسامی مستعار به شرح زیر است:

  • ـ mavenCentral(): این نام مستعار مخفف وابستگی هایی است که از مخزن مرکزی Maven 2 (central Maven 2 repository) استخراج می شوند.
  • ـ jcenter(): این نام مستعار مخفف وابستگی هایی است که از مخزن JCenter Maven Bintray استخراج می شوند.
  • ـ mavenLocal(): این نام مستعار مخفف وابستگی هایی است که از مخزن محلی Maven (local Maven repository) استخراج می شوند.
build.gradle
build.gradle


مزایا:

1) وابستگی های گذرا را به خوبی کنترل می کند. اگر یک وابستگی انتقالی متناقض در پروژه وجود داشته باشد، برای حل آن، آخرین نسخه وابستگی را انتخاب می کند. برای مثال، وابستگی "A" به صورت داخلی نیازمند وابستگی "C" با نسخه ۲.۰ و وابستگی "B" به صورت داخلی نیازمند وابستگی "C" با نسخه ۳.۰ است. سپس Gradle از آخرین نسخه وابستگی "C" استفاده می کند.

2) فایل های پیکربندی Gradle از نظر اندازه کوچک تر و تمیزتر هستند چرا که به جای XML از زبان مخصوص دامنه Groovy استفاده می کند.

3) ـ Gradle از مفهوم ساخت افزایشی (incremental build concept) استفاده می کند و با ردیابی ورودی و خروجی وظایف و تنها اجرای آنچه ضروری است، از کار جلوگیری می کند و تنها فایل هایی را پردازش می کند که در صورت امکان تغییر کرده اند و در نتیجه، سریع تر از maven عمل می کنند.


نتیجه گیری

در این مقاله سه ابزار اتوماسیون ساخت جاوا با نام های Ant، Maven و Gradle را معرفی کردیم.

جای تعجب نیست که Maven امروزه اکثر بازار build tool را در اختیار دارد.

با این حال، Gradle به دلایل زیر شاهد پذیرش خوبی در codebase های پیچیده تر بوده است:

  • بسیاری از پروژه های متن باز مانند Spring در حال حاضر از آن استفاده می کنند.
  • به لطف builds افزایشی (incremental builds) خود در اکثر سناریوها از Maven سریع تر است.
  • خدمات تجزیه و تحلیل و عیب یابی پیشرفته ای را ارائه می دهد.

با این حال به نظر می رسد که Gradle منحنی یادگیری تندتری دارد، به خصوص اگر با Groovy یا Kotlin آشنا نباشید.


منبع

https://medium.com/@257ramanrb/ant-vs-maven-vs-gradle-cd8ab4c2735f


antmavengradlejavakotlin
A passionate Android Developer
شاید از این پست‌ها خوشتان بیاید