Skip to content

3. الأدوات المستخدمة في هذا المستند

تم اختبار الأمثلة الواردة في هذا المستند باستخدام الأدوات التالية:

  • إصدارات NetBeans من 6.8 إلى 7.1.2. يرد وصف تثبيت NetBeans في [المرجع 3] في القسم 1.3.1.
  • WampServer الإصدار 2.2. يرد وصف تثبيت WampServer في [المرجع 3] في القسم 1.3.3؛
  • Maven مدمج في NetBeans. سنقوم الآن بوصف هذه الأداة.

3.1. Maven

3.1.1. مقدمة

Maven متاح على الرابط [http://maven.apache.org/index.html ]. وفقًا لمطوريه:

الهدف الأساسي لـ Maven هو تمكين المطور من فهم الحالة الكاملة لعملية التطوير في أقصر وقت ممكن. لتحقيق هذا الهدف، هناك عدة مجالات رئيسية يعالجها Maven:

  • تسهيل عملية البناء
  • توفير نظام بناء موحد
  • توفير معلومات عالية الجودة عن المشروع
  • توفير إرشادات لأفضل الممارسات في مجال التطوير
  • تمكين الانتقال السلس إلى الميزات الجديدة

تم دمج Maven في NetBeans، وسنستخدمه لواحدة فقط من ميزاته: إدارة مكتبات المشروع. تتكون هذه المكتبات من جميع ملفات JAR التي يجب أن تكون موجودة في مسار فئات المشروع. وقد يكون عددها كبيرًا. على سبيل المثال، ستستخدم مشاريعنا المستقبلية Hibernate ORM (Object-Relational Mapper). يتكون هذا ORM من عشرات ملفات JAR. وتتمثل ميزة Maven في أنها تحررنا من الحاجة إلى معرفتها جميعًا. نحتاج ببساطة إلى تحديد في مشروعنا أننا بحاجة إلى Hibernate من خلال توفير جميع المعلومات اللازمة لتحديد موقع ملف JAR الرئيسي لهذا ORM. ثم يقوم Maven أيضًا بتنزيل جميع المكتبات المطلوبة من قبل Hibernate. وتسمى هذه التبعيات Hibernate. قد تعتمد المكتبة المطلوبة من قبل Hibernate نفسها على أرشيفات أخرى. وسيتم تنزيل هذه أيضًا. يتم وضع جميع هذه المكتبات في مجلد يسمى مستودع Maven المحلي.

يمكن مشاركة مشروع Maven بسهولة. إذا قمت بنقله من جهاز كمبيوتر إلى آخر ولم تكن تبعيات المشروع موجودة في المستودع المحلي للجهاز الجديد، فسيتم تنزيلها.

يمكن استخدام Maven بمفرده أو دمجه في بيئة تطوير متكاملة (IDE) مثل NetBeans أو Eclipse.

لنقم بإنشاء مشروع Maven في NetBeans:

  • في [1]، أنشئ مشروعًا جديدًا،
  • في [2]، حدد فئة [Maven] ونوع المشروع [Java Application
  • في [3]، حدد الدليل الأصلي للمشروع الجديد،
  • في [4]، قم بتسمية المشروع،
  • في [5]، المشروع الذي تم إنشاؤه.

دعونا نستعرض مكونات المشروع ونشرح دور كل منها.

  • في [1]: الفروع المختلفة للمشروع:
    • [حزم المصدر]: فئات Java الخاصة بالمشروع؛
    • [حزم الاختبار]: فئات الاختبار الخاصة بالمشروع؛
    • [التبعيات]: أرشيفات .jar التي يتطلبها المشروع وتديرها Maven؛
    • [التبعيات الاختبارية]: ملفات .jar المطلوبة لاختبارات المشروع والتي يديرها Maven؛
    • [تبعيات Java]: ملفات .jar التي يتطلبها المشروع ولا يديرها Maven؛
    • [ملفات المشروع]: ملفات تكوين Maven و NetBeans،
  • في [3]، فرع [حزم المصدر]،

يحتوي هذا الفرع على شفرة المصدر لفئات Java الخاصة بالمشروع. قام NetBeans بإنشاء فئة افتراضية:


package istia.st.mvexemple;
 
/**
 * Hello world!
 * 
 */
public class App {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
  • في [4]، فرع [Test Packages]، الذي يحتوي على شفرة المصدر لفئات الاختبار الخاصة بالمشروع،
  • في [5]، مكتبة JUnit 3.8 المطلوبة لتشغيل الاختبارات،

قام NetBeans بإنشاء فئة افتراضية:


package istia.st.mvexemple;
 
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
 
/**
 * Unit test for simple App.
 */
public class AppTest extends TestCase {
    /**
     * Create the test case
     * 
     * @param testName
     *          name of the test case
     */
    public AppTest(String testName) {
        super(testName);
    }
 
    /**
     * @return the suite of tests being tested
     */
    public static Test suite() {
        return new TestSuite(AppTest.class);
    }
 
    /**
     * Rigourous Test :-)
     */
    public void testApp() {
        assertTrue(true);
    }
}

هذا اختبار JUnit 3.8. سنستخدم اختبارات JUnit 4.x لاحقًا.

  • في [6]، قسم [التبعيات] فارغ هنا،

يعرض هذا القسم جميع المكتبات التي يتطلبها المشروع وتديرها Maven. يتم تنزيل جميع المكتبات المدرجة هنا تلقائيًا بواسطة Maven. لهذا السبب يتطلب مشروع Maven اتصالاً بالإنترنت. سيتم تخزين المكتبات التي تم تنزيلها محليًا. إذا احتاج مشروع آخر إلى مكتبة موجودة بالفعل محليًا، فلن يتم تنزيلها. سنرى أن قائمة المكتبات هذه، بالإضافة إلى المستودعات التي يمكن العثور عليها فيها، محددة في ملف تكوين مشروع Maven.

  • في [7]، المكتبات التي يتطلبها المشروع ولكن لا يديرها Maven،
  • في [7]، ملف التكوين [pom.xml] لمشروع Maven. ويُشار إلى POM باختصار لـ Project Object Model. وسنحتاج إلى تعديل هذا الملف مباشرةً.

فيما يلي ملف [pom.xml] الذي تم إنشاؤه:


<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>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
  • تحدد الأسطر من 5 إلى 8 عنصر Java الذي سيتم إنشاؤه بواسطة مشروع Maven. تأتي هذه المعلومات من المعالج المستخدم عند إنشاء المشروع:

يتم تعريف عنصر Maven من خلال أربع خصائص:

  • [groupId]: معلومات تشبه اسم الحزمة. على سبيل المثال، مكتبات إطار عمل Spring لها groupId=org.springframework، بينما مكتبات إطار عمل JSF لها groupId=javax.faces،
  • [artifactId]: اسم عنصر Maven. في مجموعة [org.springframework]، نجد معرفات العناصر التالية: spring-context، spring-core، spring-beans، ... وفي مجموعة [javax.faces]، نجد معرف العنصر jsf-api،
  • [version]: رقم إصدار عنصر Maven. وبالتالي، فإن العنصر org.springframework.spring-core له الإصدارات التالية: 2.5.4، 2.5.5، 2.5.6، 2.5.6.SECO1، ...
  • [packaging]: تنسيق الأرتيفاكت، وغالبًا ما يكون war أو jar.

سيقوم مشروع Maven الخاص بنا بإنشاء ملف [jar] (السطر 8) في المجموعة [istia.st] (السطر 5)، باسم [mv-example] (السطر 6) وبإصدار [1.0-SNAPSHOT] (السطر 7). يجب أن تحدد هذه المعلومات الأربع بشكل فريد عنصر Maven.

تسرد الأسطر 17–24 تبعيات مشروع Maven، أي قائمة المكتبات التي يتطلبها المشروع. يتم تعريف كل مكتبة من خلال المعلومات الأربع (groupId، artifactId، version، packaging). عندما تكون معلومات التعبئة والتغليف مفقودة، كما هو الحال هنا، يتم استخدام تعبئة jar. يتم إضافة معلومة أخرى: scope، والتي تحدد المراحل التي تحتاج فيها المكتبة في دورة حياة المشروع. القيمة الافتراضية هي compile، والتي تشير إلى أن المكتبة مطلوبة للتجميع والتنفيذ. القيمة test تعني أن المكتبة مطلوبة أثناء اختبار المشروع. هذا هو الحال هنا مع مكتبة JUnit 3.8.1. إذا لم تكن هذه المكتبة موجودة في المستودع المحلي على الجهاز، يتم تنزيلها.

3.1.2. تشغيل المشروع

نقوم بتشغيل المشروع:

في [1]، يتم إنشاء مشروع Maven ثم تنفيذه [1]. فيما يلي السجلات الموجودة في وحدة التحكم NetBeans:

Scanning for projects...
...

------------------------------------------------------------------------
Building mv-exemple 1.0-SNAPSHOT
------------------------------------------------------------------------

[resources:resources]
[debug] execute contextualize
Using 'UTF-8' encoding to copy filtered resources.
skip non existing resourceDirectory D:\data\istia-1112\netbeans\glassfish\mv-pam\00\mv-exemple\src\main\resources

[compiler:compile]
Compiling 1 source file to D:\data\istia-1112\netbeans\glassfish\mv-pam\00\mv-exemple\target\classes

[exec:exec]
Downloading: http://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.0.1/commons-exec-1.0.1.pom

Downloaded: http://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.0.1/commons-exec-1.0.1.pom (8 KB at 113.5 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.0.1/commons-exec-1.0.1.jar

Downloaded: http://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.0.1/commons-exec-1.0.1.jar (49 KB at 763.6 KB/sec)
Hello World!
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 4.040s
Finished at: Thu Jun 21 10:10:40 CEST 2012
Final Memory: 13M/122M

والنتيجة هي السطر 23. يمكننا أن نرى أنه حتى في هذه الحالة البسيطة، قام Maven بتنزيل بعض التبعيات (السطران 17 و20).

3.1.3. نظام الملفات لمشروع Maven

  • [1]: يوجد نظام ملفات المشروع في علامة التبويب [Files
  • [2]: توجد مصادر Java في المجلد [src/main/java
  • [3]: توجد مصادر اختبار Java في المجلد [src/test/java
  • [4]: تم إنشاء المجلد [target] بواسطة عملية بناء المشروع،
  • [5]: هنا، أنشأ بناء المشروع أرشيفًا [mv-example-1.0-SNAPSHOT.jar].

3.1.4. مستودع Maven المحلي

ذكرنا أن Maven يقوم بتنزيل التبعيات المطلوبة للمشروع وتخزينها محليًا. يمكنك استكشاف هذا المستودع المحلي:

  • في [1]، حدد الخيار [Window / Other / Maven Repository Browser
  • في [2]، تفتح علامة تبويب [Maven Repositories
  • في [3]، تحتوي على فرعين، أحدهما للمستودع المحلي والآخر للمستودع المركزي. هذا الأخير ضخم. لعرض محتوياته، يجب تحديث فهرسه [4]. يستغرق هذا التحديث عدة عشرات من الدقائق.
  • في [5]، المكتبات الموجودة في المستودع المحلي،
  • في [6]، ستجد فرعًا [istia.st] يتوافق مع [groupId] لمشروعنا،
  • في [7]، يمكنك الوصول إلى خصائص المستودع المحلي،
  • في [8]، ترى المسار إلى المستودع المحلي. من المفيد معرفة ذلك لأنه في بعض الأحيان (نادرًا) لا يستخدم Maven أحدث إصدار من المشروع. تقوم بإجراء تغييرات وتلاحظ أنها لا يتم تطبيقها. يمكنك بعد ذلك حذف الفرع يدويًا في المستودع المحلي المطابق لـ [groupId] الخاص بك. هذا يجبر Maven على إعادة إنشاء الفرع من أحدث إصدار من المشروع.

3.1.5. البحث عن أداة باستخدام Maven

الآن دعونا نتعلم كيفية البحث عن أداة باستخدام Maven. لنبدأ بقائمة التبعيات الحالية في ملف [pom.xml]:


<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>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

تحدد الأسطر 17–23 التبعيات التي سنقوم بتعديلها لاستخدام أحدث إصدارات المكتبات.

أولاً، نزيل التبعيات الحالية [1]. ثم يتم تعديل ملف [pom.xml]:


<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>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
 
  <dependencies></dependencies>
</project>

السطر 17: لم تعد التبعية التي تمت إزالتها تظهر في [pom.xml]. والآن، دعونا نبحث عنها في مستودعات Maven.

  • في [1]، نضيف تبعية إلى المشروع؛
  • في [2]، يجب تحديد معلومات حول الأداة التي نبحث عنها (groupId، artifactId، version، packaging (Type)، و scope). نبدأ بتحديد [groupId] [3]،
  • في [4]، نضغط على [مسافة] لعرض قائمة العناصر المحتملة. هنا، [junit] و [jnit-dep]. نختار [junit
  • في [5]، باتباع نفس الإجراء، نختار أحدث إصدار. نوع التعبئة هو jar،
  • في [6]، نختار نطاق الاختبار للإشارة إلى أن التبعية مطلوبة للاختبار فقط.

في [6]، تظهر التبعيات المضافة في المشروع. يعكس ملف [pom.xml] هذه التغييرات:


<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>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
      <type>jar</type>
    </dependency>
  </dependencies>
</project>

لاحظ أن ملف [pom.xml] لا يذكر التبعية [hamcrest-core-1.1] الموضحة في [6]. وذلك لأنها تبعية لـ JUnit 4.10 وليست للمشروع نفسه. ويُشار إلى ذلك برمز مختلف في فرع [Dependencies]. وقد تم تنزيلها تلقائيًا.

الآن لنفترض أننا لا نعرف [groupId] للمنتج الذي نريده. على سبيل المثال، نريد استخدام Hibernate كـ ORM (Object Relational Mapper)، وهذا كل ما نعرفه. يمكننا عندئذ الانتقال إلى الموقع [http://mvnrepository.com/]:

في [1]، يمكنك إدخال كلمات رئيسية. اكتب hibernate وقم بتشغيل البحث.

  • في [2]، حدد [groupId] org.hibernate و[artifactId] hibernate-core،
  • في [3]، حدد الإصدار 4.1.2-Final،
  • في [4]، نحصل على كود Maven لنلصقه في ملف [pom.xml]. لنفعل ذلك.

<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>istia.st</groupId>
  <artifactId>mv-exemple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>mv-exemple</name>
  <url>http://maven.apache.org</url>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>4.1.2.Final</version>
    </dependency>
  </dependencies>
</project>

نحفظ ملف [pom.xml]. ثم يقوم Maven بتنزيل التبعيات الجديدة. يتطور المشروع على النحو التالي:

  • في [5]، التبعية [hibernate-core-4.1.2-Final]. في المستودع الذي تم العثور عليه فيه، يتم وصف هذا [artifactId] أيضًا بواسطة ملف [pom.xml]. تمت قراءة هذا الملف، واكتشف Maven أن [artifactId] يحتوي على تبعية. يقوم بتنزيلها أيضًا. وسيقوم بذلك لكل [artifactId] تم تنزيله. في النهاية، نجد في [6] تبعيات لم نطلبها مباشرة. يتم الإشارة إليها برمز مختلف عن رمز [artifactId] الرئيسي.

في هذا المستند، نستخدم Maven بشكل أساسي لهذه الميزة. هذا يوفر علينا الحاجة إلى معرفة جميع التبعيات الخاصة بالمكتبة التي نريد استخدامها. نترك Maven يديرها. علاوة على ذلك، من خلال مشاركة ملف [pom.xml] بين المطورين، نضمن أن كل مطور يستخدم بالفعل نفس المكتبات.

في الأمثلة التالية، سنقدم ببساطة ملف [pom.xml] المستخدم. لا يحتاج القارئ سوى استخدامه لتكرار الشروط الموضحة في الوثيقة. علاوة على ذلك، تدعم بيئات تطوير Java الرئيسية (Eclipse، NetBeans، IntelliJ، JDeveloper) مشاريع Maven. وبالتالي، يمكن للقارئ استخدام بيئة التطوير المفضلة لديه لاختبار الأمثلة.