Michał Mech – W stronę Java

Zapiski programisty

Archiwum tagu ‘JBoss Seam’

Reguły nawigacji w deskryptorze stron Seam’a

brak komentarzy

We wprowadzeniu do dokumentacji frameworka JBoss Seam twórcy podkreślają, że uciekają jak tylko się da od konfiguracji za pomocą plików XML na rzecz przekazywania informacji do kontenera za pomocą adnotacji. Nie mniej jednak każdy projekt napisany z pomocą Seam’a zawiera kilka plików konfiguracyjnych, jednym z nich jest deskryptor stron: pages.xml.

W pliku deskryptora (znajduje się on wewnątrz folderu WEB-INF) mamy możliwość definiowania naturalnych konwersacji (ang. natural conversation), stron błędów dla wyjątków (ang. exception handling) oraz zasad nawigacji dla stron (ang. page navigation). Ja skupię się na nawigacji.

Pusty deskryptor (zawierający jedynie węzeł główny) wygląda następująco:

<?xml version="1.0" encoding="UTF-8"?>
<pages xmlns="http://jboss.com/products/seam/pages"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://jboss.com/products/seam/pages
        http://jboss.com/products/seam/pages-2.1.xsd">
</pages>

W deskryptorze możemy umieścić dowolną ilość węzów <page>, które stanowią definicję stron. Podstawowa definicja strony to podanie jej identyfikatora. Definicja taka wiele nie wnosi więc podam od razu przykład jak zdefiniować akcję dla strony (ang. page action):

<page view-id="/testPage.xhtml" action="#{testComponent.sampleAction}"/>

Tak podana definicja spowoduje wykonanie akcji sampleAction komponentu testComponent tuż przed wyrenderowaniem strony testPage. Oczywiście zawsze istnieje możliwość wykonania kilku akcji (także z różnych komponentów) na okoliczność żądania strony samplePage.xhtml:

<page view-id="/testPage.xhtml">
    <action execute="#{testComponent.sampleAction}"/>
    <action execute="#{testComponent.sayHello}"/>
</page>

Wykonanie akcji możemy obwarować warunkiem logicznym (zapisanym oczywiście za pomocą języka EL). Służy do tego opcjonalny atrybut if, na przykład:

<page view-id="/testPage.xhtml">
    <action execute="#{testComponent.sampleAction}"/>
    <action if="#{identity.isLoggedIn}" execute="#{testComponent.sayHello}"/>
</page>

Akcje wykonywane są w kolejności zapisania ich w pliku. Ważne jest to by pamiętać o tym, że po każdej akcji realizowane są reguły nawigacji dla strony, co oznacza, że koniec końców nie każda akcja może mieć szanse uruchomienia. A wspomniane reguły definiuje się następująco:

<page view-id="/testPage.xhtml">
    <action execute="#{testComponent.sayHello}"/>
    <action execute="#{testComponent.sayHi}"/>

    <navigation>
        <rule if-outcome="hello">
            <render view-id="/home.xhtml"/>
        </rule>
        <rule if-outcome="hi">
            <redirect view-id="/login.xhtml"/>
        </rule>
    </navigation>
</page>

Każda akcja może zwrócić wartość, wynik (ang. outcome). To właśnie ta wartość posłuży to testowania zasad nawigacji dla strony. Niech komponent testComponent, do którego odwołania występują w przykładach wygląda tak:

@Name("testComponent")
public class TestComponent {
    @Logger private Log log;

    public String sayHello() {
        log.info("akcja sayHello zwraca outcome hello");
        return "hello";
    }

    public String sayHi() {
        log.info("akcja sayHi zwraca outcome hi");
        return "hi";
    }
}

Prześledźmy sytuację. Jeśli zażądamy strony testPage.xhtml, wykonana zostanie akcja sayHello(), której outcome to hello. W tej sytuacji wyrenderowana zostanie strona home.xhtml, co zmieni podmiot odwołania i akcja sayHi() nie będzie miała okazji się uruchomić. Wystarczy jednak zmienić kolejność akcji w pliku aby nastąpiło przekierowanie na stronę logowania – login.xhtml. Osiągniemy to jeśli najpierw wykona się sayHi():

