#07.1 – Maven i eclipse

By 24 stycznia 2015Kurs Javy
Wpis-Header lekcje (1)

We wcześniejszych lekcjach poznaliśmy Mavena jako narzędzie, dzisiaj dowiemy się nieco więcej jak skonfigurować i używać go w Eclipse.

Dzisiejsza lekcja powstała na prośbę jednego z naszych czytelników i omawiać będzie szerzej zagadnienia związane z konfiguracją i używaniem Maven w Eclipse.

Lekcja

Instalacja i wymagania

Aby w ogóle korzystać z Maven w środowisku Eclipse musimy najpierw pobrać odpowiednią wtyczkę. Nazywa się ona m2e i jest dostępna także poprzez Eclipse Marketplace. Najprawdopodobniej będziesz miała ją już zainstalowaną, jeśli pobierałaś wersje Eclipse przeznaczoną do web developmentu – np. SpringToolSuite. Jeśli nie, najłatwiej skorzystać z Eclipse Marketplace tak jak poniżej:

Eclipse MArketplace w menu Help

Eclipse Marketplace w menu Help


Zainstalowane moduły m2e - można je samodzielnie zainstalować wyszukując je w zakładce 'Search' pod hasłem m2e

Zainstalowane moduły m2e – można je samodzielnie zainstalować wyszukując je w zakładce ‚Search’ pod hasłem m2e

Zarządzanie projektem Maven pod Eclipse

Są trzy możliwości, jak możemy korzystać z dobrodziejstw m2e – polecam wykorzystywać wyłącznie dwie pierwsze, trzecia zostanie jedynie wspomniana i jest przeznaczona raczej dla osób doświadczonych z ‚grzebaniem’ w Eclipse.

Utwórz nowy projekt / moduł

Ta opcja jest dla osób, które dopiero będą pisały kod i chcą, aby projekt był zarządzany za pomocą Maven’a . Z menu File wybieramy opcję New a następnie Other. W oknie, które się pojawi wyszukujemy zakładkę ‚Maven’ i mamy dostępne kilka opcji:

Okno File -> New -> Other z rozwiniętą zakładką 'Maven'

Okno File -> New -> Other z rozwiniętą zakładką ‚Maven’

Pierwsza z nich (Check out Maven Projects from SCM) umożliwia import projektu pobierając go z repozytorium (jak np. Git czy Svn – o nich powiemy sobie w przyszłości). Działa analogicznie jak importowanie istniejącego projektu (opisanego poniżej) tyle tylko, że sama pobiera kod z repozytorium na dysk.

Druga opcja (Maven module) pozwala na stworzenie nowego modułu, tzn. podprojektu – takiego, który ma rodzica. Przykładem może być moduł związany z obsługą bazy danych w większej aplikacji. W mniejszych projektach często istnieje podział na moduły wg warstw logicznych – obsługi danych (np. bazy danych), logiki biznesowej (serwisy) oraz prezentacji (np. aplikacja webowa i widoki HTML). W większych często jest to podział wg domeny (np. obsługa kart, obsługa transakcji, obsługa sprzedaży itp).

Trzecia opcja (Maven project) pozwala na utworzenie nowego projektu. Projekt to nadrzędna jednostka w Mavenie, jeden projekt może (ale nie musi) grupować kilka modułów.

Konfiguracja drugiej i trzeciej opcji jest niemal identyczna, różni się jedynie tym, że w przypadku modułu w pierwszym kroku wybieramy też rodzica. Screeny będą pokazane na przykładzie projektu (opcja trzecia).

Pierwszy ekran tworzenia nowego projektu Maven

Pierwszy ekran tworzenia nowego projektu Maven

