#07 – Maven i tajemnice pliku pom.xml

By 25 września 2014Kurs Javy
Wpis-Header (1)

W opisie narzędzi i przygotowaniu projektu wspominałem o tym, żeby utworzyć projekt Maven. W tej lekcji wyjaśnimy czym dokładnie jest maven, do czego jeszcze możemy go wykorzystać.
Maven to w uproszczeniu narzędzie do zarządzania projektem, jego zaleznościami (czyli np. bibliotekami które będziemy używać) i strukturą (np. podział na moduły). Ale to tylko mały wycinek tego, co daje nam to narzędzie. Zachęcam do zapoznania się z odnośnikami znajdującymi się na dole tej lekcji, które rzucą więcej światła na możliwości jakie oferuje Maven. Oczywiście istnieją alternatywne rozwiązania, takie jak np. starszy Ant czy nowszy Gradle. Niemniej Maven dość szybko został zaadoptowany przez firmy i nic nie wskazuje na to, żeby miało się to wkrótce zmienić, dlatego z punktu widzenia celu tego bloga Mavena należy znać. Po prostu :)

Lekcja

UWAGA! Jeśli instalowałaś inne środowisko niż STS, możesz nie mieć zainstalowanego Mavena. Sprawdź w odnośnikach jak to zrobić i upewnij się, że przed kontynuowaniem Maven jest zainstalowany na Twoim komputerze.Maven jest bardzo rozbudowanym narzędziem, jednocześnie bardzo prostym w podstawowym użyciu i użytecznym nawet w małych projektach. Cała potęga kryje się w jego budowie – wszystkie elementy, kroki i procesu są dynamiczne i konfigurowalne, dzięki czemu możemy sami wpływać na ich działanie, włączać/wyłaczać poszczególne elementy wg potrzeby i dopasowywać do swoich potrzeb. Jednoczesnie cała konfiguracja jest w jednym miejscu wewnątrz projektu, co bardzo pomaga jeśli prace przy projekcie odbywają się na kilku róznych komputerach (np. w zespole, lub pracujemy w domu i w biurze).Miej na uwadze, że przedstawione poniżej informacje to tylko wycinek, który będzie nam potrzebny do dalszej pracy. Gorąco zachęcam do zapoznania się z innymi mozliwościami tego narzędzia.

Słowniczek

Zaczniemy od wyjaśnienia kilku pojęć. Będą one używane w tej i kolejnych lekcjach i kluczowe jest, żeby je zrozumiała. W razie wątpliwości można też poszukać w internecie ich znaczenia – wiele poradników i tutoriali także opisuje znaczenie poszczególnych słów i określeń.

  • artefakt – samoistna jednostka w projekcie, artefaktem jest np. każdy z modułów czy każda z zależności projektu. Można powiedzieć, że artefakt to takie zbiorcze określenie które obejmuje zarówno projekty, moduły, biblioteki, pluginy (czyli elementy całego procesu), archetypy (coś w rodzaju \’szablonu\’ projektu, który możesz szybko skonfigurować i uruchomić) itd.
  • pom.xml – główny plik z ustawieniami Maven w projekcie
  • repozytorium – zbiór artefaktów. Każda instalacja Maven powoduje utworzenie lokalnego repozytorium, jest także repozytorium centralne oraz można korzystać z dowolnych innych repozytoriów (np. jakiegoś projektu)

Struktura projektu

Korzystając z Mavena projekt ma standardową strukturę (na dysku), w której możemy wyróżnić kilka elementów (w głównym katalogu projektu):

  • pom.xml – główny plik konfiguracji Maven, omówimy go bardziej szczegółowo poniżej
  • /src/main – katalog, gdzie znajdziemy pliki naszego programu, są tam dwa podkatalogi:
    • java – tutaj trafiają wszystkie klasy (cały kod naszego modułu)
    • resources – tutaj będą wszystkie pliki, które nie są kodem, np. grafiki, pliki XML, konfiguracje itp (nauczymy się z nich korzystać w kolejnych etapach kursu)
    • w przypadku projektów webowych będziemy mieli także katalog webapp, który jest używany do umieszczania wszystkich treści webowych
  • /src/test – ma podobną strukturę jak katalog /main z tą różnicą, że jest on wykorzystywany tylko w trakcie automatycznych testów. O automatycznych testach powiemy sobie więcej w 8 lekcji
  • /target – tutaj trafia skompilowany projekt (czyli np. w postaci wykonywalnego pliku JAR lub aplikacji webowej WAR)

Poza powyższymi w naszym module oczywiście mogą się znaleźć dodatkowe pliki i katalogi, nie są one jednak ściśle związane z samym Mavenem (najczęściej).

Projekty i moduły w Mavenie

Tworząc nowy projekt w mavenie możemy wybrać jego ‚packaging’, czyli sposób, w jaki wszystkie elementy zostaną ostatecznie połaczone razem. Istnieje kilka podstawowych (oczywiście moduły i pluginy mogą rozszerzać tą listę):

  • pom
  • jar (domyślny)
  • war (aplikacje webowe, o tym porozmawiamy w przyszłości)