<page view-id="/testPage.xhtml">
    <action execute="#{testComponent.sayHi}"/>
    <action execute="#{testComponent.sayHello}"/>

    <!-- ... -- >
</page>

Podobnie jak w przypadku akcji, reguły nawigacji możemy również obwarować kilkoma obostrzeniami. Przede wszystkim możemy uzależnić wszystkie reguły nawigacji od tego czy to konkretna akcje została wykonana:

<page view-id="/testPage.xhtml">
    <!-- ... -- >

    <navigation from-action="#{testComponent.sayHi}">
        <rule if-outcome="hello">
            <render view-id="/home.xhtml"/>
        </rule>
        <rule if-outcome="hi">
            <redirect view-id="/login.xhtml"/>
        </rule>
    </navigation>
</page>

Powyższy zapis sprawi, że reguły nawigacji zostaną uwzględnione tylko po wykonaniu akcji sayHi(). To pozwala na zdefiniowanie kilku bloków nawigacji, zależnych od wykonywanych akcji. Dodatkowo możemy w atrybucie evaluate dla elementu navigation umieścić dowolne wyrażenie (EL), które ma być wykonane.

Do każdej z zasad nawigacji możemy dodać warunek logiczny, który zostanie sprawdzony tuż obok sprawdzania outcome. Na przykład:

<rule if="#{identity.isLoggedIn}" if-outcome="hello">
    <render view-id="/home.xhtml"/>
</rule>

Deskryptor pages.xml ma również szereg innych możliwości. Jedną z nich jest możliwość nakładania restrykcji na strony. Możemy żądać bycia zalogowanym oraz dodać metodę sprawdzającą dowolną inną rzecz, zdefiniowaną w zewnętrznym komponencie:

<page view-id="/testPage.xhtml" login-required="false">
    <restrict>#{testComponent.checkMe()}</restrict>
</page>

W przypadku niespełnienia jednego z tych warunków zostanie wyrzucony wyjątek org.jboss.seam.security.NotLoggedInException.

UntitledW zasadzie to wszystko co dotyczy nawigacji. Na początku wspomniałem, że pominę konwersacje i skupię się na samym aspekcie nawigacji należy jednak dodać, że pomijając definiowanie naturalnych konwersacji deskryptor daje nam spore możliwości manipulowania konwersacjami wewnątrz mechanizmu nawigacji. Możemy rozpoczynać konwersacje, kończyć je, łączyć z innymi i nie tylko. Możemy również określać parametry stron, reguły ich przekazywania oraz zgłaszać wyjątki czy rozpoczynać lub kończyć zadania w ramach jBPM. Dostępnych jest szereg możliwości, o których na pewno poinformuje nas Eclipse a które ja po zgłębieniu być może opiszę :-)

Na koniec mała podpowiedź, którą pokazuje zamieszczony powyżej zrzut ekranu. Duży projekt, zwierający wiele stron i znaczną ilość definicji bardzo rozepchałby deskryptor stron. Aby zwiększyć czytelność i przejrzystość konfiguracji mamy możliwość zdefiniowana dla każdej strony oddzielnego pliku o nazwie *.page.xml, gdzie * oznacza identyfikator strony. W przykładach posługiwałem się stroną testPage, plik dla tej strony nazwyałby się testPage.page.xml

Opublikowany przez Michał Mech

2009-03-01 o 15:41:00

Kategorie Java, Programowanie

Tagi

Wstrzykiwanie zależności – serce Seam’a

Ilość komentarzy: 4

We wstępie do dokumentacji autorzy frameworka JBoss Seam piszą, że jednym ze wzorców, którym hołdowali budując Seam’a jest wstrzykiwanie zależności (ang. Dependency Injection, DI). Wzorzec DI został nie tylko zastosowany w Seam’ie ale również rozszerzony i nazwany Bijection.

Bijection od DI różnią trzy cechy:

  1. contextual – wstrzykiwane do komponentów zależności są wybierane z odpowiedniego kontekstu w jakim występują. Seam posiada kilka kontekstów i zanim wstrzyknie zależność do komponentu szuka jej w odpowiednim miejscu;
  2. bidirectional – mechanizm Bijection pozwala nie tylko na wstrzykiwanie zależności do komponentów ale również na wystrzeliwanie ich na zewnątrz do dowolnego kontekstu;
  3. dynamic – twórcy Seam’a gwarantują, że mechanizm Bijection jest bardziej elastyczny.

