Archiwum tagu ‘Eclipse’
Budowanie aplikacji za pomocą Mavena
Kiedy pisałem o instalacji Seama wspomniałem, o instalacji narzędzia Maven, które może mi się przydać w przyszłości. I oto nadeszła ta chwila. Czytając jakiś czas temu poradnik Developing a Spring Framework MVC application pomyślałem, że fajnie byłoby zamienić narzędzie do budowania projektu z Anta na Mavena, który zajmie się przy okazji zależnościami.
Korzystam z Eclipse‘a jako IDE więc do zabawy przydadzą mi się dwa pluginy:
- Spring IDE – Przyda się do utworzenia Hello World oraz na przyszłość;
- Maven Integration for Eclipse – Zautomatyzuje nam to trochę czynności oraz dostaniemy bardzo ładny edytor plików POM.
Po zainstalowaniu powyższych tworzymy zalążek projektu w Eclipse. Wybieramy File > New > Other a później Spring Project. Podajemy nazwę projektu, niech to jExample oraz zmieniamy lokalizację Source Folder Name z src na src/main/java a Output Folder Name z bin na target/classes. Zmiany te wynikają z domyślnych ustawień pluginów Mavena, z których będziemy korzystać.
W następnej kolejności aktywujemy zarządzanie projektem za pomocą Mavena. W tym celu wybieramy Maven Enable Dependency Managment po uprzednim kliknięciu prawym klawiszem myszy na projekcie.
Kluczowym elementem pracy z Mavenem jest plik POM, który stanowi konfigurację zawierającą informacje o projekcie, jego zależnościach, e.t.c. Kreator tworzenia pliku POM uruchomi się zaraz po aktywacji Mavena. Jedyną zmianą jakiej dokonujemy to zamiana pakowania projektu z jar na war. Oto plik, który będzie wynikiem:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jExample</groupId>
<artifactId>jExample</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
</project>
Utwórzmy teraz naprawdę bardzo prostą aplikację internetową. Niech jej jedyną funkcją będzie przywitanie nas słowami … Hello World. W pierwszej kolejności tworzymy deskryptory.
src/main/webapp/WEB-INF/web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>jExample</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jExample</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
src/main/webapp/WEB-INF/jExample-servlet.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean name="/index.html" class="pl.michalmech.jexample.web.HelloController"/>
</beans>
Oraz src/main/webapp/WEB-INF/applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
</beans>
Dodajemy jeszcze szybko widok (src/main/webapp/index.jsp):
<html>
<head>
<title>jExample</title>
</head>
<body>
<h1>jExample :: Hello World</h1>
</body>
</html>
Oraz na koniec niewielki kontroler:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class HelloController implements Controller {
protected final Log logger = LogFactory.getLog(getClass());
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
logger.info("Returninag hello view");
return new ModelAndView("index.jsp");
}
}
Niestety jedyne co ma dla nas Eclipse to błędy wynikające z braku klas, których potrzebujemy:
Jest to okazja do wykorzystania wreszcie Mavena, który dostarczy nam zależności, których potrzebujemy. Chcielibyśmy przede wszystkim skorzystać ze Spring MVC (niech to będzie najnowsza wersja) oraz API związanego z sewletami. Dodajemy do pliku POM następujący wpis (możemy oczywiście w tym celu użyć edytora plików POM):
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>