Packaging JAR powoduje, że w momencie uruchomienia budowania maven wszystkie nasze klasy zostaną połączone w jeden plik JAR (który można następnie uruchamiać samodzielnie).
O plikach WAR powiemy sobie w kolejnych lekcjach, ale zatrzymajmy się na moment przy wartości POM.

Packaging POM oznacza mniej więcej tyle, że jest to projekt, który może posiadać kilka modułów (to nie jest wymagane, ale na ten moment załóżmy że to najczęstszy przypadek, w którym używamy tego ustawienia). Dla przykładu, w dowolnej dużej aplikacji najczęściej znajdziemy wiele pod-projektów (modułów, komponentów), z których każdy jest podzielony na kilka elementów (np. osobno jest kod związany z bazą danych, z logiką biznesową oraz z wyświetlaniem – warstwą prezentacji). Z punktu widzenia maven jeden taki komponent (pod-projekt) to projekt (lub moduł) który ma packaging = POM, z kolei każdy z elementów (logika biznesowa, obsługa bazy danych itp) to osobne moduły, które mają packaging JAR lub WAR i w sekcji parent ustawiony ten projekt, który ma packaging ‚POM’.

W eclipse możemy ustawić taki projekt na dwa sposoby – albo tworząc nowy moduł i podając odpowiednie dane w sekcji ‚parent’, albo otwierając plik pom.xml nadrzędnego modułu i w sekcji ‚modules’ wybierając opcję ‚create’ (opcja ‚add’ pozwala nam wybrać już istniejący moduł, którym chcemy zarządzać w ten sposób) i uzupełniając dane jak przy normalnym tworzeniu modułu Mavenowego.

Taka konfiguracja jest bardzo wygodna, ponieważ wszystkie ustawienia ‚nadrzędnego’ POMa są też dostępne w POMie podrzędnym, możemy więc z jednego miejsca zarządzać wersjami bibliotek, których używamy, używać ustawień i konfigurować pluginy. Więcej o innych zastosowaniach będziemy mówili w kolejnych lekcjach, póki co będzie to dla nas przydatne także po to, aby uporządkować nasz kod i podzielić go na moduły.

pom.xml

Plik pom.xml jest tym, co łączy projekt w Javie oraz Maven’a ;) To w nim jest cała konfiguracja związana z projektem, opis jak ma być budowany, konfiguracja pluginów itp. Nie będziemy tutaj opisywać całej struktury pliku pom, ponieważ wyznacza to znacznie poza ramy tego kursu, a jedynie nakreślimy najważniejsze elementy.To, co musi zawierać plik pom.xml, to koordynaty artefaktu, czyli groupId oraz artifactId. Jeśli projekt nie ma rodzica (tag <parent>), musimy określić także numer wersji. Identyfikator grupy to najczęściej nazwa projektu, podczas gdy identyfikator artefaktu to unikalna nazwa np. modułu – idea jest taka, że poszczególne moduły tego samego projektu mają wspólny groupId, ale unikalny artifactId. Para wartości groupId i artifactId powinna być unikalna.

Plik ten pozwala nam także określić, z jakich bibliotek i innych modułów korzysta nasz moduł. Służy do tego tag <dependencies>, który może wystąpić tylko raz – wewnątrz tego tagu możemy dodać wiele tagów <dependency>. Tag dependency może wskazywać na dowolny artefakt z repozytorium centralnego, lokalnego lub dowolnego innego skonfigurowanego w ustawieniach Maven. Musi on zawierać trzy informacje – groupId, artifactId (razem to tzw. coordinates – czyli precyzyjne określenie, o który artefakt nam chodzi) oraz version – wersję  (to nie do końca prawda, w większych projektach stosuje się tzw. dependencyManagement, czyli centralne zarządzanie numerami wersji pozwalające pominąć numer wersji w tagu dependency; zainteresowanych odsyłam do dokumentacji Mavena, nie ma w tym żadnej magii i w prostych projektach jest to mało przydatne). Przykładowy plik pom.xml wygląda następujaco:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
</project>

Jest to tzw. minimalny plik pom.xml – posiada tylko wymagane informacje.

