3. Narzędzia wykorzystane w dokumencie
Przykłady zawarte w niniejszym dokumencie zostały przetestowane przy użyciu następujących narzędzi:
- NetBeans w wersjach od 6.8 do 7.1.2. Instalacja NetBeans została opisana w [ref3] w punkcie 1.3.1.
- Wampserver w wersji 2.2. Instalacja WampServer została opisana w dokumencie [ref3] w punkcie 1.3.3;
- Maven jest zintegrowany z NetBeans. Poniżej opisujemy to narzędzie.
3.1. Maven
3.1.1. Wprowadzenie
Maven jest dostępny w URL [http://maven.apache.org/index.html ]. Według jego twórców:
Głównym celem Mavena jest umożliwienie programistom zrozumienia pełnego stanu projektu w jak najkrótszym czasie. Aby osiągnąć ten cel, Maven zajmuje się kilkoma kluczowymi obszarami:
- Ułatwienie procesu kompilacji
- Zapewnienie jednolitego systemu kompilacji
- Zapewnienie wysokiej jakości informacji o projekcie
- Dostarczanie wytycznych dotyczących najlepszych praktyk programistycznych
- Umożliwienie przejrzystej migracji do nowych funkcji
Maven jest zintegrowany z NetBeans i będziemy go używać wyłącznie w jednym celu: do zarządzania bibliotekami projektu. Biblioteki te składają się z wszystkich archiwów o nazwie jars, które muszą znajdować się w katalogu Classpath projektu. Ich liczba może być bardzo duża. Na przykład nasze przyszłe projekty będą korzystać z biblioteki Hibernate (Object Relational Mapper). Ta biblioteka składa się z dziesiątek archiwów. Zaletą Mavena jest to, że nie musimy znać ich wszystkich. Wystarczy, że w naszym projekcie wskażemy, iż potrzebujemy Hibernate, podając wszystkie informacje niezbędne do znalezienia głównego archiwum tego ORM. Maven pobiera wówczas również wszystkie biblioteki niezbędne dla Hibernate. Nazywa się to zależnościami Hibernate. Biblioteka niezbędna dla Hibernate może sama z kolei zależeć od innych archiwów. Te również zostaną pobrane. Wszystkie te biblioteki są umieszczane w folderze zwanym lokalnym repozytorium Maven.
Projekt Maven można łatwo udostępniać. Jeśli zostanie on przeniesiony z jednego komputera na drugi, a zależności projektu nie znajdują się w lokalnym repozytorium nowego komputera, zostaną one pobrane.
Maven może być używany samodzielnie lub zintegrowany z EDI (zintegrowanym środowiskiem programistycznym), takim jak NetBeans lub Eclipse.
Utwórzmy projekt Maven w NetBeans:
![]() |
- w [1], utwórz nowy projekt,
- w [2] wybierz kategorię [Maven] i typ projektu [Java Application],
![]() |
- w [3], wyznaczyć folder nadrzędny dla folderu nowego projektu,
- w [4] nadać nazwę projektowi,
- w [5] – wygenerowany projekt.
Przyjrzyjmy się elementom projektu i wyjaśnijmy rolę każdego z nich.
![]() |
- w [1]: różne gałęzie projektu:
- [Source packages]: klasy Java projektu;
- [Test packages]: klasy testowe projektu;
- [Dependencies]: archiwa .jar niezbędne dla projektu i zarządzane przez Maven;
- [Test Dependencies]: archiwa .jar niezbędne do testowania projektu i zarządzane przez Maven;
- [Java Dependencies]: archiwa .jar niezbędne dla projektu, ale niezarządzane przez Maven;
- [Project Files]: pliki konfiguracyjne Mavena i NetBeans,
![]() |
- w [3], gałąź [Source Packages],
Ta gałąź zawiera kod źródłowy klas Java projektu. NetBeans wygenerowało domyślną klasę:
package istia.st.mvexemple;
/**
* Hello world!
*
*/
public class App {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
![]() |
- w [4], gałąź [Test Packages], która zawiera kod źródłowy klas testowych projektu,
- w [5], biblioteka JUnit 3.8 niezbędna do przeprowadzenia testów,
NetBeans wygenerował klasę domyślną:
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);
}
}
Jest to test JUnit 3.8. W dalszej części będziemy korzystać z testów JUnit 4.x.
![]() |
- w [6] gałąź [Dependencies] jest tutaj pusta,
Ta gałąź wyświetla wszystkie biblioteki niezbędne dla projektu i zarządzane przez Maven. Wszystkie wymienione tutaj biblioteki są automatycznie pobierane przez Maven. Dlatego projekt Maven wymaga dostępu do Internetu. Pobrane biblioteki będą przechowywane lokalnie. Jeśli inny projekt potrzebuje biblioteki już obecnej lokalnie, nie zostanie ona ponownie pobrana. Zobaczymy, że ta lista bibliotek oraz repozytoria, w których można je znaleźć, są zdefiniowane w pliku konfiguracyjnym projektu Maven.
![]() |
- w [7] biblioteki niezbędne dla projektu, które nie są zarządzane przez Maven,
![]() |
- w [7], plik konfiguracyjny projektu Maven o nazwie [pom.xml]. POM oznacza Project Object Model. Będziemy musieli wprowadzać zmiany bezpośrednio w tym pliku.
Wygenerowany plik [pom.xml] ma następującą treść:
<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>
- Wiersze 5–8 definiują obiekt (artefakt) Java, który zostanie utworzony przez projekt Maven. Informacje te pochodzą z kreatora użytego podczas tworzenia projektu:
![]() |
Obiekt Maven jest definiowany przez cztery właściwości:
- [groupId]: informacja przypominająca nazwę pakietu. Tak więc biblioteki frameworka Spring mają groupId=org.springframework, a biblioteki frameworka JSF mają groupId=javax.faces,
- [artifactId]: nazwa obiektu Maven. W grupie [org.springframework] znajdują się zatem następujące obiekty artifactId: spring-context, spring-core, spring-beans, ... W grupie [javax.faces] znajdują się elementy artifactId i jsf-api,
- [version]: numer wersji artefaktu Maven. Zatem artefakt org.springframework.spring-core ma następujące wersje: 2.5.4, 2.5.5, 2.5.6, 2.5.6.SECO1, ...
- [packaging]: format artefaktu, najczęściej war lub jar.
Nasz projekt Maven wygeneruje plik [jar] (wiersz 8) w grupie [istia.st] (wiersz 5), o nazwie [mv-exemple] (wiersz 6) i wersji [1.0-SNAPSHOT] (wiersz 7). Te cztery informacje muszą jednoznacznie definiować artefakt Maven.
Wiersze 17–24 zawierają listę zależności projektu Maven, czyli listę bibliotek niezbędnych dla projektu. Każda biblioteka jest określona przez cztery elementy (groupId, artifactId, wersja, pakiet). Gdy brakuje informacji packaging, jak w tym przypadku, wykorzystywany jest plik jar o nazwie packaging. Dodaje się jeszcze jedną informację – scope, która określa, w jakich momentach cyklu życia projektu biblioteka jest potrzebna. Wartością domyślną jest „compile”, co oznacza, że biblioteka jest niezbędna do kompilacji i uruchomienia. Wartość „test” oznacza, że biblioteka jest potrzebna podczas testowania projektu. Tak jest w tym przypadku z biblioteką JUnit 3.8.1. Jeśli biblioteka ta nie znajduje się w lokalnym repozytorium komputera, zostanie pobrana.
3.1.2. Uruchomienie projektu
Uruchamiamy projekt:
![]() |
W [1] projekt Maven jest kompilowany, a następnie uruchamiany jako [1]. W konsoli NetBeans pojawiają się następujące logi:
Wynik znajduje się w wierszu 23. Widać, że nawet w tym prostym przypadku Maven pobrał pewne elementy (wiersze 17 i 20).
3.1.3. System plików projektu Maven
![]() |
- [1]: system plików projektu znajduje się w zakładce [Files],
- [2]: kody źródłowe Java znajdują się w folderze [src / main / java],
- [3]: źródła Java testów znajdują się w folderze [src / test / java],
- [4]: folder [target] został utworzony podczas kompilacji projektu,
- [5]: w tym przypadku kompilacja projektu utworzyła archiwum [mv-exemple-1.0-SNAPSHOT.jar].
3.1.4. Lokalne repozytorium Maven
Wspomnieliśmy, że Maven pobiera zależności niezbędne dla projektu i przechowuje je lokalnie. Można przeglądać ten lokalny repozytorium:
![]() |
- w [1] wybieramy opcję [Window / Other / Maven Repository Browser],
- w [2] otwiera się zakładka [Maven Repositories],
- w [3] zawiera dwie gałęzie: jedną dla repozytorium lokalnego, drugą dla repozytorium centralnego. To ostatnie jest ogromne. Aby wyświetlić jego zawartość, należy zaktualizować jego indeks [4]. Aktualizacja ta trwa kilkadziesiąt minut.
![]() |
- w [5], biblioteki z lokalnego repozytorium,
- w [6] znajduje się gałąź [istia.st], która odpowiada [groupId] naszego projektu,
- w [7] uzyskuje się dostęp do właściwości lokalnego repozytorium,
- w [8] mamy ścieżkę do lokalnego repozytorium. Warto ją znać, ponieważ czasami (rzadko) Maven nie korzysta już z najnowszej wersji projektu. Wprowadzamy zmiany i zauważamy, że nie są one uwzględniane. Możemy wtedy ręcznie usunąć gałąź z lokalnego repozytorium odpowiadającą naszemu [groupId]. To zmusza Maven do ponownego utworzenia gałęzi na podstawie najnowszej wersji projektu.
3.1.5. Wyszukiwanie artefaktu za pomocą Mavena
Nauczmy się teraz wyszukiwać artefakt za pomocą Mavena. Zacznijmy od listy aktualnych zależności pliku [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>
Wiersze 17–23 definiują zależności, które zamierzamy zmodyfikować, aby korzystać z najnowszych wersji bibliotek.
![]() |
Najpierw usuwamy obecne zależności [1]. Plik [pom.xml] zostaje wówczas zmodyfikowany:
<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>
W wierszu 17 usunięta zależność nie pojawia się już w pliku [pom.xml]. Teraz poszukajmy jej w repozytoriach Maven.
![]() |
- w pliku [1] dodajemy zależność do projektu,
- w pliku [2] należy podać informacje o poszukiwanym artefakcie (groupId, artifactId, wersja, opakowanie (typ) i zakres). Zaczynamy od określenia [groupId] [3],
- w polu [4] wpisujemy [espace], aby wyświetlić listę możliwych artefaktów. W tym przypadku są to [junit] i [jnit-dep]. Wybieramy [junit],
- a w przypadku [5], postępując w ten sam sposób, wybieramy najnowszą wersję. Typ pakietu to jar,
- oraz [6]; wybieramy zakres testowy, aby zaznaczyć, że zależność jest potrzebna wyłącznie do testów.
![]() |
W pliku [6] dodane zależności pojawiają się w projekcie. Plik [pom.xml] odzwierciedla te zmiany:
<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>
Należy zauważyć, że plik [pom.xml] nie zawiera wzmianki o zależności [hamcrest-core-1.1], którą widzimy w pliku [6]. Wynika to z faktu, że jest to zależność pliku JUnit w wersji 4.10, a nie samego projektu. Sygnalizuje to inna ikona w gałęzi [Dependencies]. Została ona pobrana automatycznie.
Załóżmy teraz, że nie znamy numeru [groupId] artefaktu, który nas interesuje. Na przykład chcemy użyć Hibernate jako ORM (mapera obiektowo-relacyjnego) i to wszystko, co wiemy. Możemy wtedy przejść na stronę [http://mvnrepository.com/]:
![]() |
W polu [1] można wpisać słowa kluczowe. Wpiszmy hibernate i uruchommy wyszukiwanie.
![]() |
- w [2] wybierzmy [groupId], org.hibernate oraz [artifactId] i hibernate-core,
- z [3] wybierzmy wersję 4.1.2-Final,
- z [4] otrzymujemy kod Maven, który należy wkleić do pliku [pom.xml]. Robimy to.
<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>
Zapisujemy plik [pom.xml]. Następnie Maven rozpoczyna pobieranie nowych zależności. Projekt zmienia się w następujący sposób:
![]() |
- w [5], zależność [hibernate-core-4.1.2-Final]. W repozytorium, w którym został znaleziony, ten plik [artifactId] jest również opisany przez plik [pom.xml]. Plik ten został odczytany, a Maven wykrył, że plik [artifactId] posiada zależności. Pobiera je również. Czynność tę wykona dla każdego pobranego pliku [artifactId]. W rezultacie w pliku [6] znajdują się zależności, o które nie prosiliśmy bezpośrednio. Są one oznaczone ikoną inną niż ta w głównym pliku [artifactId].
W niniejszym dokumencie wykorzystujemy Maven głównie ze względu na tę cechę. Dzięki temu nie musimy znać wszystkich zależności biblioteki, z której chcemy skorzystać. Zarządzaniem nimi zajmuje się Maven. Ponadto, udostępniając plik [pom.xml] między programistami, mamy pewność, że każdy z nich korzysta z tych samych bibliotek.
W poniższych przykładach ograniczymy się do podania wykorzystywanego pliku [pom.xml]. Wystarczy, że czytelnik z niego skorzysta, aby znaleźć się w takich samych warunkach jak w dokumencie. Ponadto projekty Maven są rozpoznawane przez główne środowiska programistyczne Java (Eclipse, NetBeans, IntelliJ, JDeveloper). Dzięki temu czytelnik będzie mógł użyć swojego ulubionego środowiska programistycznego do przetestowania przykładów.


















