| # | القسم |
|---|---|
| 1 | دورة حياة البناء |
| 2 | المراحل الرئيسية |
| 3 | التجميع |
| 4 | الاختبارات (JUnit + Surefire) |
| 5 | التغليف (jar / war) |
| 6 | Install و deploy و clean |
| 7 | اختبار — دورة الحياة والمراحل |
| 8 | تطبيق عملي — اجتياز دورة الحياة |
| 9 | الخلاصة |
ينظّم Maven بناء مشروع في دورة حياة (lifecycle): سلسلة مرتَّبة من المراحل. عندما تطلب مرحلة، ينفّذ Maven كل المراحل السابقة بالترتيب.
هذا أهم مبدأ يُحفَظ :
طلب مرحلة ينفّذ تلقائياً كل ما يسبقها. إذن
mvn packageيطلق أيضاًvalidateوcompileوtest.
لدى Maven في الواقع ثلاث دورات حياة :
| دورة الحياة | الدور |
|---|---|
| default | بناء المشروع (تجميع، اختبار، تغليف…) |
| clean | التنظيف (حذف target/) |
| site | توليد توثيق المشروع |
# تنفيذ مرحلة = تنفيذ الكل حتى تبلغها
mvn package # يطلق validate -> compile -> test -> packageتمرين مصغّر — أي مراحل تُنفَّذ عندما تشغّل mvn package؟ اسردها بالترتيب.
validate → compile → test → package: طلب مرحلة ينفّذ تلقائياً كل ما يسبقها.
تضم دورة الحياة default مراحل كثيرة؛ هذه الأكثر استخداماً يومياً :
| المرحلة | ماذا تفعل |
|---|---|
validate | تتحقق من صحة المشروع ووجود كل المعلومات اللازمة |
compile | تجمّع شفرة المصدر (src/main/java) |
test | تشغّل الاختبارات الوحدية |
package | تغلف الشفرة المجمَّعة (.jar أو .war) |
verify | تطلق اختبارات التكامل وضوابط الجودة |
install | تثبّت الأثر في المستودع المحلي ~/.m2 |
deploy | تنشر الأثر على مستودع بعيد مشترَك |
mvn validate # تحققات أساسية
mvn compile # + التجميع
mvn test # + الاختبارات الوحدية
mvn package # + إنشاء الأثر
mvn verify # + اختبارات التكامل
mvn install # + نسخ إلى ~/.m2
mvn deploy # + نشر بعيدكلما تقدّمنا في القائمة، زاد ما يفعله Maven.
mvn install«السكين السويسري» للتطوير المحلي: يبني الكل ويجعل الأثر متاحاً لمشاريعك الأخرى على الجهاز نفسه.
تحوّل المرحلة compile شفرة Java (src/main/java) إلى bytecode (.class) في target/classes. يتولى ذلك إضافة Compiler، باستخدام javac في JDK.
يُحدَّد إصدار Java بالخصائص التي رأيناها في الدرس 02 :
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties># تجميع الشفرة الرئيسية
mvn compile
# تجميع شفرة الاختبار أيضاً
mvn test-compileتمرين مصغّر — في أي مجلد يُودَع الـ bytecode .class للشفرة الرئيسية بعد mvn compile؟
في target/classes (مثال target/classes/com/exemple/App.class).
| الخاصية | الدور |
|---|---|
maven.compiler.source | إصدار لغة Java المقبول في الشفرة |
maven.compiler.target | إصدار الـ bytecode المولَّد |
النتيجة في target/ :
target/
└── classes/
└── com/exemple/App.class <-- bytecode مجمَّعإذا فشل التجميع (
BUILD FAILURE)، يتوقف Maven فوراً: لا تُنفَّذ المراحل التالية (test،package). نصحّح دائماً أخطاء التجميع أولاً.
تشغّل المرحلة test الاختبارات الوحدية في src/test/java. تطلقها إضافة Surefire، عادة مع إطار JUnit.
اختبار JUnit نموذجي :
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class CalculTest {
@Test
void additionDeDeuxNombres() {
assertEquals(4, 2 + 2);
}
}# تشغيل كل الاختبارات
mvn test
# تشغيل صنف اختبار واحد
mvn test -Dtest=CalculTest
# البناء مع تخطي الاختبارات (يُتجنَّب إلا لحالات محددة)
mvn package -DskipTestsتمرين مصغّر — اكتب أمر Maven الذي يغلف المشروع دون تشغيل الاختبارات.
mvn package -DskipTests| العنصر | الدور |
|---|---|
| JUnit | الإطار الذي يعرّف الاختبارات ويتحقق منها |
| Surefire | إضافة Maven التي تشغّل الاختبارات الوحدية |
| Failsafe | الإضافة التي تشغّل اختبارات التكامل (مرحلة verify) |
إذا فشل اختبار واحد، يفشل البناء كله (
BUILD FAILURE) ولا يُنتَجpackage. هذا مقصود: لا نسلّم أثراً لا تنجح اختباراته. تخطي الاختبارات بـ-DskipTestsيجب أن يبقى استثناء.
تجمع المرحلة package الشفرة المجمَّعة في أثر قابل للتسليم، يُودَع في target/. يعتمد نوع الأثر على الوسم <packaging> في pom.xml.
| التغليف | الأثر | الاستخدام |
|---|---|---|
jar | .jar | مكتبة أو تطبيق Java مستقل |
war | .war | تطبيق ويب يُنشَر على خادم (Tomcat…) |
pom | (لا شيء) | مشروع أب/مجمّع، بلا شفرة |
<!-- اختيار نوع الأثر -->
<packaging>jar</packaging># إنتاج الأثر
mvn package
# تحديد النتيجة
ls target/النتيجة :
target/
├── classes/
├── mon-app-1.0.0-SNAPSHOT.jar <-- الأثر القابل للتسليم
└── ...يتبع اسم الأثر النمط
artifactId-version.packaging. مثال:mon-app-1.0.0-SNAPSHOT.jar. هذا الملف الذي توزّعه أو تنشره.
بعد package، تكمل ثلاث عمليات دورة الحياة.
| الأمر | الأثر |
|---|---|
mvn install | يبني + ينسخ الأثر إلى ~/.m2 (قابل لإعادة الاستخدام محلياً) |
mvn deploy | يبني + ينشر الأثر على مستودع بعيد (Nexus/Artifactory) |
mvn clean | يحذف المجلد target/ (يبدأ من الصفر) |
التوليفة clean install من الأكثر شيوعاً: تضمن بناءً نظيفاً تماماً.
# البدء من الصفر والبناء حتى التثبيت المحلي
mvn clean install
# البناء والنشر على المستودع البعيد للفريق
mvn clean deploy| المرحلة | من يحتاجها؟ |
|---|---|
install | مطوّر يريد إعادة استخدام الأثر في مشروع محلي آخر |
deploy | فريق / CI ينشر إصداراً للجميع |
clean | أي شخص يريد تجنّب بقايا بناء سابق |
mvn clean installالمنعكس عندما «لم يعد يعمل بلا سبب»: يحذفcleanملفات مجمَّعة قديمة محتملة فيtarget/.
تمرين مصغّر — اكتب الأمر الذي يبدأ من target/ نظيف ثم يثبّت الأثر في المستودع المحلي ~/.m2.
mvn clean installالسؤال 1: ماذا يحدث عندما تشغّل mvn package؟
a) تُنفَّذ مرحلة package وحدها
b) ينفّذ Maven أيضاً كل المراحل السابقة (validate، compile، test)
c) ينشر Maven الأثر على مستودع بعيد
d) يحذف Maven المجلد target/
الإجابة: b) — طلب مرحلة ينفّذ كل المراحل السابقة بالترتيب: validate → compile → test → package.
السؤال 2: أي إضافة Maven تشغّل الاختبارات الوحدية؟
a) Compiler
b) Surefire
c) Shade
d) Jar
الإجابة: b) — إضافة Surefire تشغّل الاختبارات الوحدية (مع JUnit) أثناء المرحلة test.
السؤال 3: ماذا تفعل المرحلة install؟
a) تثبّت Maven على الجهاز
b) تنسخ الأثر إلى المستودع المحلي ~/.m2
c) تنشر على Maven Central
d) تحذف target/
الإجابة: b) — تنسخ install الأثر إلى ~/.m2، فيصبح قابلاً لإعادة الاستخدام من مشاريع محلية أخرى.
السؤال 4: أي وسم يحدد إن كان المشروع ينتج .jar أو .war؟
a) <scope>
b) <version>
c) <packaging>
d) <artifactId>
الإجابة: c) — <packaging>jar</packaging> أو <packaging>war</packaging> يثبّت نوع الأثر الذي تنتجه package.
السؤال 5: ماذا يحدث أثناء mvn package إذا فشل اختبار وحدي؟
a) يُنتَج الأثر رغم ذلك
b) يفشل البناء (BUILD FAILURE) ولا يُنتَج الأثر
c) يتجاهل Maven الاختبار
d) ينتقل Maven مباشرة إلى deploy
الإجابة: b) — اختبار فاشل يوقف البناء؛ لا يُنشأ package. هذا مقصود: لا نسلّم أثراً تفشل اختباراته.
على مشروع Maven، اجتز دورة الحياة خطوة بخطوة: نظّف، جمّع، اختبر، غلّف، ثم ثبّت محلياً. راقب في كل خطوة ما ينتجه Maven في target/.
# 1. البدء من الصفر: يحذف target/
mvn clean
# 2. التجميع: ينتج target/classes
mvn compile
ls target/classes # bytecode .class موجود
# 3. الاختبار: Surefire يشغّل اختبارات JUnit
mvn test
# 4. التغليف: ينتج .jar في target/
mvn package
ls target/*.jar # mon-app-1.0.0-SNAPSHOT.jar
# 5. التثبيت في المستودع المحلي ~/.m2
mvn install
# الصيغة المختصرة الأكثر شيوعاً:
mvn clean installالنتيجة المتوقعة :
[INFO] --- compiler:compile --- (target/classes créé)
[INFO] --- surefire:test --- Tests run: 1, Failures: 0, Errors: 0
[INFO] --- jar:jar --- Building jar: target/mon-app-1.0.0-SNAPSHOT.jar
[INFO] --- install:install --- Installing ... to ~/.m2/repository/...
[INFO] BUILD SUCCESSلاحظ ترتيب أسطر
[INFO]:compileثمtestثمjarثمinstall. هذا الدليل الظاهر على أن Maven يسلسل المراحل تلقائياً بترتيب دورة الحياة.
validate → compile → test → package → verify → install → deploy.compile (إضافة Compiler) تنتج الـ bytecode في target/classes.test (إضافة Surefire + JUnit) تشغّل الاختبارات؛ الفشل يوقف البناء.package تنشئ .jar/.war؛ install تنسخه إلى ~/.m2؛ clean يفرغ target/.تتقن الآن Maven: البنية، و pom.xml، والتبعيات، ودورة الحياة. الوحدة 04 تتناول التحوية بـ Docker، حيث ستغلف هذه الآثار Maven في صور قابلة للنقل.
جميع الحقوق محفوظة. يُحظَر نسخ هذه الدورة أو نشرها أو استخدامها أو تكييفها، كلياً أو جزئياً، دون إذن كتابي مسبق من الدكتور هيثم رحومة.
دورة من إعداد الدكتور هيثم رحومة — تطوير ونشر حلول البيانات