Na pierwszym ekranie mamy do wyboru kilka opcji, związanych bardziej z wyglądem w Eclipse niż z działaniem m2e:

  • Create simple project (skip archetype selection) – zaznaczając tą opcję pomijamy wybór archetypu (czyli ‚szablonu’ projektu, możemy skorzystać z gotowych lub z utworzonych przez nas) i tworzymy pusty projekt. Często zaczynając pracę będziemy korzystali właśnie z tej opcji, samodzielnie dodając zależności i tworząc strukturę projektu.
  • Use default workspace location – możemy utworzyć projekt w innym miejscu na dysku niż domyślny katalog. Ta opcja nie zmienia nic w zachowaniu m2e, dotyczy jedynie fizycznego położenia plików na dysku
  • Add projects to working set – ta opcja pozwala nam na wybranie working set’a, do którego dodamy projekt. Working set to coś w rodzaju katalogów – możemy pogrupować sobie projekty nad którymi aktualnie pracujemy (jest to pomocne, jeśli pracujemy nad wieloma jednocześnie, np. przy dużym projekcie)
  • Rozwijając zakładkę Advanced mamy dodatkowe opcje, z których ciekawsza jest Name template – pozwala ona określić, pod jaką nazwą będzie się wyświetlał projekt. Ja proponuję [groupId].[artifactId] – dla mnie najlepiej się ona sprawdza, ale jest to bardzo kwestia osobistych preferencji. Tak, żeby Tobie było wygodnie :)
Drugi ekran - konfiguracja specyficzna dla Maven'a

Drugi ekran – konfiguracja specyficzna dla Maven’a

W drugim kroku konfigurujemy ustawienia specyficzne dla Mavena. Wymagane pola to:

  • Group Id i Artifact Id – ‚współrzędne’ Mavena, więcej o nich znajdziesz w lekcji #7
  • Version – wersja naszego projektu, najczęściej na początek warto zostawić domyślny numer. Numeracja wersji w Mavenie ma pewną konwencję i składa się z następujacych elementów (od lewej; elementy te są opcjonalne od Minor Version):
    • Major version (0.0.1-SNAPSHOT) – wersja główna, zwiększamy ją jak robimy bardzo duże zmiany, np. przepisujemy dużą część, zmieniamy cały (lub większość) interfejs itp
    • Minor version  (0.0.1-SNAPSHOT) – wersja mniejsza, zmieniamy ją w przypadku dodania/modyfikacji znaczących funkcjonalności (ale nie wpływających na całą aplikację)
    • Incremental  (0.0.1-SNAPSHOT) – zmieniamy zawsze, gdy wprowadzamy jakieś nowe rzeczy (najczęściej w przypadku projektów komercyjnych zmieniamy w sytuacji kiedy udostępniamy nową wersję dla klienta/do pobrania)
    • Build number  (0.0.1-12) – nieczęsto używana notacja (ale nadal zgodna ze standardem), najczęściej w dużych projektach o zautomatyzowanym procesie wydawania oprogramowania
    • Qualifier  (0.0.1-SNAPSHOT) – to bardzo wazny element, ponieważ dodanie kwalifikatora -SNAPSHOT oznacza, że jest to wersja przejściowa i (najczęściej) nie do końca gotowa do działania w środowisku produkcyjnym. Często też takie wersje są wypuszczane częściej, jako podgląd. Przez to niektóre repozytoria nie przechowują ich (w takich wypadkach często można skonfigurować dodatkowe, osobne repozytorium na artefakty z tym klasyfikatorem). Inny przykład klasyfikatora to np. -beta, -alpha itp
  • Packaging type – określa sposób, w jaki pliki w tym module/projekcie będą traktowane i przetwarzane w procesie budowania. Jest kilka standardowych typów, z którymi będziemy się spotykać najczęściej:
    • pom – jeśli chcemy, aby nasz projekt/moduł był rodzicem dla innych, musimy wybrać ten rodzaj paczkowania
    • jar – ten rodzaj jest przeznaczony do aplikacji standalone (takie, które do działania nie wymagają nic innego, np serwera aplikacji) oraz bibliotek (moduły naszej aplikacji często traktujemy właśnie jako biblioteki, które później są wykorzystywane przez np. aplikację webową lub inny interfejs)
    • war – to paczkowanie tworzy strukturę katalogów dla projektu aplikacji webowej
    • ear – jest to tzw. enterprise archive, które służy do paczkowania m.in. komponentów EJB, dość rzadko spotykane, ale można się z nim spotkac w większych projektach

Te informacje są wystarczające, aby utworzyć nowy projekt. Po kliknięciu na ‚Finish’ po chwili powinniśmy mieć skonfigurowany, gotowy do dalszej pracy projekt :)