Zapisanie pliku sprawi, że Maven pobierze ze swojego lokalnego repozytorium wymagane zależności i dostarczy do projektu. W przypadku braku wymaganych paczek, zostaną one wcześniej pobrane z sieci (http://repo2.maven.org/maven2) oraz zainstalowane w repozytorium lokalnym Mavena. Warto zaznaczyć, że Maven dostarczył nam również inne wymagane pośrednio zależności: commons-logging, spring-core, e.t.c. My nie musimy się niczym martwić. Projekt już nie świeci się na czerwono od błędów.
W związku z tym, że dążymy do ujrzenia naszej aplikacji działającej przydałoby sie teraz utworzyć plik WAR. W tym celu wykonujemy w konsoli (będąc w loklizacji, w której znajduje się nasz projekt) polecenie:
mvn clean package
Wynikiem wykonania tego polecenia powinno być coś takiego:
F:\workspace\jExample>mvn clean package [INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Building Unnamed - jExample:jExample:war:0.0.1-SNAPSHOT [INFO] task-segment: [clean, package] [INFO] ------------------------------------------------------------------------ [INFO] [clean:clean] [INFO] Deleting directory F:\workspace\jExample\target [INFO] [resources:resources] [INFO] Using default encoding to copy filtered resources. [INFO] [compiler:compile] [INFO] Compiling 1 source file to F:\workspace\jExample\target\classes [INFO] [resources:testResources] [INFO] Using default encoding to copy filtered resources. [INFO] [compiler:testCompile] [INFO] No sources to compile [INFO] [surefire:test] [INFO] No tests to run. [INFO] [war:war] [INFO] Packaging webapp [INFO] Assembling webapp[jExample] in [F:\workspace\jExample\target\jExample-0.0.1-SNAPSHOT] [INFO] Processing war project [INFO] Webapp assembled in[171 msecs] [INFO] Building war: F:\workspace\jExample\target\jExample-0.0.1-SNAPSHOT.war [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 5 seconds [INFO] Finished at: Wed Apr 08 23:51:16 CEST 2009 [INFO] Final Memory: 11M/20M [INFO] ------------------------------------------------------------------------
Teraz krótkie wyjaśnienie. Maven w pierwszej kolejności wyczyścił wszystko to co mogło być do tej pory skompilowane i umieszczone w folderze target. Po to było polecenie clean. W dalszej części Maven zajmuje się pakowaniem projektu (polecenie package). Plan tej czynności zakłada wykonanie kilku czynności wcześniej. Jest to przede wszystkim kompilacja źródeł, zebranie zasobów, wykonanie testów jednostkowych oraz wreszcie zebranie wszystkiego do kupy w WAR Pomimo tego, że w tym przypadku niewiele faktycznie jest do zrobienia, Maven informuje nas o każdej czynności i wynikach jej wykonania.
Każda z czynności jest realizowana przez oddzielny plugin Mavena, który możemy w szczególności skonfigurować wedle naszych życzeń.
Do Hello World krzyczącego do nas z okna przeglądarki zostało bardzo niewiele. Podobnie jak w tutorialu, o którym wspomniałem na początku, my również skorzystamy z kontenera aplikacji Apache Tomcat (instalacja jest niezwykle prosta więc pominę jej opis).
Przy tej okazji chciałbym zwrócić uwagę na konfigurację zależności servlet-api. Przestrzeń (ang. scope) jest zdefiniowana jako provided. Dzieje się tak ponieważ Tomcat dostarcza już tą paczkę wśród swoich bibliotek więc aplikacja, która jest rozmieszczana (ang. deploy) na serwerze nie musi jej zawierać.
W folderze domowym instalacji Mavena, w folderze conf znajduje się plik z globalną konfiguracją: settings.xml. W bloku zawierającym definicje serwerów servers/servers dodajmy opis lokalnego Tomcata:
<server>
<id>tomcat.local</id>
<username>admin</username>
<password></password>
</server>
Identyfikator serwera jest dowolny natomiast login oraz hasło (a dokładniej jego brak) wynika z domyślnych wartości dla standardowej instalacji Tomcataa. Aby umieścić naszą aplikację na serwer skorzystamy z pluginu Tomcat Maven Plugin. Aby wykonać całą robotę, czyli kompilację, spakowanie oraz rozmieszczenie (ang. deploy) projektu na serwer wystarczy wykonać polecenie:
mvn clean package tomcat:deploy
W zasadzie to wystarczy ponieważ Maven pobierze ze swojego repozytorium i zainstaluje wspomniany plugin jak tylko będzie go potrzebował. Podczas wykonywania polecenia zobaczymy to w konsoli:
[INFO] Searching repository for plugin with prefix: 'tomcat'. [INFO] org.codehaus.mojo: checking for updates from central [INFO] artifact org.codehaus.mojo:tomcat-maven-plugin: checking for updates from central Downloading: http://repo1.maven.org/maven2/org/codehaus/mojo/tomcat-maven-plugin/1.0-beta-1/tomcat-maven-plugin-1.0-beta-1.pom 5K downloaded Downloading: http://repo1.maven.org/maven2/org/codehaus/mojo/mojo-parent/20/mojo-parent-20.pom 18K downloaded Downloading: http://repo1.maven.org/maven2/org/codehaus/mojo/tomcat-maven-plugin/1.0-beta-1/tomcat-maven-plugin-1.0-beta-1.jar 48K downloaded
Niemniej jednak gdybyśmy chcieli wskazać jakieś inne repozytorium, które Maven ma przeszukiwać w chwili kiedy czegoś potrzebuje, możemy je zdefiniować w pliku POM:
<repositories>
<repository>
<id>mojo</id>
<name>Mojo Project</name>
<url>http://repository.codehaus.org</url>
</repository>
</repositories>
Podobnie ma się rzecz z uruchomieniem plugin. Użyta będzie domyślna konfiguracja. Aby ją zmienić powinniśmy odpowiednio zmodyfikować POM. Oto przykład jak jawnie podać nazwę serwera, na którym umieszczamy (ang. deploy) aplikację:
<build>
<plugins>
<plugin>
<groupid>org.codehaus.mojo</groupid>
<artifactid>tomcat-maven-plugin</artifactid>
<configuration>
<server>tomcat.local</server>
</configuration>
</plugin>
</plugins>
</build>
Konfiguracja oczywiście będzie będzie wzięta z ustawień globalnych Mavena.
W zasadzie to wszystko. Wykonanie wspomnianego polecenia (mvn clean package tomcat:deploy) powinno dać następujący wynik:
... [INFO] Building war: F:\workspace\jExample\target\jExample-0.0.1-SNAPSHOT.war [INFO] [tomcat:deploy] [INFO] Deploying war to http://localhost:8080/jExample [INFO] OK - Deployed application at context path /jExample [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------
Uruchomienie w przeglądarce adresu http://localhost:8080/jExample/index.html pozwoli nam upewniść się, że aplikacja działa.
To co opisałem, to zaledwie kropla w morzu możliwości Mavena, który posiada ich oczywiście dużo więcej, dzięki różnorodnym pluginom. Możemy dzięki niemu nie tylko zarządzać budowaniem projektu i zależnościami ale również generować dokumentację czy nawet sprawdzać styl kodowania.
JBoss Tools – wsparcie dla Seam’a w Eclipse
W poprzednim poście utworzyłem pierwszy projekt (HelloWorld) za pomocą seam-gen. Spróbujmy teraz skonfigurować sobie środowisko dla tego oraz innych projektów Seam‘owych.
Firma JBoss przyszła nam z pomocą i stworzyła JBoss Tools, czyli zestaw narzędzi dla Eclipse, które wspomagają pracę z frameworkiem JBoss Seam. Najszybszy sposób instalacji narzędzi wiedzie nas przez Update Manager’a, gdzie podajemy odpowiedni link i instalujemy wybrane narzędzia. Zestaw JBoss Tools poza wsparcie dla Seam’a zawiera narzędzia pomocne przy pracy między innymi z jBPM, Hibernate, Struts. Jeśli mamy już zainstalowany pakiet JBoss Tools, zabieramy się do pracy.
W pierwszej kolejności importujemy projekt do Eclipse’a. Wybieramy File > Import > Existing Projects into Workspace i szukamy projektu. Po poprawnym imporcie projekt HelloWorld powinien pojawić się w naszym eksploratorze paczek (ang. Package Explorer).
Następnie przełączamy perspektywę na Seam i przechodzimy do konfiguracji projektu. W sekcji Seam Settings w pierwszej kolejności zaznaczamy Seam support dalej przechodzimy do konfiguracji środowiska uruchomieniowego JBoss Seam – Seam runtime. W tym celu klikamy Add i w oknie, które się pojawi podajemy folder domowy Seam’a (C:\Program Files\JBoss-seam-2.1.1.GA), nazwę konfiguracji (np.: Seam runtime) oraz wersję frameworka (2.0).
W dalszej kolejności dodajemy i konfigurujemy połączenie z bazą danych projektu (Connection profile). Klikamy New… i w okienku podajemy wszystkie wymagane dane takie jak nazwę połączenia (np.: hello database) typ bazy, dane do połączenia, ścieżkę do sterownika, e.t.c. Poniżej prezentuję zrzut ekranu ukazujący ustawienia dla mojego projektu.
Pakiet narzędzi JBoss Tools pozwala również na utworzenie projektu bez korzystania z seam-gen‘a. Wybieramy File > New > Seam Web Project. Kreator przeprowadzi nas przez proces konfiguracji projektu podczas, którego możemy utworzyć konfigurację serwera, połączenia do bazy danych i środowiska uruchomieniowego.
Dzięki JBoss Tools mamy możliwość szybkiego tworzenia encji, akcji, konwersacji, e.t.c. Narzędzie to jest między innymi nakładką na seam-gen’a. Ponadto dostajemy kilka dodatkowych edytorów (np.: dla facelets) oraz ładne widoki deskryptorów. Postaram się dostarczać więcej informacji wraz z poznawaniem JBoss Tools’ów.
Instalacja frameworka JBoss Seam
Pierwszą czynnością wymaganą do nauki frameworka JBoss Seam jest oczywiście jego instalacja. Framework to tylko narzędzie służące do budowania aplikacji, które przecież działają w jakimś środowisku, zaczniemy więc od instalacji środowiska, zarówno uruchomieniowego jak i środowiska programistycznego (Integrated Development Environment). Ja wybrałem serwer a JBoss, jako serwer aplikacji oraz Eclipse jako moje IDE. Instalację Eclipse’a pominę, skupię się na instalacji JBoss’a oraz JBoss Seam’a. Wszystkie opisy dotyczą systemu Windows.
Instalację serwera JBoss przeprowadzamy za pomocą JEMS Installer. Jest to narzędzie, służące do instalacji wszelkich produktów firmy JBoss. Aby uruchomić instalator wystarczy pobrać i uruchomić najnowszy plik JAR (w chwili pisania tego tekstu jest to plik 1.2.1.CR4.jar) lub uruchomić go poprzez Java Web Start.
Pierwszym etapem instalacji jest ekran powitalny, na którym śmiało klikamy Next. Proces instalacji jest rozłożony na 17 ekranów i na niemal wszystkich zachowujemy domyślne, zaznaczone opcje i klikamy Next.
Jedynym odstępstwem od “domyślna wartość + Next” jakie poczyniłem to miejscem instalacji serwera uczyniłem lokalizację C:Program FilesJBoss-4.2.2.GA.
Po instalacji serwera JBoss należy ustawić zmienną środowiskową JBOSS_HOME. Jak łatwo się domyślić powinna to być ścieżka wskazująca na zainstalowany serwer. U mnie jest to C:Program FilesJBoss-4.2.2.GA. Na tym etapie warto ustawić zmienną środowiskową JAVA_HOME i jako wartość podać lokalizacją, w której zainstalowaliśmy Javę. U mnie zmienna ta ma wartość C:Program FilesJavajdk1.6.0_07
Pozostaje nam teraz uruchomić serwer wykonując polecenie:
C:\Program Files\JBoss-4.2.2.GA\bin>run
Po uruchomieniu serwera wpisujemy w przeglądarce adres http://localhost:8080. Powinniśmy ujrzeć stronę, której zrzut prezentuję obok.
Kolejnym etapem jest instalacja frameworka JBoss Seam. Słowo instalacja jest tutaj mocno nad wyraz ponieważ cały proces polega na pobraniu archiwum (w chwili pisania tego tekstu najnowszym plikiem był jboss-seam-2.1.1.GA.zip) i rozpakowaniu jego zawartości w wybranym przez nas miejscu. Ja wybrałem lokalizację C:Program FilesJBoss-seam-2.1.1.GA.
Do pracy będzie potrzebny również Anta. Pobieramy wersję 1.7.0 (w chwili pisania tego tekstu najnowszy jest jest to najnowsza wersja akceptowana przez Seam’a). Odradzam instalowanie wersji 1.7.1. Seam może nas później ukarać komunikatem:
You are using Apache Ant version 1.7.1 compiled on June 27 2008. You must use Ant 1.7.0 to build Seam. Ant 1.7.1 has known bugs.
Rozpakowujemy zawartość archiwum (apache-ant-1.7.0-bin.zip) w wybranym przez nas miejscu. Ja zdecydowałem się na C:Program FilesApache Software FoundationAnt. Przyda nam się zmienna środowiskowa ANT_HOME. Jej wartość w moim przypadku to oczywiście C:Program FilesApache Software FoundationAnt. Aby polecenie ant było dostępne należy do zmiennej środowiskowej Path dodać %ANT_HOME%/bin
Wykonanie polecenia:
ant -version
powinno spowodować wyświetlenie:
Apache Ant version 1.7.0 compiled on December 13 2006
Na przyszłość zainstalowałem sobie Mavena. Procedura identyczna jak w przypadku Anta. Pobieramy archiwum z binarkami i rozpakowujemy je do wybranej lokalizacji (u mnie jest to C:Program FilesApache Software FoundationMaven 2) oraz tworzymy zmienną środowiskową MAVEN_HOME (o wartości C:Program FilesApache Software FoundationMaven 2) a do zmiennej Path dodajemy %MAVEN_HOME%/bin
Polecenie:
mvn -version
powinno poskutkować wyświetleniem się:
Maven version: 2.1.0-M1 Java version: 1.6.0_07 Default locale: pl_PL, platform encoding: Cp1250 OS name: "windows xp" version: "5.1" arch: "x86" family: "windows"
Super! Mamy wszystko czego trzeba. Spróbujmy uruchomić jeden z przykładów dostarczonych razem z frameworkiem JBoss Seam. Przechodzimy do folderu examples/booking w folderze domowym Seam’a i uruchamiamy w konsoli polecenie:
ant deploy
Wynik tego polecenia to:
Buildfile: build.xml initcopy: initpoms: [echo] Setting up dependencies [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [artifact:install] [INFO] Installing C:Program FilesJBoss-seam-2.1.1.GAclassespomsroot.pom to C:Documents and SettingsMike.m2repositoryorgjbossseamroot2.1.1.GAroot-2.1.1.GA.pom [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [artifact:install] [INFO] Installing C:Program FilesJBoss-seam-2.1.1.GAclassespomsparent.pom to C:Documents and SettingsMike.m2repositoryorgjbossseamparent2.1.1.GAparent-2.1.1.GA.pom [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms [copy] Copying 1 file to C:Program FilesJBoss-seam-2.1.1.GAclassespoms copyseam: copyseamdependencies: gettrinidad: getelri: copyextradependencies: init: [echo] Building Seam on JBoss Booking Example 2.1 select-compiler: compile: jar: init.war: war: jboss.war: distributable.war: ear: archive: datasource: service: meldware: deploy: BUILD SUCCESSFUL Total time: 6 seconds
Jak widać wszystko poszło bez zakłóceń. W przeglądarce wpisujemy adres http://localhost:8080/seam-booking i cieszymy się pierwszą aplikacją napisaną w JBoss Seam, którą udało na się uruchomić.


