20 czerwca 2008

Podboje JBoss Seam ciąg dalszy - minimalna konfiguracja działa!

Wczorajsze boje z JBoss Seam 2.0.3.CR1 - JBoss Seam, Apache Geronimo z Eclipse Ganymede i Apache Maven 2 zakończyły się poprawnym rozmieszczeniem aplikacji, jednakże próba uruchomienia strony witaj.seam zakończyła się pustą stroną XHTML.

Porównując różnice między aplikacją utworzoną wcześniej z seam-gen (Uruchomienie projektu seamowego w Eclipse Ganymede z JBoss Tools i Geronimo Eclipse Plugin) a z mavenowym archetypem maven-archetype-webapp natknąłem się na różnicę w web.xml:
 <filter>
<filter-name>Seam Filter</filter-name>
<filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Seam Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Nie znalazłem dokumentacji, dlaczego miałbym potrzebować SeamFilter, a mimo to postanowiłem spróbować uruchomienia w ciemno. Po dodaniu zmiany do web.xml i uruchomieniu
 c\:/geronimo/bin/deploy.sh -u system -p manager deploy \
target/seam-richfaces-tree.war src/main/resources/geronimo-web.xml
Bez zmian. Strona wciąż nie wyświetla się.

Porównując dalej aplikacje okazało się, że moja nowa aplikacja seamowa nie posiadała pliku faces-config.xml (!) Aż trudno uwierzyć, że żaden z elementów Seama czy MyFaces nie zgłosił jego braku.
 <?xml version='1.0' encoding='UTF-8'?>
<faces-config version="1.2"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<application>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>
</faces-config>
Skorzystanie z FaceletViewHandler wymaga zadeklarowania zależności w pom.xml (zależność znajduje się w repozytorium repository.jboss.org).
 <dependency>
<groupId>com.sun.facelets</groupId>
<artifactId>jsf-facelets</artifactId>
<version>1.1.15.B1</version>
</dependency>
i zbudowaniu aplikacji
 jlaskowski@work /cygdrive/c/projs/sandbox/seam-richfaces-tree
$ mvn clean package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building seam-richfaces-tree Maven Webapp
[INFO] task-segment: [clean, package]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] Deleting directory c:\projs\sandbox\seam-richfaces-tree\target
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] No sources to compile
[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[seam-richfaces-tree] in [c:\projs\sandbox\seam-richfaces-tree\target\seam-richfaces-tree]
[INFO] Processing war project
[INFO] Webapp assembled in[157 msecs]
[INFO] Building war: c:\projs\sandbox\seam-richfaces-tree\target\seam-richfaces-tree.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
a następnie jej rozmieszczeniu na wcześniej uruchomionym Geronimo
 jlaskowski@work /cygdrive/c/projs/sandbox/seam-richfaces-tree
$ c\:/geronimo/bin/deploy.sh -u system -p manager deploy \
target/seam-richfaces-tree.war src/main/resources/geronimo-web.xml
Using GERONIMO_BASE: c:\geronimo
Using GERONIMO_HOME: c:\geronimo
Using GERONIMO_TMPDIR: var\temp
Using JRE_HOME: c:\apps\java5\jre
Deployed pl.jaceklaskowski.seam/seam-richfaces-tree/1.0/war @
/seam-richfaces-tree
Na konsoli Geronimo można zaobserwować
 19:13:04,953 INFO  [ServletContextListener] Welcome to Seam 2.0.3.CR1
...
19:13:29,046 INFO [Initialization] initializing Seam
...
19:13:30,312 INFO [Initialization] done initializing Seam
...
19:13:30,359 INFO [MyfacesConfig] Starting up Tomahawk on the MyFaces-JSF-Implementation
19:13:30,921 INFO [AbstractFacesInitializer] ServletContext
'C:\geronimo\repository\pl\jaceklaskowski\seam\seam-richfaces-tree\1.0\seam-richfaces-tree-1.0.war\' initialized.
Uruchomienie http://localhost:8080/seam-richfaces-tree/witaj.seam i...



Działa! Od razu mi lepiej ;-)

W międzyczasie "uzbroiłem" stronę witaj.xhtml w szablon Facelets.
 <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
template="szablon.xhtml">

<ui:define name="body">
<p>Witaj Nieznajomy!</p>
</ui:define>

</ui:composition>
gdzie szablon wskazywany przez atrybut template wskazuje na plik szablon.xml:
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:s="http://jboss.com/products/seam/taglib">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Strona powitalna</title>
</head>

<body>

<div class="body">
<ui:insert name="body"/>
</div>

</body>
</html>
Wytłumaczenie działania facelets i jego szablonu pozostawiam dla dociekliwych jako zadanie domowe. Sądzę, że działanie facelets w tym zakresie powinno być samowyjaśniające.

Uważne oko mogło zauważyć, że pracuję z Firefox 3.0. Nie ukrywam, że jestem zachwycony szybkością jego działania. Mając bardzo bogatą bazę odnośników (wiele z nich to artykuły do przeczytania) praca z 2.0.0.14 była udręką, bo przy jednocześnie otwartych 10 pojedyńczych przeglądarkach strasznie spowalniała. Dodając do tego niezwykle powolne otwieranie zakładek (Ctrl+T) w zasadzie całkowicie z nich zrezygnowałem. Otworzenie nowej zakładki przez Ctrl+T zajmowało ponad 15-30 sekund, podczas gdy otwarcie przez menu pod prawym klawiszem myszy było błyskawiczne. Niestety, nie zawsze mogłem otworzyć zakładkę przez menu, więc szybciej uruchamiałem nowe okno. Teraz, z FF 3.0 sprawa jest całkowicie rozwiązana. Otwieranie zakładek, zajętość pamięci oraz szybkość renderowania stron są przygniatające. Strony wyświetlane są z prędkością światła. Na prawdę warto było przenieść się na FF 3.0. Polecam!

Pytanie konkursowe: Jaka technologia realizuje warstwę prezentacji w JBoss Seam? I uzupełniające: Jaki projekt oferuje mechanizm szablonów dla JBoss Seam? (zwróć uwagę na różnicę między technologia a projekt).