Importuj projekt/moduł

Ta opcja pozwala nam m.in. zaimportować pliki źródłowe, które mamy na dysku jako projekt Maven. Po wybraniu opcji File -> Import i rozwinięciu zakładki ‚Maven’ mamy dostępne kilka opcji.

Okno File->Import z rozwiniętą zakładką 'Maven'

Okno File->Import z rozwiniętą zakładką ‚Maven’

  • Pierwsza opcja (Check out Maven Projects from SCM) działa analogicznie jak wspomniana wcześniej – pozwala pobrać pliki z repozytorium kodu i zaimportować je w Eclipse jako projekt Maven
  • Druga opcja (Existing Maven Projects) będzie dla nas najbardziej przydatna i ją opiszemy szerzej, służy do zaimportowania plików, które mamy na dysku i traktowania ich jako projekt Maven. Oczywiście muszą mieć one plik pom.xml oraz strukturę zgodną z Mavenem
  • Trzecia opcja (Install or deploy an artifact to a Maven repository) pozwala nam zaimportować artefakt (np. plik JAR) do repozytorium (co w efekcie umożliwi np. korzystanie przy pomocy Mavena z bibliotek, które nie są publikowane w ramach Mavena). Jest to bardzo przydatna opcja w szczególności, jeśli musimy korzystać z projektów pisanych dawno temu i chcemy używać Mavena do zarządzania nowym projektem (Uwaga! To importuje plik tylko do lokalnego repozytorium, tj. ktoś inny chcąc u siebie zbudować projekt, będzie musiał zaimportować te same artefakty co my do swojego repozytorium)
  • Czwarta opcja (Materialize Maven Projects from SCM) pozwala na pobranie plików projektu i import jego źródeł na dysk z repozytorium kodu tylko na podstawie pliku pom.xml (o ile zawiera on informacje o lokalizacji repozytorium). Opcja stosowana dość rzadko (osobiście nie miałem okazji), niemniej na pewno warto wiedzieć, że istnieje

Skupmy się na drugiej opcji, czyli importowaniu plików, które mamy na dysku do Eclipse. Po wybraniu tej opcji zobaczymy okno podobne do poniższego:

Okno importu projektu Maven - na przykładzie widoczny projekt open source webcam-captureNotabene autorem jest nasz rodak, Bartosz Firyn, któremu w tym miejscu serdecznie dziękuje za oszczędzenie tygodni pracy kilka razy :)

Okno importu projektu Maven – na przykładzie widoczny projekt open source webcam-capture
Notabene autorem tej biblioteki jest nasz rodak, Bartosz Firyn, któremu w tym miejscu serdecznie dziękuje za oszczędzenie tygodni pracy, kilkukrotnie :)

Oczywiście początkowo główna część okna będzie pusta – po wyborze ścieżki w polu Root Directory Eclipse przeszukuje ten katalog i podkatalogi w poszukiwaniu plików pom.xml a następnie na tej podstawie tworzy listę projektów, które możemy zaimportować. Możemy wybrać wszystkie z nich lub tylko niektóre, w zależności od potrzeby.

Możemy także ustawić Working set, którego będziemy używać oraz schemat nazewnictwa (ukryty pod opcją ‚Advanced’).

Po kliknięciu ‚Finish’ przygotuj się na chwilę czekania, szczególnie z większymi projektami, Eclipse w tym czasie pobiera wszystkie zależności (oraz ich zależności), importuje kod, analizuje go, indeksuje i pewnie robi masę innych użytecznych rzeczy o których mam niewielkie pojęcie, w każdym razie – chwile to trwa :)

Konwersja projektu na Maven

Ta opcja dostępna jest z poziomu menu kontekstowego, jako Maven -> Enable Maven Nature lub z submenu Configure -> Convert to Maven Project. Obie te opcje jednak niosą ze sobą pewne ryzyka – decydując się na ich użycie, naprawdę należy być świadomym, co się robi. Ponieważ nie jest to coś, z czym możesz się spotkać na co dzień, nie będziemy zgłębiać tego tematu, mam nadzieję, że wybaczycie :)

Praca z plikiem pom.xml