<project>
  ...
  <properties>
    <mavenVersion>2.1</mavenVersion>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-artifact</artifactId>
      <version>${mavenVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-project</artifactId>
      <version>${mavenVersion}</version>
    </dependency>
  </dependencies>
  ...
</project>

Więcej przykładów znajdziesz na stronie Mavena, pod adresem http://maven.apache.org/guides/introduction/introduction-to-the-pom.html

Cykl życia (domyślny)

Cała idea działania Mavena jest zbudowana wokół tzw. cyklu życia (maven build lifecycle). Każdy z kroków to kolejny element na drodze od kodów źródłowych do projektu uruchomionego na serwerze (tak, Maven może także to zrobić). Poniższy diagram przedstawia (uproszczony) domyślny cykl życia projektu.

Domyślny (uproszczony) cykl życia projektu

Domyślny (uproszczony) cykl życia projektu

Krótkie omówienie poszczególnych faz:

  • validate – walidacja, na tym etapie sprawdzane jest, czy kod źródłowy jest poprawny, czy wszystkie pliki zawierają prawidłowe elementy (o ile Maven ma informacje, jak to sprawdzić) itp., ogólnie jest to sprawdzenie, czy projekt można skompilować
  • compile – kompilacja projektu, czyli zamiana kodów źródłowych na kod zrozumiały dla maszyny wirtualnej
  • test – automatyczne wykonanie testów, o których to będzie kolejna lekcja
  • package – łączenie elementów stworzonych w poprzednich etapach w tzw. deliverable, czyli np. plik JAR który można uruchomić lub plik WAR który można uruchomić na serwerze
  • integration-test – to kolejna seria automatycznych testów, tym razem integracyjnych. Testy integracyjne to w skrócie testy sprawdzające czy nasz komponent współpracuje z innymi w ramach większego systemu. Testy tego rodzaju nie będą omawiane w tym kursie (ale może w przyszłości pojawi się o nich parę słów na blogu w ramach luźnej notatki :) )
  • verify – weryfikacja, czy stworzona paczka spełnia kryteria jakościowe (o kryteriach, metrykach itp. powiemy sobie w przyszłości)
  • install – instalacja paczki wygenerowanej w kroku package. Przy czym uwaga, instalacja oznacza tyle, że artefakt (czyli wynik działania package) zostanie umieszczony w repozytorium Mavena (domyślnie lokalnym, ale możemy też umieścić je w repozytorium zdalnym) i będzie dostępny dla innych modułów (np. jako zależność)
  • deploy – umieszczenie artefaktu np. na serwerze za pomocą FTP czy jakiegoś API serwera aplikacji

Maven’a uruchamiamy przechodząc do katalogu z plikiem pom.xml i wpisujac mvn <step> . Możliwości jest oczywiście więcej, możemy wykonać konkretny cel (‚podkrok’ w ramach danego kroku) ale ponieważ w tym kursie Maven posłuży nam tylko jako narzędzie dodatkowe, nie będziemy omawiać szczegółów. Zainteresowanych odsyłam do dokumentacji lub książek na temat samego Mavena :)

To, co trzeba wiedzieć, to to, że wywołaniem konkretnego kroku (np. poprzez mvn install) wykonujemy wszystkie kroki po kolei, aż do tego, który określiliśmy (w tym przypadku wszystkie kroki poza ostatnim – deploy). Najczęstszym sposobem użycia (i ten proszę sobie napisać na karteczce i nakleić na monitor) to polecenie mvn clean install – cel clean nie należy do głównego cyklu życia (ale możemy go wykonać tak jak dowolny inny krok, po prostu wstawiając go po spacji do polecenia). To polecenie najpierw usunie wszystkie stare pliki (to ważne, ponieważ czasem nieusunięcie plików może prowadzić do błędów, które trudno zlokalizować) a następnie skompiluje projekt, zapaczkuje go (stworzy artefakt) i umieści go w repozytorium (domyślnie lokalnym). Artefakt znajdziemy też oczywiście w katalogu /target jako plik .jar / .war .

Zadanie

Jeśli projekt, nad którym pracujesz, nie jest jeszcze projektem typu maven (można to poznać np. po tym, że nie ma w jego głównym katalogu pliku pom.xml), skonwertuj go na projekt Maven (klikając prawym przyciskiem myszki na projekt w Eclipse, a następnie wybierając odpowiednią opcję konwersji).Zmodyfikuj plik pom.xml tak, aby zawierał poniższe zmiany:

  • Uzupełnij nazwę projektu i jego opis oraz adres URL (jeśli nie posiadasz własnej strony, jako adres URL podaj stronę tego projektu)
  • Skonfiguruj projekt tak, aby plik JAR można było uruchomić bezpośrednio, klikając na niego dwukrotnie myszką (tzw. self-executable JAR). Zrób to wyłącznie poprzez modyfikacje w pliku pom.xml
  • Dodaj zależność do artefaktu org.springframework:spring-core w najnowszej wersji (wyszukaj wersję w repozytorium centralnym)

Następnie dodaj moduły:

  • koty-domain i przenieś do niego klasę Kot
  • koty-application i umieść w nim resztę klas. Do tego modułu przenieś zależność do spring-core

Pamiętaj, że część zmian z pierwszej części zadania będziesz musiał przenieść do modułu (chodzi głównie o konfigurację executable JAR – do modułu koty-application)

Upewnij się, że nadal można skompilować projekt (dodaj zależności jeśli jest taka potrzeba).

Podpowiedzi

More »
  1. Realizuj jedną zmianę na raz, przy pierwszym spotkaniu Maven może wydać Ci się ogromnym i skomplikowanym narzędziem, ale tak naprawdę znacznie ułatwia życie programisty :) Ważne jest, żeby się do niego nie zrazić, ale jednocześnie poznać ograniczenia i wymogi
  2. Zawartość repozytorium centralnego możesz łatwo przeszukiwać na stronie mvnrepository.com
  3. Jeśli po przeniesieniu klasy pojawią się błędy, pozwól środowisku IDE rozwiązać je za Ciebie (Ctrl+1 w środowisku Eclipse). Nastepnie prześledź zmiany w plikach pom.xml

