Wrzesień
17
2009

Projekt seam-gen

Słowa kluczowe: , , , , | Kategorie: Seam Framework
No Gravatar

Obiecałem omówić TDD w Seam Framework, ale po drodze napotkałem kilka istotnych problemów. Wszystkie błędy oraz ich eliminacja były związane ze sposobem zarządzania plikami projektu. Sprawiło to, że postanowiłem opisać proces rozwoju nowego projektu od samego początku.

Dotąd opisałem jedynie tworzenie projektu Seam z wykorzystaniem JBoss Tools, jednak od dość dawna pracuję z systemem Ubuntu i używam generatora seam-gen.

Instalacja

Nie instalowałem ani serwera JBoss, ani Seam Framework – rozpakowałem pobrane archiwa odpowiednio do katalogów: /home/slawek/jboss/home/slawek/seam. Apache Ant, JDK 1.6 oraz PostgreSQL zostały zainstalowane z repozytorium pakietów Ubuntu. Jeżeli dobrze pamiętam, były to następujące metapaczki:

sudo aptitude install ant sun-java6-jdk postgresql-8.3

Konfiguracja seam-gen

Automatyczne generowanie nowego projektu seam-gen można podzielić na dwa etapy – konfigurację i utworzenie. Pierwszy z nich realizuje się za pomocą polecenia:

slawek@localhost:~/seam$ ./seam setup
SEAM_HOME: /home/slawek/seam
Using seam-gen sources from: /home/slawek/seam/seam-gen
Buildfile: /home/slawek/seam/seam-gen/build.xml

init:

setup:
     [echo] Welcome to seam-gen :-)

Dla MS Windows polecenie będzie mniej więcej tak:

C:\seam> seam.bat setup

Teraz następuje seria pytań dotyczących ustawień nowego projektu. Na początku należy podać katalog, zawierający projekty Seam. W moim przypadku będzie to:

    [input] Enter your Java project workspace (the directory that
contains your Seam projects) [] []
/home/slawek/java

Następnie należy wskazać ścieżkę do katalogu głównego serwera JBoss:

    [input] Enter your JBoss AS home directory [] []
/home/slawek/jboss

Teraz podaję nazwę projektu – będzie to projekt przykładowy, wykorzystywany na blogu:

    [input] Enter the project name [blog] [blog]
blog
     [echo] Accepted project name as: blog

Następnie seam-gen proponuje użycie biblioteki ICEfaces zamiast RichFaces. Grzecznie odmawiam:

    [input] Do you want to use ICEfaces instead of RichFaces [n] (y, [n])
n
    [input] skipping input as property icefaces.home.new has already been set.

Przy wyborze motywu graficznego strony, wskazuję domyślny:

    [input] Select a RichFaces skin [DEFAULT] (blueSky, classic,
deepMarine, [DEFAULT], emeraldTown, japanCherry, ruby, wine)
DEFAULT

Kolejne pytanie brzmi, czy projekt ma być rozmieszczany na serwerze w postaci archiwum EAR, czy może WAR. W drugim przypadku utraciłbym wsparcie dla komponentów EJB, zatem wybieram:

    [input] Is this project deployed as an EAR (with EJB components)
or a WAR (with no EJB support) [ear] ([ear], war)
ear

Teraz muszę zdefiniować domyślne pakiety dla klas generowanych z użyciem seam-gen. Osobno dla komponentów:

    [input] Enter the Java package name for your session beans [] []
pl.info.czerwinski

dla encji:

    [input] Enter the Java package name for your entity beans [] []
pl.info.czerwinski

i dla testów:

    [input] Enter the Java package name for your test cases [] []
pl.info.czerwinski

Przy wyborze bazy danych, seam-gen daje szeroki wachlarz możliwości. Ja korzystam z PostgreSQL:

    [input] What kind of database are you using? [postgres]
(hsql, mysql, oracle, [postgres], mssql, db2, sybase, enterprisedb, h2)
postgres

Hibernate potrzebuje klasy zawierającej bardziej szczegółowe informacje na temat wspieranego przez bazę danych dialektu SQL:

    [input] Enter the Hibernate dialect for your database [] []