Autorzy Seam’a wyżej cenią adnotacje niż konfigurację za pomocą XML‘a, stąd właśnie one posłużą nam informowaniu kontenera o zależnościach między komponentami i jak powinny być one wstrzykiwane i wystrzeliwane.

Za mechanizm bijection odpowiedzialne są dwie adnotacje: @In i @Out. Lecz, żeby dobrze je zrozumieć zacznijmy od prostej adnotacji @Name. Za pomocą @Name możemy nadać nazwę dowolnemu komponentowi w aplikacji. Nazwa musi być unikalna dla całej aplikacji. Krótki przykład zastosowania:

@Entity
@Name("article")
public class Article implements Serializable {

    private long id;

    private String title;

    ...
}

Jeśli jakiś komponent (lub nawet JSF) odwoła się do obiektu o nazwie article, Seam przeszuka obowiązujący kontekst i dostarczy zależność. W powyższym przykładzie mamy jeszcze adnotację @Entity, która w opisywanym zagadnieniu nie gra większej roli. Wskazuje ona, że klasa jest encją reprezentującą trwały obiekt w bazie danych.

Przejdźmy teraz do wstrzykiwania i wystrzeliwania zależności. Oto komponent sesyjny (ang. Session Bean), który wykona dla nas trochę logiki biznesowej:

@Stateless
@Name("paper")
public class PaperAction implements Paper {
    @In @Out
    private Article article;

    @Out
    private List lt;Articlegt; articles;

    @PersistenceContext
    private EntityManager em;

    public String addArticle () {
        em.persist (article);
        article = new Article ();

        articles = em.createQuery("select a from Article a")
            .getResultList();

        return null;
    }
}

Adnotacja @Stateless informuje nas, że komponent jest bezstanowy co oznacza, że będzie tworzony od nowa za każdym razem kiedy kontener zostanie poproszony o jego dostarczenie. Nazwą komponentu (określoną przez adnotację @Name) jest paper.

Skupmy się teraz na zależnościach. Widzimy przy polu article adnotację @In. Oznacza to, że zanim zostanie wykonana jakakolwiek metoda komponentu, kontener ma wstrzyknąć do tego pola zależność o nazwie article. Jeśli chcemy do pola article wstrzyknąć zależność o innej nazwie niż pole powinniśmy do adnotacji dodać parametr value, np.: @In(value=”favoriteArticle”) (Adnotacja @In oraz @Out posiada kilka innych prostych parametrów. Polecam zapoznanie się z nimi.) Oczywiście komponent może zawierać dowolną ilość elementów z adnotacją @In. Pamiętać należy o tym, że za każdym razem będą one wstrzykiwane.

W dalszej kolejności widzimy adnotacje @Out, opisujące pola article oraz articles. Oznaczają one, że po zakończeniu pracy komponentu kontener powinien pobrać zawartość tych oraz umieścić w odpowiednich kontekstach. Obiekty te, będą teraz dostępne dla innych komponentów. Zostaną wystrzelone na zewnątrz komponentu.

Komponent paper zawiera jeszcze jedną adnotację: @PersistenceContext. Informuje ona, że do opisanego za jej pomocą pola kontener ma wstrzyknąć managera encji. Podobnie jak w przypadku @Entity nie jest to w tej chwili meritum sprawy.

Jedyna metoda komponentu addArticle() ma za zadanie zapisać artykuł znajdujący się polu article do bazy danych a później pobrać wszystkie artykuły i zapisać je w polu articles.

Na samym końcu zerknijmy na fragment widoku (JSF), który mógłby służyć do podania tytułu artykułu oraz miałby za zadanie wyświetlić wszystkie inne tytuły artykułów:

<h:form>
    Podaj tytuł artykułu:
    <h:inputText value="#{article.title}"/>
    <h:commandButton type="submit" value="Zapisz" action="#{paper.addArticle}" />
</h:form>

<h:dataTable value="#{articles}" var="article">
    <h:column>
        <h:outputText value="#{article.title}"/>
    </h:column>
</h:dataTable>