Z użyciem wtyczki m2e możemy otworzyć plik pom.xml w specjalnym edytorze. Edytor ten podzielony jest na kilka zakładek, jak na przykładzie poniżej. Każda z tych zakładek została pokrótce omówiona poniżej.

Widok zakładki Overview w edytorze pliku pom.xml

Widok zakładki Overview w edytorze pliku pom.xml

  • Overview – tutaj możemy skonfigurować ogólne parametry projektu, takie jak nazwa, rodzic, podmoduły, repozytorium kodu oraz inne metadane obsługiwane przez plik pom.xml. W przypadku modułów warto zwrócić uwagę na dwa przyciski znajdujące się w tej zakładce:
    • Add pozwala dodać ISTNIEJĄCY moduł/projekt, jako moduł tego projektu
    • Create pozwala utworzyć moduł, który będzie przypisany do tego projektu
  • Dependencies – Tutaj możemy zarządzać zależnościami naszego modułu za pomocą prostego edytora graficznego
  • Dependency Hierarchy – To bardzo przydatna zakładka w przypadku konfliktów wersji (np. potrzebujemy modułu A w wersji X, a poprzez inne zależności jest on też importowany w wersji Y) – pozwala nam przede wszystkim przejrzeć i przefiltrować wszystkie zależności, które występują w naszym module, jak też wykluczać je w razie potrzeby. (Uwaga praktyczna: filtrowanie potrafi działać bardzo powoli, szczególnie w dużych projektach)
  • Effective POM – Kolejna z ważnych zakładek do rozwiązywania projektów, pozwala podejrzeć tzw. effective POM – czyli ujednolicony plik POM po dodaniu wszystkich elementów z plików POM projektów-rodziców i określeniu wartości wszystkich zmiennych. Tak naprawdę to effective POM decyduje o tym, jak projekt jest budowany. Jeśli więc jakieś z ustawień są nadpisywane, można to zweryfikować właśnie w tym miejscu
  • pom.xml – tekstowa wersja pliku pom.xml, z czasem najczęściej będziesz korzystała właśnie z tej zakładki ;)

Rozwiązywanie problemów

Pracując z projektami Maven czasem możemy napotkać na pewne drobne problemy i bugi. Jest kilka sposobów, żeby sobie z nimi poradzić, możemy spróbować następujacych kroków:

  1. Nie panikujemy ;)
  2. Sprawdzamy w czym jest problem – być może zrobiliśmy np. literówkę. Możemy to sprawdzić w oknie ‚problems’:Screenshot_9
  3. Na początku próbujemy po dobroci – wyczyścić trochę metadanych i odświeżyć (klikamy prawym przyciskiem myszki na projekt i wybieramy Maven -> Update Project. W oknie, które się pojawi wybieramy też ‚Force Update of Snapshot/Releases’ i klikamy OK. Ta operacja może zająć chwilę
  4. Jeśli to nie pomoże, czasem pomocne jest usunięcie projektu do Eclipse (uwaga, żeby nie zaznaczyć opcji usuwania także plików) i ponowne zaimportowanie go
  5. Kolejnym krokiem jest wyczyszczenie pamięci Eclipse pomiędzy usunięciem, a ponownym importem w tej kolejności:
    1. usuwamy projekt
    2. zamykamy Eclipse
    3. uruchamiamy z opcją czyszczenia (jak to zrobić możesz przeczytać tutaj)
    4. zamykamy
    5. uruchamiamy bez opcji czyszczenia
    6. importujemy projekt

Czasami pojawia się też problem tego rodzaju, że dodając projekt do serwera aplikacji w Eclipse (np. Tomcata), otrzymujemy błąd ClassNotFoundException. Czasem jest to spowodowane tym, że Eclipse z jakiegoś powodu ‚gubi’ informacje o zależnościach z Mavena. Najczęściej można to rozwiązać klikając prawym przyciskiem myszki na projekt, który sprawia problemy i wybierając opcję ‚Properties’. Następnie przechodzimy na zakładkę Deployment Assembly.

Przykłądowa konfiguracja Deployment Assembly dla projektu webowego w Mavenie

Przykłądowa konfiguracja Deployment Assembly dla projektu webowego w Mavenie

Upewniamy się, że jest tam pozycja ‚Maven Dependencies’. Jeśli jej nie ma, wykonujemy poniższe kroki:

  1. Wybieramy opcję ‚Add’
  2. W oknie, które się pojawi wybieramy ‚Java Build Path Entries’
  3. W kolejnym oknie wybieramy Maven Dependencies (całe, a nie któryś z podelementów)
  4. Klikamy ‚Finish’

Powyższe działania powinny pomóc w większości problemów z Mavenem, ale oczywiście może się zdarzyć, że natrafisz na inny problem. Warto zapytać swoich współpracowników, być może mieli podobny problem, lub napisac do nas – zawsze spróbujemy pomóc :)

