ملف pom.xml

6 دقيقة

جدول المحتويات


1 — ملف pom.xml، قلب المشروع

pom.xml (Project Object Model) الملف المركزي لكل مشروع Maven. وثيقة XML تصف المشروع: هويته، تبعياته، خصائصه، وطريقة بنائه.

يبدأ كل pom.xml بجذر <project> مع مساحة أسمائه، ويصرّح إلزامياً بإصدار النموذج :

xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <!-- بقية الإعداد هنا -->

</project>

<modelVersion>4.0.0</modelVersion> إلزامي ويساوي دائماً 4.0.0 اليوم: هو إصدار صيغة ملف pom.xml، لا إصدار مشروعك.

↑ العودة إلى الأعلى


2 — البنية العامة لـ pom.xml

يُقرأ pom.xml من الأعلى إلى الأسفل، بكتل كبيرة. هذا التنظيم النموذجي :

الكتلةالدور
<modelVersion>إصدار الصيغة (دائماً 4.0.0)
<groupId> / <artifactId> / <version>الإحداثيات (هوية المشروع)
<packaging>نوع الأثر (jar، war، pom)
<properties>متغيرات قابلة لإعادة الاستخدام (إصدارات، ترميز)
<dependencies>المكتبات المستخدمة (الدرس 03)
<build>الإضافات وإعداد البناء

تحدد الكتلة <packaging> نوع المخرج :

القيمةالمنتج
jarمكتبة أو تطبيق Java (الافتراضي)
warتطبيق ويب قابل للنشر على خادم
pomمشروع «أب» بلا شفرة (مجمّع)

إن أغفلت <packaging>، يختار Maven القيمة jar افتراضياً. مرة أخرى: العرف قبل الإعداد.

تمرين مصغّر — اكتب الوسم <packaging> لإنتاج تطبيق ويب قابل للنشر على Tomcat.

عرض الحل
xml
<packaging>war</packaging>

↑ العودة إلى الأعلى


3 — إحداثيات المشروع (GAV)

يُعرَّف كل مشروع Maven تعريفاً فريداً بثلاثة إحداثيات، تُختصر غالباً GAV: GroupId, ArtifactId, Version.

xml
<groupId>com.exemple</groupId>
<artifactId>mon-app</artifactId>
<version>1.0.0</version>
الإحداثيالمعنىالعرف
groupIdالمنظمة / المشروعاسم نطاق معكوس: com.exemple
artifactIdاسم الوحدةقصير، بأحرف صغيرة: mon-app
versionالإصدار الحاليرقمي: 1.0.0، أو 1.0.0-SNAPSHOT

تستحق اللاحقة -SNAPSHOT انتباهاً خاصاً :

الإصدارالمعنى
1.0.0-SNAPSHOTإصدار قيد التطوير، غير مستقر، يُحدَّث كثيراً
1.0.0إصدار منشور (release)، ثابت وغير قابل للتغيير
bash
# اسم الأثر المنتج يجمع artifactId + version
# مثال: mon-app-1.0.0-SNAPSHOT.jar
mvn package

التوليفة groupId:artifactId:version هي «العنوان البريدي» لمشروعك في منظومة Maven. هكذا يمكن لمشاريع أخرى الاعتماد عليه.

تمرين مصغّر — اكتب وسوم GAV الثلاثة لمشروع com.banque اسمه gestion-comptes بإصدار تطوير 1.0.0.

عرض الحل
xml
<groupId>com.banque</groupId>
<artifactId>gestion-comptes</artifactId>
<version>1.0.0-SNAPSHOT</version>

↑ العودة إلى الأعلى


4 — الخصائص

تعرّف الكتلة <properties> متغيرات قابلة لإعادة الاستخدام في كل pom.xml. نمركز فيها الإصدارات والإعدادات لتجنّب التكرار.

xml
<properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <junit.version>5.10.2</junit.version>
</properties>

نعيد استخدام خاصية لاحقاً بصيغة ${nom} :

xml
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>${junit.version}</version>   <!-- يعيد استخدام الخاصية -->
    <scope>test</scope>
</dependency>

خصائص شائعة :

الخاصيةالدور
maven.compiler.source / targetإصدار Java لشفرة المصدر وللـ bytecode
project.build.sourceEncodingترميز الملفات (دائماً UTF-8)
خصائص مخصَّصة (junit.version…)مركزة أرقام الإصدارات

مركزة الإصدارات في <properties> ممارسة جيدة: للانتقال بـ JUnit من 5.10 إلى 5.11، تعدّل مكاناً واحداً بدل كل تبعية.

تمرين مصغّر — عرّف خاصية gson.version قيمتها 2.10.1، ثم بيّن كيف تعيد استخدامها في وسم <version>.

عرض الحل
xml
<properties>
    <gson.version>2.10.1</gson.version>
</properties>
<!-- ... -->
<version>${gson.version}</version>

↑ العودة إلى الأعلى


5 — وراثة الأب

يمكن لـ pom.xml أن يرث من pom.xml آخر عبر الكتلة <parent>. يسترجع الابن حينها خصائص الأب وتبعياته وإعداداته. هذه الآلية تسمح بـ عزل الإعداد المشترك بين عدة وحدات.

xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.5</version>
    <relativePath/>   <!-- فارغ: ابحث عن الأب في المستودع -->
</parent>

الاستخدام الأشهر هو أب Spring Boot، الذي يثبّت إصدارات عشرات المكتبات لتكون متوافقة. بفضله، تصرّح بتبعيات دون تحديد إصدارها :

xml
<!-- بلا <version>: يُورَث من الأب -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
مع وراثة الأببلا وراثة الأب
إصدارات متسقة مضمونةخطر إصدارات غير متوافقة
إعداد مكرَّر أقلإعادة التصريح بكل شيء في كل وحدة