A teraz co się stanie kiedy klikniemy Zapisz:

  1. Seam postara się odnaleźć dwa komponenty: article oraz paper. Pierwszy jest wymagany ponieważ do komponentu o tej nazwie, a dokładniej do jego pola title, ma być zapisany tytuł wpisany w pole tekstowe. Drugi komponent jest poszukiwany aby wykonać jego metodę addArticle();
  2. Oba komponenty zostaną utworzone ponieważ nie ma ich w żadnym kontekście. Article jest encją, w której zapiszemy dane z formularza a paper jest komponentem bezstanowym, który wykona trochę logiki;
  3. Zostanie wykonana akcja a po jej zakończeniu pola oznaczone za pomocą @Out zostaną wystrzelone do kontenera, dzięki czemu będą dostępne dla innych komponentów oraz dla widoku.

Zastosowana w widoku notacja #{…} to Expression Language (EL), na który polecam zwrócić uwagę ponieważ jest wykorzystywany w Seam’ie niemal wszędzie gdzie się da.

Na koniec dodatkowa, ważna informacja. Za pomocą @In oraz @Out możemy adnotować również metody aby osiągnąć identyczny efekt jak w powyższym, przykładowym komponencie. Oto przykład jak wyglądałby komponent paper, gdybym adnotacji użył do opisania metod:

@Stateless
@Name("paper")
public class PaperAction {
    private Article article;

    private List lt;Articlegt; articles;

    @PersistenceContext
    private EntityManager em;

    public String addArticle () {
        em.persist (article);
        article = new Article ();

        articles = em.createQuery("select a from Article a")
            .getResultList();

        return null;
    }

    @In
    public function void setArticle(Article article) {
        this.article = article;
    }

    @Out
    public function Article getArticle() {
        return article;
    }

    @Out
    public function List lt;Articlegt; getArticles() {
        return articles;
    }
}

Opublikowany przez Michał Mech

2009-01-25 o 16:49:00

JBoss Tools – wsparcie dla Seam’a w Eclipse

Ilość komentarzy: 4

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.

HelloWorld in Package ExplorerW 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.

HelloWorld settings

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.

Opublikowany przez Michał Mech

2009-01-23 o 20:47:00

JBoss Seam – pierwszy projekt

jeden komentarz

Skoro już udało mi się zainstalować Seam’a czas na pierwszy projekt.

JBoss Seam dostarcza nam narzędzie seam-gen, które pozwala między innymi na utworzenie szkieletu aplikacji (ang. scaffolding) oraz reverse engineering aplikacji dla istniejącej już bazy danych. Skorzystamy z tego narzędzia aby utworzyć pierwszy projekt w JBoss Seam.

W linii komend wpisujemy:

seam setup

Aby polecenie to zadziałało lokalizacja, w której jest Seam powinna być dodana do zmiennej środowiskowej Path. Po wywołaniu polecenia uruchomiony zostanie konfigurator środowiska oraz projektu. Na każde pytanie konfiguratora odpowiadamy podając wymagane przez niego dane. Jeśli odpowiada nam zaproponowana wartość (podana w nawiasach kwadratowych) wciskamy Enter. Pojawi się komunikat:

SEAM_HOME: C:\Program Files\JBoss-seam-2.1.1.GA
Using seam-gen sources from: C:\Program Files\JBoss-seam-2.1.1.GA\seam-gen
Buildfile: C:\Program Files\JBoss-seam-2.1.1.GA\seam-gen\build.xml

init:

Oraz rozpocznie proces konfigurowania projektu.

setup:
[echo] Welcome to seam-gen :-)
[input] Enter your Java project workspace (the directory that contains your Seam projects) [F:/workspace] [F:/workspace]

Wybieramy ścieżkę do katalogu gdzie znajdują się nasze projekty. U mnie jest to workspace Eclipse‘a: F:/workspace. Projekt zostanie później utworzony w podanej lokalizacji.

[input] Enter your JBoss AS home directory [C:/Program Files/JBoss-4.2.2.GA] [C:/Program Files/JBoss-4.2.2.GA]

Podajemy ścieżkę do katalogu domowego serwera JBoss. U mnie jest to: C:/Program Files/JBoss-4.2.2.GA