org.hibernate.dialect.PostgreSQLDialect

Przyda się też archiwum zawierające sterownik JDBC:

    [input] Enter the filesystem path to the JDBC driver jar [] []
/home/slawek/java/postgresql-8.3-604.jdbc4.jar

oraz klasa samego sterownika:

    [input] Enter JDBC driver class for your database [] []
org.postgresql.Driver

Następnie seam-gen prosi o podanie URL do bazy danych. W przypadku lokalnej bazy PostgreSQL jest to jdbc:postgresql:[NAZWA_BAZY]:

    [input] Enter the JDBC URL for your database [] []
jdbc:postgresql:blog

Następnie podaję nazwę użytkownika bazy:

    [input] Enter database username [] []
blog

oraz hasło:

    [input] Enter database password [] []
blog

Domyślny schemat bazy danych ustawiam na public:

    [input] Enter the database schema name (it is OK to leave this blank)
[] []
public

Katalog pozostawiam pusty:

    [input] Enter the database catalog name (it is OK to leave this blank)
[] []

Teraz dwa pytania dotyczące działań, jakie Hibernate ma podjąć w momencie rozmieszczenia aplikacji na serwerze. Jeżeli tablice nie istnieją jeszcze w bazie danych, zostaną one utworzone na podstawie mapowania klas encji. Dlatego odpowiadam:

    [input] Are you working with tables that already exist
in the database? [n] (y, [n])
n

Następne pytanie dotyczy każdego ponownego rozmieszczenia projektu na serwerze – seam-gen pyta, czy w takiej sytuacji ma usunąć wszystkie dane i utworzyć je ponownie na podstawie mapowania. Na etapie rozwijania projektu jest to przydatne, więc wybieram:

    [input] Do you want to drop and recreate the database tables
and data in import.sql each time you deploy? [y] ([y], n)
y

To już było ostatnie pytanie. Teraz jeszcze powinny pojawić się komunikaty o następującej treści:

[propertyfile] Creating new property file:
/home/slawek/seam/seam-gen/build.properties
     [echo] Installing JDBC driver jar to JBoss AS
     [echo] Type './seam create-project' to create the new project

BUILD SUCCESSFUL
Total time: 1 minute 47 seconds
slawek@localhost:~/seam$ 

Cała konfiguracja została zapisana do pliku ~/seam/seam-gen/build.properties i w każdej chwili można zmienić dowolne ustawienia edytując tenże.

Utworzenie projektu

Aby utworzyć projekt, należy ponownie uruchomić skrypt seam – tym razem z parametrem create-project:


slawek@localhost:~/seam$ ./seam create-project
SEAM_HOME: /home/slawek/seam
Using seam-gen sources from: /home/slawek/seam/seam-gen
Buildfile: /home/slawek/seam/seam-gen/build.xml

[…]

BUILD SUCCESSFUL
Total time: 6 seconds
slawek@localhost:~/seam$

Podobny efekt można uzyskać za pomocą polecenia ant:


slawek@localhost:~/seam$ cd seam-gen
slawek@localhost:~/seam/seam-gen$ ant create-project

Projekt jest utworzony już po kilku sekundach.

Skrót do bibliotek

Chcę uniknąć kopiowania bibliotek do każdego projektu, aby oszczędzić trochę miejsca na dysku. Dlatego postanowiłem utworzyć w katalogu z projektami nowy katalog lib, zawierający wszystkie biblioteki Seam oraz JDBC:


slawek@localhost:~/java$ cp /home/slawek/seam/lib .
slawek@localhost:~/java$ cp postgresql-8.3-604.jdbc4.jar ./lib

Z każdego nowego projektu będę usuwał wygenerowany katalog lib, a następnie tworzył dowiązanie symboliczne (pod MS Windows byłby to zwykły skrót do folderu) do katalogu utworzonego wcześniej:

slawek@localhost:~/java$ cd blog
slawek@localhost:~/java/blog$ rm -rf lib
slawek@localhost:~/java/blog$ ln -s /home/slawek/java/lib/ .

