Skip to content

3. Інструменти, описані в документі

Приклади з цього документа було протестовано за допомогою таких інструментів:

  • NetBeans від версії 6.8 до версії 7.1.2. Процес встановлення NetBeans описано в [ref3] у розділі 1.3.1.
  • Wampserver версії 2.2. Встановлення WampServer описано в [ref3] у розділі 1.3.3;
  • Maven інтегровано в NetBeans. Тепер ми опишемо цей інструмент.

3.1. Maven

3.1.1. Вступ

Maven доступний у URL [http://maven.apache.org/index.html ]. За словами його творців:

Головною метою Maven є надання розробнику можливості в найкоротший термін отримати повне уявлення про стан розробки. Для досягнення цієї мети Maven намагається вирішити кілька ключових завдань:

  • Спрощення процесу збірки
  • Забезпечення уніфікованої системи збірки
  • Надання якісної інформації про проєкт
  • Надання рекомендацій щодо найкращих практик розробки
  • Забезпечення прозорого переходу на нові функції

Maven інтегрований у NetBeans, і ми будемо використовувати його лише для однієї його функції: управління бібліотеками проекту. Вони складаються з набору архівів jars, які мають знаходитися в папці Classpath проекту. Їх може бути дуже багато. Наприклад, у наших майбутніх проєктах буде використовуватися ORM (об’єктно-реляційний мапер) Hibernate. Цей ORM складається з десятків архівів jar. Перевага Maven полягає в тому, що він звільняє нас від необхідності знати їх усі. Нам достатньо вказати в нашому проєкті, що нам потрібен Hibernate, надавши всю необхідну інформацію для пошуку головного архіву цього ORM. Тоді Maven також завантажує всі бібліотеки, необхідні для Hibernate. Це називається залежностями Hibernate. Бібліотека, необхідна для Hibernate, сама може залежати від інших архівів. Вони також будуть завантажені. Усі ці бібліотеки розміщуються в папці, яка називається локальним репозиторієм Maven.

Проєктом Maven легко ділитися. Якщо його перенести з одного комп’ютера на інший, а залежності проєкту відсутні в локальному сховищі нового комп’ютера, їх буде завантажено.

Maven можна використовувати окремо або інтегрувати в ІДС (Інтегроване середовище розробки), таке як NetBeans або Eclipse.

Створимо проект Maven у NetBeans:

  • у [1] створіть новий проєкт,
  • у [2] виберіть категорію [Maven] та тип проєкту [Java Application],
  • у [3], вкажіть батьківську папку для папки нового проєкту,
  • у [4] вкажіть назву проекту,
  • у [5] — згенерований проект.

Розглянемо елементи проекту та пояснимо роль кожного з них.

  • у [1]: різні гілки проєкту:
    • [Source packages]: класи Java проекту;
    • [Test packages]: тестові класи проекту;
    • [Dependencies]: архіви .jar, необхідні для проекту та керовані Maven;
    • [Test Dependencies]: архіви .jar, необхідні для тестування проекту та керовані Maven;
    • [Java Dependencies]: архіви .jar, необхідні для проекту та не керовані Maven;
    • [Project Files]: файли конфігурації Maven та NetBeans,
  • у [3], гілка [Source Packages],

Ця гілка містить вихідний код 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] гілка [Dependencies] тут порожня,

Ця гілка відображає всі бібліотеки, необхідні для проєкту та керовані 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] містяться такі artifactId: spring-context, spring-core, spring-beans, ... У групі [javax.faces] містяться artifactId та 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-exemple] (рядок 6) та версію [1.0-SNAPSHOT] (рядок 7). Ці чотири елементи повинні однозначно визначати артефакт Maven.

У рядках 17–24 наведено перелік залежностей проекту Maven, тобто список бібліотек, необхідних для проекту. Кожна бібліотека визначається чотирма параметрами (groupId, artifactId, версія, тип упаковки). Коли інформація packaging відсутня, як у цьому випадку, використовується файл jar packaging. Додається ще один параметр — 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 при 113,5 KB/сек)
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 при 763,6 KB/сек)
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] створюється під час збірки (build) проєкту,
  • [5]: тут у процесі побудови проекту було створено архів [mv-exemple-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, версія, тип упаковки (Type) та область застосування (scope)). Спочатку вказуємо [groupId] [3],
  • у полі [4] вводимо [espace], щоб відобразити список можливих артефактів. Тут це [junit] та [jnit-dep]. Вибираємо [junit],
  • у [5], діючи таким самим чином, обираємо найновішу версію. Тип пакета — jar,
  • та [6]; ми обираємо область застосування «test», щоб вказати, що ця залежність потрібна лише для тестування.

У [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 (об’єктно-реляційний мапер), і це все, що ми знаємо. Тоді можна перейти на сайт [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]. Читачеві достатньо буде скористатися ним, щоб опинитися в тих самих умовах, що й у документі. Крім того, проекти Maven підтримуються основними середовищами розробки Java (Eclipse, NetBeans, IntelliJ, JDeveloper). Тож читач зможе використовувати свій улюблений IDE для тестування прикладів.