يعمل أب Spring Boot كـ «قائمة مشتريات مصدَّقة»: يضمن أن مكتباتك تتفاهم، دون أن تختار كل رقم إصدار يدوياً.

↑ العودة إلى الأعلى


6 — ملف pom.xml كامل مع تعليقات

هذا pom.xml واقعي يجمع ما سبق: إحداثيات، خصائص، أب اختياري، وتبعيات.

xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">

    <!-- إصدار صيغة الملف -->
    <modelVersion>4.0.0</modelVersion>

    <!-- إحداثيات GAV: هوية المشروع -->
    <groupId>com.exemple</groupId>
    <artifactId>mon-app</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <!-- متغيرات قابلة لإعادة الاستخدام -->
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.10.2</junit.version>
    </properties>

    <!-- المكتبات المستخدمة -->
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

يمكن عرض pom.xml «الفعلي» (مع كل الوراثة محلولة) :

bash
# يعرض الـ pom الكامل، بما فيه الأب
mvn help:effective-pom

الأمر mvn help:effective-pom ثمين لفهم ما «يراه» Maven فعلاً، بما فيه كل ما يأتي من الأب.

تمرين مصغّر — اكتب الأمر الذي يعرض pom.xml الفعلي، مع كل وراثة الأب محلولة.

عرض الحل
bash
mvn help:effective-pom

↑ العودة إلى الأعلى


7 — اختبار — ملف pom.xml

السؤال 1: ماذا تعني إحداثيات GAV الثلاثة؟

a) Group, Action, Value

b) GroupId, ArtifactId, Version

c) Git, Apache, Version

d) General, Application, Version

عرض الحل

الإجابة: b) — GAV = groupId و artifactId و version: الهوية الفريدة للمشروع.


السؤال 2: ماذا تعني اللاحقة -SNAPSHOT في إصدار؟

a) إصدار منشور وثابت

b) إصدار قيد التطوير، غير مستقر ويُحدَّث كثيراً

c) لقطة شاشة للمشروع

d) إصدار مهجور

عرض الحل

الإجابة: b) — تشير -SNAPSHOT إلى إصدار تطوير. إصدار بلا هذه اللاحقة هو release ثابت.


السؤال 3: لماذا تُستخدم الكتلة <properties>؟

a) للتصريح بالتبعيات

b) لتعريف متغيرات قابلة لإعادة الاستخدام (إصدارات، ترميز) بـ ${...}

c) لإعداد خادم الويب

d) لكتابة شفرة Java

عرض الحل

الإجابة: b) — تمركز الخصائص قيماً قابلة لإعادة الاستخدام عبر الصيغة ${nom}، فتجنّب التكرار.


السؤال 4: ما فائدة الوراثة من <parent> مثل spring-boot-starter-parent؟

a) تلغي الحاجة إلى الشفرة

b) تضمن إصدارات مكتبات متسقة وتقلّل الإعداد

c) تسرّع الشبكة

d) تشفّر pom.xml

عرض الحل

الإجابة: b) — يثبّت الأب إصدارات متوافقة؛ يمكن حينها التصريح بتبعيات دون تحديد إصدارها.


السؤال 5: أي قيمة يأخذها <modelVersion> دائماً اليوم؟

a) 1.0.0

b) 3.9.6

c) 4.0.0

d) 17

عرض الحل

الإجابة: c)<modelVersion>4.0.0</modelVersion> إصدار صيغة ملف pom.xml، إلزامي وثابت.

↑ العودة إلى الأعلى


8 — تطبيق عملي — كتابة pom.xml

المطلوب

اكتب من الصفر pom.xml لمشروع هويته com.banque:gestion-comptes:1.0.0-SNAPSHOT، مغلف بـ jar، مجمَّع بـ Java 17 بترميز UTF-8، ويمركز إصدار JUnit في خاصية. ثم تحقّق منه.


التصحيح — pom.xml المتوقَّع

xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.banque</groupId>
    <artifactId>gestion-comptes</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.10.2</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

التحقق :

bash
# يتحقق من صحة الـ pom وقابليته للحل
mvn validate

# يعرض الـ pom الفعلي (الأب والخصائص محلولة)
mvn help:effective-pom

النتيجة المتوقعة :

[INFO] BUILD SUCCESS

إذا عرض mvn validate القيمة BUILD SUCCESS، فملف pom.xml سليم نحوياً وإحداثياته صحيحة. خطأ شائع: نسيان <modelVersion> أو إغلاق وسم XML بشكل سيئ.

↑ العودة إلى الأعلى


9 — الخلاصة

النقاط التي يجب تذكّرها

  1. pom.xml ملف XML يصف الهوية والخصائص والتبعيات والبناء.
  2. إحداثيات GAV (groupId، artifactId، version) تعرّف المشروع تعريفاً فريداً.
  3. -SNAPSHOT = إصدار قيد التطوير؛ بلا لاحقة = إصدار منشور ثابت.
  4. <properties> تمركز متغيرات قابلة لإعادة الاستخدام عبر ${nom}.
  5. وراثة <parent> تعزل الإعداد وتضمن إصدارات متسقة.

ما يلي

الدرس 03 — إدارة التبعيات: التصريح بالمكتبات، وفهم النطاقات، والمستودعات، والحل الانتقالي.

↑ العودة إلى الأعلى


جميع الحقوق محفوظة. يُحظَر نسخ هذه الدورة أو نشرها أو استخدامها أو تكييفها، كلياً أو جزئياً، دون إذن كتابي مسبق من الدكتور هيثم رحومة.

دورة من إعداد الدكتور هيثم رحومة — تطوير ونشر حلول البيانات