Teraz nie muszę się już martwić dodawaniem brakujących plików JAR ani zużywaniem wolnej przestrzeni dyskowej.

Dodanie biblioteki jaxrs-api

W Seam Framework 2.1 występuje pewien dość dziwny błąd. Aby go wyeliminować, wystarczy dodać do pliku deployed-jars-ear.list następującą linijkę:

jaxrs-api.jar

Zmiana położenia klas dla testów

Niestety utworzenie jednego katalogu ze wszystkimi bibliotekami sprawia pewne problemy przy uruchamianiu testów. Klasy należące do Apache Wicket znajdują się w kilku archiwach, przez co występują konflikty. Oczywiście można usunąć wszystkie pliki wicket*.jar z katalogu lib, ale bezpieczniej będzie dokonać pewnych zmian w build.xml.

Najpierw utworzę plik zawierający listę bibliotek dołączanych w trakcie uruchamiania testów. Pod Linuxem można to zrobić za pomocą polecenia ls:


slawek@localhost:~/java/blog$ cd lib
slawek@localhost:~/java/blog/lib$ ls *.jar > classpath-jars-test.list
slawek@localhost:~/java/blog/lib$ cd ..
slawek@localhost:~/java/blog$ mv lib/classpath-jars-test.list .

Pod MS Windows przypuszczalnie użyłbym dir z odpowiednimi parametrami.

Oczywiście z listy należy usunąć wszystkie wpisy zaczynające się od wicket.

build.xml definiuję nowy zestaw plików, pobierany z pliku classpath-jars-test.list – tuż przed pierwszym znacznikiem target:

[…]

<fileset id="test.lib" dir="${lib.dir}">
  <includesfile name="classpath-jars-test.list"/>
</fileset>

<path id="test.classpath">
  <fileset refid="test.lib"/>
</path>

<target name="init" […]

Przy uruchamianiu testów (target name="test") trzeba wykorzystać nowo utworzoną ścieżkę test.classpath zamiast build.classpath (linia 12):


<target
    name="test"
    depends="buildtest"
    description="Run the tests">
[…]
  <path id="test.path">
    <path path="${test.dir}"/>
    <fileset dir="${lib.dir}/test">
      <include name="*.jar"/>
    </fileset>
    <path path="${bootstrap.dir}"/>
    <path refid="test.classpath"/>
  </path>
[…]
</target>

Teraz, niezależnie od zawartości katalogu lib na komputerach różnych programistów, testy powinny działać tak samo.

Ant

Kompilacja, budowanie czy testowanie projektu wykonywane są za pomocą Apache Ant. Aby wykonać jakąś czynność, należy wpisać ant [NAZWA_ZADANIA].

Najważniejsze zadanie to zbudowanie i rozmieszczenie na serwerze gotowej aplikacji:


slawek@localhost:~/java/blog$ ant explode

W celu uruchomienia testów automatycznych, należy uruchomić:


slawek@localhost:~/java/blog$ ant test

Czyszczenie odbywa się w dwóch etapach. Pierwszym jest usunięcie odpowiednich katalogów z projektu:


slawek@localhost:~/java/blog$ ant clean
Buildfile: build.xml

clean:
   [delete] Deleting directory /home/slawek/java/blog/dist
   [delete] Deleting directory /home/slawek/java/blog/exploded-archives
   [delete] Deleting directory /home/slawek/java/blog/test-report

BUILD SUCCESSFUL
Total time: 0 seconds
slawek@localhost:~/java/blog$

Drugim zadaniem jest usunięcie aplikacji z serwera:


slawek@localhost:~/java/blog$ ant unexplode
Buildfile: build.xml

unexplode:
   [delete] Deleting:
/home/slawek/jboss/server/default/deploy/blog-ds.xml
   [delete] Deleting directory
/home/slawek/jboss/server/default/deploy/blog.ear

BUILD SUCCESSFUL
Total time: 0 seconds
slawek@localhost:~/java/blog$

Skoro już utworzyłem nowy projekt seam-gen, wreszcie jestem gotów na testy – już w kolejnym wpisie.

Napisz Komentarz

*