[input] Enter the project name [HelloWorld [HelloWorld]

Podajemy nazwę projektu. Jak inaczej nazwać pierwszy projekt, jeśli nie HelloWorld

[echo] Accepted project name as: HelloWorld

[input] Do you want to use ICEfaces instead of RichFaces [n] (y, [n])

Wybieramy do budowy widoku będzie używana biblioteka ICEfaces zamiast standardowego rozwiązania w Seamie jakim jest RichFaces? Domyślna opcja to n, czyli pozostajemy przy RichFaces.

[input] skipping input as property icefaces.home.new has already been set.
[input] Select a RichFaces skin [deepMarine] (blueSky, classic, [deepMarine], DEFAULT, emeraldTown, japanCherry, ruby, wine)

Wybieramy styl jaki będzie użyty dla RichFaces. Mamy kilka do wyboru, ja zdecydowałem się na domyślną wartość deepMarine

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

Wybieramy sposób pakowania projektu. Wybieramy pomiędzy domyślną wartością ear a war. Zawierzę dokumentacji Seam’a i zdecyduję się na domyślną wartość ear. Dokumentacja informuje nas, że jeśli posiadamy serwer aplikacji zgodny z EJB 3.0 (JBoss taki jest) oraz posiadamy Javę EE 5 to powinniśmy zdecydować się na ear

[input] Enter the Java package name for your session beans [pl.michalmech.helloworld] [pl.michalmech.helloworld]

Podajemy nazwę paczki w aplikacji dla naszych beanów odpowiedzialnych za logikę biznesową, czyli dla Session Beans. Ja proponuję: pl.michalmech.helloworld

[input] Enter the Java package name for your entity beans [pl.michalmech.helloworld.model] [pl.michalmech.helloworld.model]

Podajemy nazwę paczki dla encji, reprezentujących dane w bazie, czyli dla Entity Beans. Proponuję: pl.michalmech.helloworld.model

[input] Enter the Java package name for your test cases [pl.michalmech.helloworld.test] [pl.michalmech.helloworld.test]

Podajemy nazwę paczki dla testów aplikacji. Niech będzie to pl.michalmech.helloworld.test

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

Wybieramy typ bazy danych. Aplikacja HelloWorld nie będzie jej wymagała więc niech będzie to domyślna baza HSQL

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

Wybieramy dialekt Hibernate‘a dla wybranej bazy danych. Dla HSQL’a jest to org.hibernate.dialect.HSQLDialect

code[input] Enter the filesystem path to the JDBC driver jar [C:\Program Files\JBoss-seam-2.1.1.GA/lib/hsqldb.jar] [C:\Program Files\JBoss-seam-2.1.1.GA/lib/hsqldb.jar]

Podajemy lokalizację sterownika, spakowanego do pliku JAR, dla JDBC, obsługującego wybraną przez nas bazę. U mnie jest to C:\Program Files\JBoss-seam-2.1.1.GA/lib/hsqldb.jar

code[input] Enter JDBC driver class for your database [org.hsqldb.jdbcDriver] [org.hsqldb.jdbcDriver]

Podajemy nazwę klasy sterownika dla JDBC, obsługującego wybraną przez nas bazę. W mojej sytuacji jest to org.hsqldb.jdbcDriver

[input] Enter the JDBC URL for your database [jdbc:hsqldb:.] [jdbc:hsqldb:.]

Podajemy URL do bazy danych: jdbc:hsqldb:.

[input] Enter database username [sa] [sa]

Użytkownik bazy danych: sa

[input] Enter database password [] []

Hasło użytkownika bazy danych: (brak hasła)

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

Schemat bazy. Skoro piszą “it is OK to leave this blank” to ja jestem na OK.

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

Katalog bazy. Skoro piszą “it is OK to leave this blank” to ja jestem na OK.

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

Czy pracujemy z bazą danych, która już posiada tabele z danymi? Nie, czyli opcja: n

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

Czy jeśli rozmieszczamy aplikację na serwerze (ang. deploy) to baza danych ma zostać wyczyszczona i wykonana ma być zawartość pliku import.sql. Nie: n

[delete] Deleting: C:\Program Files\JBoss-seam-2.1.1.GA\seam-gen\build.properties
[propertyfile] Creating new property file: C:\Program Files\JBoss-seam-2.1.1.GA\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: 18 seconds

Jeden z ostatnich komunikatów informuje nas, że konfiguracja została zapisana w pliku C:\Program Files\JBoss-seam-2.1.1.GA\seam-gen\build.properties. Możemy zawsze go zmienić jeśli nie chcemy ponownie uruchamiać konfiguratora.

Zgodnie z kolejną informacją powinniśmy teraz wykonać instrukcję seam create-project. W pliku seam-gen\README, w folderze domowym Seam’a próżno szukać informacji o poleceniu seam new-project choć dokumentacja właśnie to polecenie zaleca wykonać. Jaka jest różnica? Prawdopodobnie żadna i jedno polecenie jest aliasem drugiego. Wykonajmy:

seam create-project

Wynik działania polecenia to:

C:\Program Files\JBoss-seam-2.1.1.GA>seam create-project
SEAM_HOME: C:\Program Files\JBoss-seam-2.1.1.GA
Using seam-gen sources from: C:\Program Files\JBoss-seam-2.1.1.GA\seam-gen
Buildfile: C:\Program Files\JBoss-seam-2.1.1.GA\seam-gen\build.xml

init:

init-properties:
[echo] C:/Program Files/JBoss-4.2.2.GA

validate-workspace:

validate-project:

icefaces-staging-copy:

initcopy:

initpoms:
[echo] Setting up dependencies
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[artifact:install] [INFO] Installing C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms\root.pom to C:\Documents and Settings\Mike\.m2\repository\org\jboss\seam\root\2.1.1.GA\root-2.1.1.GA.pom
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms[artifact:install] [INFO] Installing C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms\parent.pom to C:\Documents and Settings\Mike\.m2\repository\org\jboss\seam\parent\2.1.1.GA\parent-2.1.1.GA.pom
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms
[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms[copy] Copying 1 file to C:\Program Files\JBoss-seam-2.1.1.GA\classes\poms

copyseam:

copyseamdependencies:

copyjbossembedded:

copy-icefaces-home:

copy-icefaces-maven:

copy-lib:
[echo] Copying Seam and dependencies to the F:/workspace/HelloWorld/lib directory...
[copy] Copying 120 files to F:\workspace\HelloWorld\lib
[copy] Copied 5 empty directories to 2 empty directories under F:\workspace\HelloWorld\lib
[echo] Copying JBoss Embedded configuration to the F:/workspace/HelloWorld/ bootstrap directory...
[copy] Copying 30 files to F:\workspace\HelloWorld\bootstrap

file-copy-war:

file-copy-ear:
[echo] Copying resources needed for EAR deployment to the F:/workspace/HelloWorld/resources directory...
[copy] Copying 1 file to F:\workspace\HelloWorld\resources\WEB-INF
[copy] Copying 1 file to F:\workspace\HelloWorld
[copy] Copying 1 file to F:\workspace\HelloWorld
[copy] Copying 1 file to F:\workspace\HelloWorld
[copy] Copying 1 file to F:\workspace\HelloWorld
[copy] Copying 7 files to F:\workspace\HelloWorld\resources

setup-filters:

file-copy:
[copy] Copying 1 file to F:\workspace\HelloWorld
[copy] Copying 3 files to F:\workspace\HelloWorld\resources
[copy] Copying 11 files to F:\workspace\HelloWorld\resources
[copy] Copying 4 files to F:\workspace\HelloWorld
[copy] Copying 1 file to F:\workspace\HelloWorld
[copy] Copying 1 file to F:\workspace\HelloWorld
[copy] Copying 1 file to F:\workspace\HelloWorld
[copy] Copying 1 file to F:\workspace\HelloWorld\.settings
[copy] Copying 1 file to F:\workspace\HelloWorld
[copy] Copying 1 file to F:\workspace\HelloWorld
[mkdir] Created dir: F:\workspace\HelloWorld\nbproject
[copy] Copying 3 files to F:\workspace\HelloWorld\nbproject
[copy] Copying 1 file to F:\workspace\HelloWorld\resources
[copy] Copying 1 file to F:\workspace\HelloWorld\resources
[copy] Copying 1 file to F:\workspace\HelloWorld\resources
[copy] Copying 1 file to F:\workspace\HelloWorld\resources
[copy] Copying 1 file to F:\workspace\HelloWorld\resources
[copy] Copying 1 file to F:\workspace\HelloWorld\resources
[copy] Copying 12 files to F:\workspace\HelloWorld\view
[copy] Copying 9 files to F:\workspace\HelloWorld\view
[copy] Copying 1 file to F:\workspace\HelloWorld\src\hot\pl\michalmech\helloworld
[copy] Copying 3 files to F:\workspace\HelloWorld
[mkdir] Created dir: F:\workspace\HelloWorld\src\main\pl\michalmech\helloworld\model
[mkdir] Created dir: F:\workspace\HelloWorld\src\test\pl\michalmech\helloworld\test
[copy] Copying 1 file to F:\workspace\HelloWorld\src\test

create-project:
[echo] A new Seam project named 'HelloWorld' was created in the F:/workspace directory
[echo] Type 'seam explode' and go to http://localhost:8080/HelloWorld
[echo] Eclipse Users: Import the project using File  Import...  Existing Projects into Workspace, set the root directory to F:/workspace, then select the project named HelloWorld
[echo] NetBeans Users: Open the project using File  Open project... and select the project folder F:/workspace/HelloWorld
[echo] IDEA Users: Open the project using File  Open project... and select the file F:/workspace/HelloWorld/HelloWorld.ipr

BUILD SUCCESSFUL
Total time: 17 seconds

Projekt został poprawnie utworzony. JBoss Seam był na tyle uprzejmy, że przygotował projekt tak by można było go zaimportować do dowolnego z trzech najpopularniejszych IDE dla Javy (Eclipse, NetBeans, IntelliJ IDEA).

Pozostało nam skompilować, spakować projekt i rozmieścić na serwerze (ang. deploy). Wykonujemy polecenie sugerowane nam przez seam-gen’a:

seam explode

Wynikiem powinno być:

SEAM_HOME: C:\Program Files\JBoss-seam-2.1.1.GA
Using seam-gen sources from: C:\Program Files\JBoss-seam-2.1.1.GA\seam-gen
Buildfile: C:\Program Files\JBoss-seam-2.1.1.GA\seam-gen\build.xml

init:

init-properties:
[echo] C:/Program Files/JBoss-4.2.2.GA

validate-workspace:

validate-project:

explode:
[echo] Deploying project 'HelloWorld' to JBoss AS as an exploded directory

init:
[mkdir] Created dir: F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.jar
[mkdir] Created dir: F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.war
[mkdir] Created dir: F:\workspace\HelloWorld\dist

groovy.compile:

groovy.copy:

compile:
[javac] Compiling 1 source file to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.jar

copyclasses:

jar:
[copy] Copying 2 files to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.jar
[copy] Copying 2 files to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.jar\META-INF
[copy] Copying 1 file to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.jar\META-INF
[copy] Copying 1 file to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.jar

war:
[copy] Copying 21 files to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.war
[copy] Copying 1 file to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.war\WEB-INF\classes
[copy] Copying 4 files to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.war\WEB-INF
[copy] Copying 13 files to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.war\WEB-INF\lib
[copy] Copying 1 file to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.war\WEB-INF\classes
[copy] Copying 6 files to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\HelloWorld.war\WEB-INF\classes

ear:
[copy] Copying 1 file to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear
[copy] Copying 11 files to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\lib
[copy] Copying 2 files to F:\workspace\HelloWorld\exploded-archives\HelloWorld.ear\META-INF

stage:

datasource:
[copy] Copying 1 file to C:\Program Files\JBoss-4.2.2.GA\server\default\deploy

explode:
[copy] Copying 67 files to C:\Program Files\JBoss-4.2.2.GA\server\default\deploy\HelloWorld.ear

BUILD SUCCESSFUL
Total time: 6 seconds

Sprawdźmy rezultat w przeglądarce. Wpisujemy adres http://localhost:8080/HelloWorld i cieszymy oczy (należy pamiętać o tym by serwer JBoss był uruchomiony) pierwszą aplikacją, którą “napisaliśmy” bazując na szkielecie JBoss Seam.

Seam new project

Opublikowany przez Michał Mech

2009-01-18 o 22:54:00