Podsumowanie

W tej lekcji poznaliśmy trochę Mavena od strony jego obsługi w Eclipse a także jak radzić sobie z najczęstszymi problemami :) Maven to naprawdę potężne narzędzie i zachęcam do pogłębiania swojej wiedzy w tym zakresie!

Licencja Creative Commons

Jeśli uważasz powyższą lekcję za przydatną, mamy małą prośbę: polub nasz fanpage. Dzięki temu będziesz zawsze na bieżąco z nowymi treściami na blogu ( i oczywiście, z nowymi częściami kursu Javy). Dzięki!

  • 5
  •  
  •  
  •  
  •  
  • AgnieszkaU

    Hej, przechodzę krok po kroku Wasz kurs Javy i próbowałam w tej lekcji pobrać z http://webcam-capture.sarxos.pl/ projekt Webcam Capture. Tam jest zip (webcam-capture-0.3.10-dist.zip) do pobrania, ale nie ma w nim struktury maven’owej, np. nie ma pom.xml’i. Robię coś nie tak? Mogę skądś pobrać to tak, jak to jest prezentowane w tej lekcji. Będę wdzięczna za pomoc.

    • Cześć,

      plik, który pobierasz jest już gotowy do dystrybucji i użycia w dowolnej aplikacji, czyli pozbawiony elementów związanych z rozwijaniem go (jak np, plików pom.xml). Żeby dokładni epowtórzyć kroki z lekcji, pobierz paczkę z githuba: https://github.com/sarxos/webcam-capture/archive/master.zip :)

      Mam nadzieję, że to pomoże, a w razie problemów pisz, postaramy się pomóc :)

      • AgnieszkaU

        Dziękuję. Właśnie o to mi chodziło.

  • AgnieszkaU

    Podczas tworzenia nowego Maven Project po kroku ‚Select project name and location” (tu wybieram domyślnie) pojawia mi się krok „Select an Archetype”. Wcześniej, jeśli dobrze pamiętam, go nie było ;-) Można ten krok pominąć? Coś nie tak wybieram? Nie wiem, co tam wybrać.

    • Cześć,
      na pierwszym ekranie jest opcja ‚Create simple project (skip archetype selection)’ – wystarczy zaznaczyć tą opcję, żeby pominąć wspomniany ekran :)

      Pozdrawiam, Jakub Derda

  • Iti

    Po utworzeniu nowego czystego projektu webowego przy użyciu maven dostałam 1 warning i 1 error:

    Warning:
    Build path specifies execution environment J2SE-1.5. There are no JREs installed in the workspace that are strictly compatible with this environment. (świeża instalka eclipse, java aktualna)

    Error:
    web.xml is missing and is set to true

    • Cześć,
      jeśli chodzi o błąd – generując pusty projekt w mavenie z packaging typu war, plik web.xml nie generuje się automatycznie. Możesz go sam utworzyć – piszemy o tym w lekcji 9 (http://kobietydokodu.pl/09-spring-mvc/), dział ‚Plik web.xml’).

      Warning z kolei otrzymujesz dlatego, że Maven domyślnie ma ustawioną Javę w wersji 5 – stąd Eclipse informuje, że masz inną wersję Javy na komputerze (zapewne 8 – która jest w stanie obsługiwać 5 wersję, ale ściśle rzecz biorąc nią nie jest). Przykład, jak temu zaradzić znajdziesz np tutaj: https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html – wystarczy powiedzieć Mavenowi, której wersji ma użyć.

      Pozdrawiamy!

  • Dorusiak

    Witam
    Podoba mi się ten kurs:) ale mam wątpliwości czy będę mogła z niego korzystać mając zainstalowane środowisko NetBeans 8.0.2 . Proszę o odpowiedź czy muszę je koniecznie zmienić na Eclipse czy dam radę na NetBeans.

    • Cześć,
      NetBeans jest jak najbardziej w pełni funkcjonalnym środowiskiem do programowania w Javie – niektóre opcje będą się inaczej nazywały, ale poza importowaniem projektu / debugowaniem czy uruchamianiem, samo programowanie będzie identyczne :)

      Zalecamy Eclipse z kilku powodów – jest to główne środowisko w firmach i prędzej czy później się z nim zetkniesz, ale też jest to obecnie najpopularniejsza platforma i ma największą ilość tutoriali, manuali i porad.
      Ostatecznie, wybór IDE to kwestia Twojej wygody, każde pozwala na to samo, wybór pomiędzy nimi to tylko kwestia preferencji i wygody.

      Pozdrawiamy

      • Dorusiak

        To super, dzięki za info.

  • michał

    cześć,
    spróbuję tu zapytać, czy potrafisz pomóc w rozwiązaniu następującego problemu. posiadam dwa moduły, które zawierają te same pliki, jednak o rożnych zawartościach, czy jest jakis sposób gdy ładuje jara jako zależnosc do wara aby nadpisać pliki? mam nadzieje ze rozumiesz o co mi chodzi. z gory dzieki za wszelką pomoc :)
    Pozdrawiam

    • Cześć,

      jeśli dobrze rozumiem, to masz moduł X, który jest typu WAR oraz ma jakiś plik, dajmy na to application.properties. Masz też moduł Y, w którym jest plik o tej samej nazwie. Chcesz, aby plik WAR miał plik application.properties z modułu Y, a nie X, tak ?

      W takiej sytuacji zerknij na WAR overlays – https://maven.apache.org/plugins/maven-war-plugin/overlays.html , dzięki temu możesz bezpośrednio używać plików z innych artefaktów, zamiast umieszczać je w katalog lib.

      Jeśli jednak potrzebujesz używać różnych plików w różnych sytuacjach (np. budując do testów i na produkcje) to powinieneś zainteresować się profilami – struktura plików będzie wtedy nieco inna, ale to naprawdę potężne narzędzie. Zerknij np na dyskusję http://stackoverflow.com/questions/12729513/how-to-overwrite-files-in-the-war-file-during-maven-build , gdzie znajdziesz przykład użycia profili. Bardziej techniczny opis znajdziesz https://maven.apache.org/guides/mini/guide-building-for-different-environments.html i http://maven.apache.org/guides/introduction/introduction-to-profiles.html . Mam nadzieję, że to odpowiada na Twoje pytanie, ale jeśli nie to oczywiście chętnie pomożemy znaleźć rozwiązanie :)

      • michał

        Dzięki za odpowiedź ;)

        Oczywiście chodzi o to pierwsze. Pozwolę sobie jednak dopytać, robię coś takiego:

        com.example
        modul-jar
        jar

        WEB-INF/layouts/layouts.xml

        mam wrażenie, że wykorzystałem juz wszelkie kombinacje, a nadal nie nadpisuje mi zadanej zawartości

        • Zwróć uwagę, że moduł ten pracuje na gotowym artefakcie – czyli pliku WAR lib ZIP (wg dokumentacji). Na pewno nie zgadza się więc typ. Moduł ten ma też swoje ograniczenia, więc być może nie będzie spełniał Twoich wymagań.

          Jeśli to nie problem, opisz tutaj strukturę plików obu modułów – będzie łatwiej coś poradzić.

          Zerknij także do dokumentacji tutaj: http://maven.apache.org/plugins/maven-dependency-plugin/examples/copying-artifacts.html – ten moduł pozwala na zwykłe kopiowanie, wymaga więcej konfiguracji ale być może w konkretnie Twoim przypadku będzie to korzystniejsze.

          • michał

            Pozwolilłem sobie odezwać się mailowo :)