zip Pobierz rozwiązanie tego zadania

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!

  •  
  •  
  •  
  •  
  •  
  • pioiop

    „Następ­nie dodaj moduł o nazwie koty-domain i prze­nieś do niego plik Kot.java .”

    Czy w tym kroku chodzi o dodanie nowego folderu czy stworzenie pakietu o nazwie koty-domain?

    • Cześć,

      dzięki za zwrócenie uwagi! Już dopisałem fragment o modułach i ich dodawaniu w eclipse – zerknij w tej lekcji pod nagłówkiem ‚Pro­jekty i mod­uły w Mavenie’.

      Pozdrawiamy! :)

  • kux

    Error 404 na załączniku

  • hfjka

    W jaki sposób przenieść klasy do modułu? Przeciągnąłem te pliki do folderów modułów i nie działa.

    • Cześć,
      pliki są przeniesione prawidłowo – nie są widoczne jako ‚źródła’ ponieważ projekt, który masz otwarty to ‚koty’, podczas gdy pliki przeniosłeś do modułu ‚koty-domain’ i ‚koty-application’. Z punktu widzenia eclipse są to osobne projekty, te pliki są widoczne pod ‚głównym’ projektem tylko dlatego, że domyślnie moduły są katalogami wewnątrz głównego modułu.
      Pozdrawiamy,

  • Mirinda

    Nie bardzo rozumiem jak zrobić 2 zadanie.. Mogę poprosić o jakąś podpowiedź?

    • Podpowiedź znajdziesz w komentarzu poniżej :) Ogólnie po wszystkich zmianach powinnaś mieć poniższą strukturę modułów:

      — koty
      |– koty-domain
      |– koty-application

      To krok pierwszy. Mając już tak utworzone moduły w Mavenie (w treści lekcji znajdziesz akapit, jak można zrobić to w Eclipse) wystarczy przenieść pliki z jednego miejsca w inne.
      Możesz też zerknąć do rozwiązania i zobaczyć, jak wygląda struktura plików w nim.

  • ania

    Mam ogromny problem z tą lekcją. Nie chce się skompilować. error does not contain main type.
    Prosze o pomoc bo nie mogę ruszyć dalej. Utworzyłam moduły, i przeciągnełam do nich klasy.

    • Cześć!
      Jakie kroki po kolei robisz? Czy próbujesz uruchomić aplikację klikając na plik pod projektem koty (tak jak pokazałaś na 2 screenie) czy bezpośrednio z modułu koty-application (rozwijając 2 pozycje od dołu z pierwszego screena)? Zwróć też uwagę, że moduł koty-application ma błędy (czerwony krzyżyk przy nazwie modułu). Sprawdź, co to za błędy, być może literówka, która nie pozwala się skomplikować lub problem z konfiguracją maven.

      • ania

        tworzę moduły za pomocą pom.xml, następnie przeciągam moje klasy do koty-app i koty-dom które są bezpośrednio w kotach( nie te drugie). Czy to jest błąd? Myslę, że źle przekładam klasy. Są czerwone znaki bo interfejs nie widzi klasy kot pomimo że zrobiłam zależności.

        • Cześć, a możesz spakować wszystkie pliki do katalogu ZIP i nam przesłać? Dzięki temu będziemy widzieli co i jak :)

          Spróbuj jeszcze kliknąć prawym przyciskiem myszki na projekty wszystkie trzy i wybrać refresh. Ew możesz jeszcze kliknąć na koty-application prawym przyciskiem myszki, wybrać maven -> update Maven project i zaznaczyć opcję ‚force update snapshot’.

          Ostatecznie możesz także ponownie zaimportować moduły do eclipse lub porównać z naszym rozwiązaniem i zobaczyć, gdzie są różnice :)

          • ania

            cześć. Jak nie dojdę do jutra sama to wyślę projekt zip.
            Skon­fig­u­ruj pro­jekt tak, aby plik JAR można było uru­chomić bezpośred­nio, klika­jąc na niego dwukrot­nie myszką (tzw. self-executable JAR). Zrób to wyłącznie poprzez mody­fikacje w pliku pom.xml
            Jak zrobić ten krok? myślę że tu jest błąd. Mój pom.xml i wasz wygląda praktycznie tak samo.

          • Radek

            Hej!
            Mam identyczny problem. Wszystko ładnie się kompiluje po utworzeniu już modułu koty-domain i przeniesieniu tam pliku koty. Błędy wyskakują w momencie przeniesienia plików Interfejs i KotDAO do modułu koty-application:
            – w plikach Interfejs i KodDAO nie znajduje klasy Kot(nie ma jej w tym pakiecie)
            – wyświetla się błąd(czerwony krzyżyk) przy pustym”katalogu” src / main, tym który jest nad target. Nie potrafię stwierdzić jaki to błąd, ponieważ nigdzie nie wyskakuje żaden komunikat (może czegoś tam brakuje?).

            Wydaje mi się, że jeśli udałoby się Wam wrzucić zip z całym poprawnie rozwiązanym projektem do tej lekcji dużo łatwiej moglibyśmy porównać z nim nasze samodzielne zmagania i tym samym nie pisząc tutaj czasami nieświadomie głupich pytań :D
            Z góry dzięki!

          • Cześć, odpowiedzi są dostępne – na dole lekcji jest link (http://kobietydokodu.pl/wp-content/uploads/2015/02/kobietydokodu.pl-zadanie-07.zip). Zaimportowałem go właśnie do eclipse i uruchomiłem bez problemu. Jeśli chcesz zaimportować to rozwiązanie do eclipse, pamiętaj, aby użyć opcji File -> Import -> Maven -> Existing Maven Project
            Byłoby łatwiej powiedzieć w czym dokładnie leży problem, gdybyś podesłał strukturę plików jaką masz albo zip z tymi plikami ;)

          • Radek

            Po długich poszukiwaniach znalazłem i rozwiązałem problem. Okazało się, że przy tworzeniu nowego modułu eclipse domyślnie tworzy pakiet org. i były nieporozumienia z importami oraz wymagał żeby plik main znajdował się w source folderze. Do tego eclipse nie potrafił samodzielnie pobrać zależności i musiałem to zrobić ręcznie, ale dodanie całego projektu ułatwiło mi sprawę :D

            PS W linku do pobrania projektu wkradł Ci się nawias zamykający i nie znajduje strony.

          • Super, że się udało :) Nawias ‚dodał’ do linka Disqus, ale wystarczyła spacja – dzięki za informacje :)

          • Cześć, faktycznie rozwiązanie nie zawierało właściwego fragmentu – już poprawione :)

  • marek

    „Dodaj zależność do arte­faktu org.springframework:spring-core w najnowszej wer­sji”
    Ta zależność powinna znajdować sie w pliku pom.xml głównego modułu(projektu)? Chciałem sprawdzić rozwiązanie, jednak w pobranym pliku pom.xml nie ma dodanych żadnych zależności

    • Cześć,
      ta zależność powinna być tam, gdzie jej używasz – w tym wypadku w module koty-apllication. W nim także jest plik pom.xml.

  • Olga

    Hejka!
    Niestety muszę dołączyć do grona osób, których Maven póki co nie lubi :(
    Wysyłam maila ze spakowanymi plikami na adres mailowy Ani, będę przeogromnie wdzięczna za jakieś wskazówki.
    Pozdrawiam pełną programistycznej empatii parę! :D

    • Mamy maila, postaramy się na dniach odpisać, a w weekend uzupełnić lekcje o wskazówki jakie wysłaliśmy do Waszych problemów, mam nadzieję, że dzięki temu i Ty i reszta z mavenem się polubią!

  • Karolina

    Mam takie dość głupie pytanie, ale liczę na pomoc :). Zaimportowałam wasze rozwiązanie zadania do Eclipse i nie mogę go skompilować ani uruchomić. Jest komunikat „the selection cannot be launched and there are no recent launches.” Co powinnam zrobić? I jeszcze przy okazji w którym miejscu rozwiązania od was jest odpowiedź na pytanie: „Skonfiguruj projekt tak, aby plik JAR można było uruchomić bezpośrednio,
    klikając na niego dwukrotnie myszką (tzw. self-executable JAR)”. Będę wdzięczna za pomoc :)

    • Po imporcie wybierz plik z aplikacją, kliknij prawym przyciskiem myszki i wybierz ‚Run’. Upewnij się, że ikonka pliku to ‚wypełnione’ J, a nie sam kontur (to oznacza, że Eclipse traktuje to jako plik, a nie jako źródła). Spróbuj zrobić ‚update Maven project’ (opis jak to zrobić jest w komentarzach w dalszej części).

      Co do robienia pliku JAR wykonywalnym, zerknij do pom.xml, do sekcji plugins ;)

  • Chris

    Zadanie jest tak niezrozumiałe, że straciłem chęć do nauki. Chociażby kwestia konfiguracji projektu tak, aby plik JAR można było uruchomić bezpośrednio, klikając na niego dwukrotnie myszką. Kiedy wybieram packaging jar, to wywala błąd, że moduły można dodawać tylko na pom…

    • Cześć,
      moduły jak najbardziej można dodawać tylko dla packaging=pom, dlatego kolejność kroków w zadaniu jest taka, a nie inna. Założeniem zadania było to, aby skonfigurować jeden moduł jako JAR, następnie zmienić jego packaging na POM, dodać moduły i przenieść konfigurację do odpowiedniego modułu. Faktycznie opis zadania jest być może zbyt lakoniczny – zaraz to poprawimy! Mamy nadzię że nie zniechęciłeś się do nauki na dłużej i że była to tylko chwilowa słabość ;)

      • Roman Lis

        Podbijam problem.

        Też nie bardzo rozumiem, co w tym punkcie trzeba zrobić. Przydałby się akapit, o co chodzi i jak zrobić coś takiego.

        Wzorując się na pobranym zadaniu (musiałem pobrać, bo tylko drogą analizy gotowego rozwiązania można zrozumieć część kroków) ustawiłem główny pom.xml na packing POM, a podrzędne na JAR.
        Obecnie Eclipse wyświetla błąd z relative path (ale jest sporo tego w google, także pewnie uda mi się rozwiązać ten problem;) ).

        • Postaramy się uzupełnić lekcję wkrótce o to, jak dodawać moduły do istniejącego projektu oraz jak modyfikować taki projekt :) Dzięki za feedback!

      • Roman Lis

        Mam też dodatkowe pytanie.

        Po zaimportowaniu gotowego zadania mam 3 foldery (coś jak 3 projekty).
        1) Głowny z pom.xml i dwoma modułami -> odpalam run as i wyświetla mi się do wyboru maven build…. Następnie muszę podać ‚goals’ . Podając eclipse:eclipse niby przechodzi poprawnie, ale program (wyświetlanie kotów itp) nie odpala się.

        2) jest to koty-application -> odpalam go jako normalny java applet/application i tutaj wszystko wygląda tak jak na poprzednich wersjach (

  • Piotr

    Witam, potrzebowałem przekonwertować projekt na Maven’a.
    Czy będzie przeszkadzać w czymś gdy będę mieć na ikonce projektu M i J?

    Po ściągnięciu i zaimportowaniu odpowiedzi z Państwa projekcje ikonka nie ma tego J i mnie to zastanwia :)

    • Nie przeszkadza to w niczym – to tylko oznaczenia Eclipse na różne typy projektów (tzw. Facets) – o ile jest ‚M’ przy danym projekcie, powinien działać bez problemu :)

  • kkk2016

    Siedzę nad tym tydzien i nadal nie wiem o co chodzi. Wytłumaczcie to prosze lepiej, bo póki co, to ciężko jest się w tym połapać. Tworzę nowy moduł i pojawia się mi coś takego, jak na załączniku. Nie wiem, który artefakt mam wybrać. W folderach koty-domain i koty-application pojawiają się jakies klasy testowe, a w koncu po dodaniu modułu koty-webapp i uruchomieniu, pojawia się info, że koty-application nie istnieje (pomimo, ze dodałam zależnośc do koty-webapp)

    • Na pierwszym ekranie pominąłeś wybór ‚use simple archetype (skip archetype selection)’ – ta opcja pozwala pominąć wybór archetypu, co powinno rozwiązać też problem testowych klas.

      Jeśli chodzi o zależności – podeślij projekt spakowany do ZIPa, inaczej ciężko nam zdiagnozować co może być nie tak

      • kkk2016

        Uff, udało się mi przez to przebrnąć. Na razie wszystko działa. Dzięki :)

  • Anka

    Mozecie jasniej rozpisac po kolei kroki przy wykonywaniu zadania? Nie polapalam sie o co wam chodzi :/

    • Monika Senderecka

      Myślę że zadanie głównie polega na przejrzeniu dokumentacji technicznej, są tam artykuły które krok po kroku wyjaśniają te zagadnienia.

  • Monika Senderecka

    Witam, pracuję na Windowsie, czy powinnam czuć się zobowiązana do zrobienia tego zadania wyłącznie poprzez modyfikacje w pliku pom.xml?
    Żeby otworzyć jara posłużyłam się plikiem wykonywalnym.

    • Celem tej części zadania jest przećwiczenie konfiguracji pluginów – jest to coś zdecydowanie przydatnego w codziennej pracy, choć nie kluczowego na początku :)

  • Piotrek

    Hej. Mam pytanie do tego tematu odnośnie tworzenia nieco bardziej rozbudowanej Aplikacji. Czy jeśli mamy klasy domeny, klasę z main() i DAO. To Wszystkie klasy domeny upchać w „NazwaApki”-domain, a reszte klas czyli z main i DAO w „NazwaApki”- application?

    • To zależy jak sam zdecydujesz o podziale aplikacji, ale w ogólnym przypadku prawie tak (wyciągnąłbym klasę z main() do modułu np. -ui).
      Najprostszy podział wygląda mniej więcej następująco:
      * X-domain – klasy modelu, po prostu klasy do przechowywania i przekazywania danych
      * X-interfaces – opcjonalny moduł, ale może zawierać interfejsy serwisów udostępnianych na zewnątrz; w przypadku RESTowych serwisów ma to mniejsze znaczenie niż wcześniej, kiedy królowała technologia SOAP
      * X-application – tutaj trafia logika biznesowa, czyli to, co robi Twoja aplikacja
      * X-webapp / X-ui – tutaj trafiają rzeczy związane stricte z aplikacją webową lub interfejsem użytkownika

      W idealnym przypadku chodzi o to, że np. konsumując serwisy wystawiane przez Twoją aplikację albo pracując z tymi samymi danymi, inny projekt może po prostu dodać zależność do X-domain. Dzięki temu będzie miał dostępne wszystkie typy używane przez aplikacje, a jednocześnie nie będzie pobierał klas z logiką biznesową (co mogłoby prowadzić do nadużyć, nieudokumentowanych funkcji itp). Z kolei X-webapp i X-ui wydziela się do osobnego modułu (i oddziela od logiki aplikacji), ponieważ w większych projektach (weźmy np. system do e-bankingu) interfejs aplikacji (wraz z technologiami frontendowymi) zmienia się kilkukrotnie w ciągu całego życia aplikacji, jednak zasady działania pozostają te same. Oddzielenie części odpowiedzialnej za interakcje z użytkownikami od ‚głównej’ logiki systemu pozwala zaoszczędzić czas i wdrażać takie zmiany bezpiecznie (np. równolegle do rozwijania i poprawiania ‚starej’ wersji).

      Idąc dalej – prawie każdy ma minimalnie inny schemat, który w jakiś sposób jest powiązany z powyższym. Np. Netbeans sugeruje moduły EJB (coś w rodzaju webserwisów – interfejsy i domeny), Web i Application (https://netbeans.org/kb/docs/javaee/maven-entapp.html), Apache ma kilka przykładów bardziej skomplikowanych (np. http://maven.apache.org/archetype/maven-archetype-plugin/examples/create-multi-module-project.html – mamy ‚business domain model’, ‚business services’, ‚persistence layer’, ‚infrastructure’, ‚remoting’, ‚web services’, ‚web application’, ‚enterprise application’ – choć należy mieć na uwadze, że jest to tylko przykład do wyjaśnienia innych operacji, a nie ‚zalecana’ struktura). Jednym słowem – nie ma z góry ustalonego schematu i wiele firm wprowadza własny – ten uproszczony opisany powyżej powinien dać solidną podstawę do zrozumienia pochodnych i bardziej specyficznych schematów (a także powinien pomóc zorganizować własną aplikację)

      EDIT: kolejny przykład można znaleźć tutaj: https://github.com/sonatype/maven-example-en/blob/master/chapter-multimodule-web-spring.asciidoc

      • Piotrek

        Super! Dzięki za wyczerpujące wytłumaczenie :) Pytanie z serii stylistyczno-ciekawskich… W powyższej lekcji mówicie aby klasę z danymi wstawić do ——applictaion a w powyższym wyjaśnienu na odwrót ( tj. -domain ). to pomyłka czy zabieg ze względu na minimalistyczną wersje aplikacjia ‚koty’?
        Myli mi się również pojęcie domeny, ponieważ wydawało mi się że to w domenie umieszczamy „logike aplikacji”, a przechowywanie danych gdzie indziej.

  • karol

    Dołączę się do pytania kolegi.
    Jeśli robimy aplikację webową to wszystko co tyczy się www wrzucamy w „NazwaApki-webapp”? Czy dobrze to zrozumieliśmy.
    Początkowo to na pewno są nie potrzebne rozmyślania, ale każdy chciałby od razu robić prawidłowo.

    I moje pytanie dodatkowe:
    Jak tworzę nowy projekt Maven który jest rodzicem dla modułów domain application i webapp. W webapp archetyp webapp. Co robię nie tak, że mowo tworzoną klasę z pakietem wrzuca do src/main/resources? Powinno być w src/main/Java

    • Tak, do X-webapp powinno trafić wszystko, co jest związane tylko z warstwą webową :) Poniżej trochę szersza odpowiedź.
      Co do pytania dodatkowego – w IDE najprawdopodobniej możesz wybrać ‚katalog’, do którego ma trafić nowa klasa – np. w Eclipse można to zmienić w okienku ‚Create Java Class’ w polu ‚Source folder’: http://www.tutorialspoint.com/eclipse/images/new_java_class.jpg – pierwsze pole u góry. Raczej nie jest to związane z konfiguracją Mavena, a środowiska lokalnie :)

      • karol

        tak zmieniamy w tym miejscu o ile folder istnieje w projekcie:)
        Mam jeszcze problem z @Autowired kiedy jest dodane do kontrolera nie mogę odpalić projektu (po odpaleniu w przeglądarce wyskakuje strona 404), jak tylko usunę linijkę działa wyświetlenie prostej strony z komunikatem, ale z listą mam już problem:/

        • Możliwe, że to co próbujesz ‚pobrać’ poprzez Autowired nie jest zarządzane przez Springa – zerknij do logów, tam powinna być informacja co poszło nie tak. Najprawdopodobniej aplikacja nie uruchamia się, i stąd błąd 404. Możesz też podesłać kod – może uda nam się zerknąć, choć ostatnio bardzo krucho u nas z czasem ;)

    • karol

      Udało mi się wybrnąć tak, że w strukturze dodałem folder java następnie odświeżyłem drzewo katalogów w Eclipse i na koniec Maven > Update project

      • Super! Tak się czasem dzieje, jeśli pobierasz projekt np. z Git’a, a w danym katalogu nie ma żadnych plików – git po prostu ignoruje wtedy katalog.

  • W konsoli mam taki błąd:
    (…) Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [eu.karols.bookstore.BookDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. (…)
    I faktycznie – nad klasą BookDAO nie ma adnotacji @Repository (jest wykomentowana). Po jej odkomentowaniu aplikacja się uruchamia: http://prntscr.com/c5c61q

    Problemem było to, że przez @Autowired mówisz Springowi, że ma użyć beana tego typu – Spring jednak nie zarządza żadnym tego typu beanem (ponieważ brakowało adnotacji lub innej podpowiedzi dla Springa, żeby stworzył takiego beana), przez co wyrzucił błąd.

  • olekxd

    Witam, czy istnieje mozliwosc dodania jakiegos przykladu z zobrazowaniem tego jak sie poruszac po projekcie maven. Nigdy nie mialem z nim doczynienia i po przeczytaniu juz co nieco zarowno z oficjalnej strony jak i tych polecanych pod artykulem strasznie ciezko przychodzi mi jakis pozytywny rezultat. Skad w ogole ten plik depedency.reduced-pom.xml w folderze koty-application ?

  • wojtuś

    Hej zrobiłem wszystko wg kursu i pojawia mi się problem z którym nie mogę sobie poradzić, w jaki sposób mam skompilować aplikację żeby otrzymać plik .jar?. Run as -> maven build (jeśli tak to jakie goal ustawić), czy za pomocą wiersza poleceń tak jak jest to opisane?

    • wojtuś

      Udało mi się utworzyć plik .jar, wystarczyło w goal wpisać package (w eclipse) lub urzyć komendy mvn package, ale mam kolejny problem, nie mogę otworzyć pliku .jar

      • Aby móc ‚uruchomić’ plik JAR po prostu na niego klikając, musisz skonfigurować jeszcze plugin (zerknij do pliku pom.xml w rozwiązaniu) – dzięki temu w pliku JAR dodane zostaną odpowiednie metadane (np. plik MANIFEST.MF – więcej o nim znajdziesz np tutaj: https://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html), co pozwoli na jego uruchomienie.

        Możesz oczywiście samodzielnie taki plik dołaczyć do pliku JAR (jest to po prostu plik ZIP z innym rozszerzeniem) – szczegóły znajdziesz pod powyższym linkiem.

  • Dobry

    Wykonałem zadanie, program się kompiluje jednak mam problem z uruchomieniem pliku .jar – w konsoli leci błąd „no main manifest attribute(…)”. Jednocześnie zauważyłem, że w pliku pom.xml do artefaktu koty-application brakuje części składni, która widoczna jest w rozwiązaniu do zadania. Pytanie, czy coś pominąłem? Czy może ten fragment kodu powinien zostać wygenerowany automatycznie?

    Mój plik pom.xml: http://wklej.org/id/2887411/

    Tego w nim brakuje względem pliku z rozwiązania do zadania:

    org.apache.maven.plugins
    maven-shade-plugin
    2.4.1

    package

    shade

    pl.kobietydokodu.koty.Interfejs

    I jeszcze mam pytanie odnośnie struktury plików (screenshot), czy wszystko jest ok?

    https://uploads.disquscdn.com/images/1a090632701bc32989e93d6a90a3e57f6744a493e5f6bd70f6c5aa00fba92a45.png

    Z góry dziękuję za pomoc :)

    • Co do struktury – helloworldapp powinna być wewnątrz koty-application :) poza tym wygląda w porządku.

      Jeśli chodzi o różnice w pliku pom.xml – ten fragment trzeba dodać samodzielnie, jako element zadania. Można go znaleźć w wielu miejscach w internecie, i jest odpowiedzialny za właściwe przygotowanie pliku manifest (który z kolei Java wykorzystuje do uruchomienia właściwej klasy).

      • Dobry

        Dzięki za pomoc :) …jednak utknąłem na dobre. Walczę z tym od 3 dni, dzisiaj przepisałem projekt na nowo i wciąż nie mogę odpalić pliku JAR ze względu na komunikat: „Error: Could not find or load main class pl.kobietydokodu.koty.Interfejs”. Mógłbyś jeszcze raz rzucić okiem na moją strukturę plików (screenshot), ponieważ coś jest chyba nadal nie tak. Klasa Interfejs nie jest traktowana tak jakby zawierała metodę MAIN. Nie mam pojęcia czemu…

        Tutaj jest kod mojej klasy Interfejs: http://wklej.org/id/2891276/
        A tutaj zawartość pliku pom.xml dla artefaktu koty-application: http://wklej.org/id/2891277/
        Tutaj jest cały projekt: https://www.dropbox.com/s/rp7fcbnub0cfi8v/KobietyDoKodu.zip?dl=0

        Z góry bardzo dziękuję za pomoc

        https://uploads.disquscdn.com/images/8f7bf47d6e68ec7d336584372cdeaed54a4b58e80c301f4eb0e447cec8d57049.png

        • W strukturze projektu z jakiegoś powodu klasy masz umieszczone po prostu w głównym folderze modułu, a nie w src/main/java/… tak jak powinny być w projekcie Mavenowym. Z tego powodu IDE widzi te pliki tak, jakby były to pliki tekstowe a nie pliki Javy. Nie zauważyłem wcześniej z uwagi na to, że IDE czasem różnie grupują pliki i nie wyświetlają faktycznych katalogów tylko ‚logiczny’ podgląd.
          Poprawiłem strukturę plików, możesz pobrać tutaj: http://www.filedropper.com/kobietydokodu2 . W kodzie miałeś też kilka błędów – np. zamiast getImie() używałeś wywołania getImieKota() (także poprawione). Pozdrawiamy!

          • Dobry

            Dzięki wielkie! Jesteście MEGA! :)
            Jutro jadę dalej z tematem

  • rumc

    Witam mam prośbę o może trochę łopatologiczne wytłumaczenie krok po kroku tego zadania gdyż kompletnie nie wiem jak zacząć poza tym, że skonwertowałem swój projekt na maven project