Webapps avec maven et jetty

9 mai 2008 – 18:05

Introduction

Dans cet article, je vais réaliser une application très simple (un helloWorld), le but est de montrer que l’utilisation de maven peut être simple et vous faciliter la vie (si si ,je vous assure)
Cette webapp sera déployée pour le moment sur jetty et non un jboss encore une fois pour alléger l’exercice.

Le code source sera disponible ici, via subversion : http://www.cestpasdur.com/svn/seriestv/. (login : guest, le mot de passe est vide), prendre la révision 28.

Afin d’intégrer un vrai processus de développement, nous procèderons par itération et celle ci sera mise en intégration continue sur Hudson.

Cette application va ensuite être réutilisée et améliorée dans une série d’article afin d’illustrer les points suivants :

  • webapp simple avec maven
  • webapp avec jsf
  • webapp sécurisée avec spring-security
  • webapp avec de la persistance JPA
  • webapp ajax avec DWR richFaces
  • webapp consommant et exposant des webservices en SOAP et REST avec apache CXF
  • webapp exposant des services avec EJB3

Cet ensemble de technologies seront mises en place afin de gérer des utilisateurs.

Structure de l’application

Afin que cette application soit évolutive (nous allons procéder par itération afin d’ajouter les nouvelles fonctionnalités), cette application aura la structure suivante :

  • seriestv-parent
    • seriestv-war
    • seriestv-ear
    • seriestv-ejb3
    • seriestv-ws
    • … (à suivre)

Contenu du pom parent

< ?xml version=”1.0″ encoding=”UTF-8″?>
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”>
4.0.0
com.cestpasdur
seriestv

pom 0.1-SNAPSHOT
${project.artifactId} : pom parent

${project.artifactId}-war

maven-eclipse-plugin
2.4

org.springframework.ide.eclipse.core.springnature

org.springframework.ide.eclipse.core.springbuilder

false
false
1.5

central
http://repo1.maven.org/maven2

java.net
https://maven-repository.dev.java.net/nonav/repository
legacy

Explications :Nous sommes en cours de développement, l’application doit être en snapshot.SNAPSHOT siginfie que deux artifacts dans la même version snapshot peuvent être différents, ce qui n’est pas le cas des artifacts releasés, lorsque l’on demande a maven de récupérer des artifacts en snashot, il va s’assurer de télécharger la version d’un snapshot, soit par la présence d’un timestamp dans son nom, soit pas l’age du fichier).
Une release ne peut avoir de liens vers des artifacts en snapshot, car si vous builder deux fois l’application, celle ci peut être différente, ce qui est contraire aux bonnes pratiques.Le pom parent est packagé en pom, celui-ci n’est présent que pour faire hériter les sous modules de paramètrage commun (maven fonctionne sur le concept de l’héritage, ce qui ne devrait pas dépayser les déeloppeurs objets.GroupId + artifactId servent permettent de donner un livrable unique.Les modules sont des sous-ensembles de l’application, dans le pom parent nous utilisons une façon relative (un peu comme les liens en html) de lier le pom parent aux sous-projets le compsants. Ainsi lorsque nous demanderons à maven de builder le pom parent, celui ci va builder le pom parent + ses sous modules.Si je ne suis pas clair sur l’explication précédente, n”hésitez pas à me le mettre en commentaire, j’essaierais de mieux faire. Dans tous les cas, il reste la documentation de maven.Le site developpez.com a également une bonne introduction à maven. Il reste également le livre électronique better build with maven quiest disponible gratuitementen ligne

Contenu du pom du modules war

<?xml version=”1.0″ encoding=”UTF-8″?>
<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>

<!– Lien vers le pom parent –>
<parent>
<groupId>com.cestpasdur</groupId>
<artifactId>seriestv</artifactId>
<version>0.1-SNAPSHOT</version>
</parent>
<groupId>com.cestpadur</groupId>
<artifactId>seriestv-war</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!– needed for JSF and jetty–>
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>1.2_08</version>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>1.2_08</version>
</dependency>

</dependencies>

<name>${parent.artifactId} : webapp</name>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.9</version>
<configuration>
<contextPath>/${project.artifactId}</contextPath>
<scanIntervalSeconds>3</scanIntervalSeconds>
<scanTargetPatterns>
<scanTargetPattern>
<directory>
src/main/webapp/WEB-INF
</directory>
<excludes>
<exclude>**/*.jsp</exclude>
<exclude>**/*.xhtml</exclude>
</excludes>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</scanTargetPattern>
</scanTargetPatterns>
</configuration>
</plugin>

<!– Afin de pouvoir utiliser les specificites java 5 car sinon java 1.3 par defaut–>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>

</plugins>
</build>
</project>

Le maven-jetty-plugin va lors du goal maven suivant va démarrer une instance du serveur jetty contenant notre webapp à l’adresse http://localhost:8080/seriestv-war/, si vous faites des modifications sur les fichiers qui sont scannés toutes les 3 secondes par jetty, celles-ci seront prises en compte à chaud (ou hot deploy).

mvn jetty:run

Si vous souhaiter modifier le port par défaut par jetty utilisé, je vous conseiller de vous référer à cette page qui vous apportera un peu plus de détail sur ce plugin.

Je ne suis pas entré en détail sur d’autres points tels que le web.xml, index.jsp, mais ils n’ont rien d’inhabituel, et vous pourrez voir le code source complet sur le subversion du site.

Nous allons bientôt compliquer les choses avec le prochain article sur l’intégration de JSF sur cette webapp.

netvibes : migrer vers ginger

5 mars 2008 – 16:12

get-netvibes-ginger.png

Si vous êtes comme moi amateur du “portail” netvibes, et comme moi malchanceux car vous n’avez pas réussi à vous inscrire parmi les bétas testeurs de ginger (qui je le rappelle est la prochaine version de nevibes), alors vous serez heureux d’apprendre que ce temps est révolu.

Un petit lien est apparu en bas de votre page netvibes vous invitant à migrer vers netvibes ginger :

netvibes-migrate-to-ginger.png

Cliquez dessus, et à vous les nouveaux widgets.

En savoir plus sur netvibes ginger

JBOSS SEAM, création du premier projet HelloWorld

3 mars 2008 – 12:51

Introduction

Après avoir effectué la configuration de l’environnement permettant de faire fonctionner le framework JBoss seam dans le l’article Jboss seam premier pas getting started, nous allons maintenant pouvoir créer notre premier projet.

Configuration de l’environnement avec seam setup

C:\>seam setup
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre1.6.0_04\lib\tools.jar
Buildfile: C:\java\jboss-seam-2.0.1.GA\seam-gen\build.xml

init:

setup:
[echo] Welcome to seam-gen :-)
[input] Enter your Java project workspace (the directory that contains your Seam projects) [C:/Projects] [C:/Projects]
C:\java\workspace
[input] Enter your JBoss home directory [C:/Program Files/jboss-4.2.2.GA] [C:/Program Files/jboss-4.2.2.GA]
C:\java\jboss-4.2.2.GA
[input] Enter the project name [myproject] [myproject]
HelloWorld
[echo] Accepted project name as: HelloWorld
[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.
[input] Select a RichFaces skin [blueSky] ([blueSky], classic, ruby, wine, deepMarine, emeraldTown, sakura, DEFAULT)
ruby
[input] Is this project deployed as an EAR (with EJB components) or a WAR (with no EJB support) [ear] ([ear], war, )
war (ca fait riche un ear pour faire un hello world)
[input] Enter the Java package name for your session beans [com.mydomain.HelloWorld] [com.mydomain.HelloWorld]
[input] Enter the Java package name for your entity beans [com.mydomain.HelloWorld] [com.mydomain.HelloWorld]
[input] Enter the Java package name for your test cases [com.mydomain.HelloWorld.test][com.mydomain.HelloWorld.test]
[input] What kind of database are you using? [hsql] ([hsql], mysql, oracle, postgres, mssql, db2, sybase, enterprisedb, h2)

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

[input] Enter the filesystem path to the JDBC driver jar [lib/hsqldb.jar] [lib/hsqldb.jar]
C:\java\jboss-4.2.2.GA\server\all\lib\hsqldb.jar
[input] Enter JDBC driver class for your database [org.hsqldb.jdbcDriver] [org.hsqldb.jdbcDriver]

[input] Enter the JDBC URL for your database [jdbc:hsqldb:.] [jdbc:hsqldb:.]
jdbc:hsqldb:mem:helloWorldDb
[input] Enter database username [sa] [sa]

[input] Enter database password [] []

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

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

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

[input] Do you want to drop and recreate the database tables and data in import.sql each time you deploy? [n] (y, [n], )
y
[propertyfile] Creating new property file: C:\java\jboss-seam-2.0.1.GA\seam-gen\build.properties
[echo] Installing JDBC driver jar to JBoss server
[echo] Type ’seam create-project’ to create the new project

BUILD SUCCESSFUL
Total time: 3 minutes 16 seconds

C:\>

Création d’un nouveau projet avec seam new-project

Voilà notre premier projet configuré, maintenant il faut le créer avec la commande :

seam new-project

La structure du projet a été créée dans le workspace indiqué précédement. Les jars seam vont y être copiés, les templates facelets, les métédatas Eclipse, les scripts de build Ant.

Copier le war explosé dans le répertoire adéquat du serveur jboss avec la commande :

seam explode

Importer et démarrer l’application dans JBOSS TOOLS

Afin de pouvoir modifier les fichiers dans l’IDE, il faut :

File > new > Project > sélectionnez Général > Project (ne pas sélectionner projet java)
Project name : helloworld


Maintenant afin de voir les traces dans la console eclipse, nous allons ajouter dans la view server, notre serveur jboss :
Windows > show view > sélectionnez servers
Dans la view nouvellement ouverte, clic droit new server et sélectionnez le server JBOSS AS 4.2
Cliquez sur next
Home directory : C:\java\jboss-4.2.2.GA
jboss-tools-add-jboss-422-2.png
Choisissez le serveur default et cliquez sur finish
Maintenant démarrez le serveur nouvelle ajouté, si vous regardez bien la console, vous verrez l’application helloworld démarrer.
Afficher dans votre navigateur http://localhost:8080/helloworld/

Vous devriez voir quelque chose ressemblant à çà :

jboss-seam-new-project.png

Afin de tester une fonctionnalité intéressant de JBOSS :

Modifiez par exemple de fichier web.xml se trouvant dans ressources > WEB-INF
Modifiez la valeur du noeud

<context-param>
<param-name>org.richfaces.SKIN</param-name>
<param-value>ruby</param-value>
</context-param>

par

<context-param>
<param-name>org.richfaces.SKIN</param-name>
<param-value>pop</param-value>
</context-param>

Lorsque vous allez sauvegarder vos modifications, observez la console

on peut observer que le fichier modifié a directement été copié dans

[copy] Copying 3 files to Y:\java\jboss-4.2.2.GA\server\default\deploy\helloworld.war

Et que sans redémarrer votre serveur, la modification a été prise en compte. Que de temps gagné (ceux qui ont codé sur des gros projets avec maven, spring et Eclipse me comprendront), raffraichissez votre page et observez le nouveau thème appliqué au projet :

jboss-tools-edit-web-xml.png

Création de la page helloWorld

Nous allons pour cela créér unenouvelle action avec la commande :

seam new-action
C:\dev\projects>seam new-action
Buildfile: C:\java\jboss-seam-2.0.1.GA\seam-gen\build.xml

init:

init-properties:
[echo] C:/java/jboss-4.2.2.GA

validate-workspace:

validate-project:

action-input:
[input] Enter the Seam component name
sayHelloWorld
[input] Enter the local interface name [SayHelloWorld] [SayHelloWorld]

[input] Enter the bean class name [SayHelloWorldBean] [SayHelloWorldBean]

[input] Enter the action method name [sayHelloWorld] [sayHelloWorld]

[input] Enter the page name [sayHelloWorld] [sayHelloWorld]

setup-filters:

new-action-ear:

new-action-war:
[echo] Creating a new JavaBean component with an action method
[copy] Copying 1 file to C:\java\workspace\HelloWorld\src\action\com\mydomain\HelloWorld
[copy] Copying 1 file to C:\java\workspace\HelloWorld\src\test\com\mydomain\HelloWorld\test
[copy] Copying 1 file to C:\java\workspace\HelloWorld\src\test\com\mydomain\HelloWorld\test
[copy] Copying 1 file to C:\java\workspace\HelloWorld\view
[echo] Type ’seam explode’ and go to http://localhost:8080/HelloWorld/sayHelloWorld.seam

new-action:

BUILD SUCCESSFUL
Total time: 31 seconds

C:\dev\projects>

La création d’une action nécessite de redémarrer le serveur, faites le avec la commande :

seam restart

Votre serveur d’application devrait redéployer tout seul l’application helloworld

Afin de voir notre helloworld, il suffit maintenant d’afficher la page http://localhost:8080/HelloWorld/sayHelloWorld.seam

Vous devriez voir la page suivante s’afficher :

seam-say-helloworld.png

Afin que l’application fasse ce qu’on lui demande, c’est à dire “dire bonjour”, il ne vous reste plus qu’a cliquer sur le bouton sayHelloWorld qui lancera la méthode sayHelloWorld de l’action que nous venons de créer.

public void sayHelloWorld()
{
//implement your business logic here
log.info(”sayHelloWorld.sayHelloWorld() action called”);
facesMessages.add(”sayHelloWorld”);
}

JBOSS SEAM, premiers pas (getting started)

27 février 2008 – 23:11

Un petit tutoriel dans la lignée des step by step de spring afin de créer sa première application fonctionnant avec jboss Seam.

Installation

Prérequis : avoir un jdk 5 ou 6 installé sur la machine.

Téléchargez JBOSS Seam (version 2.0.2,  au jour d’aujourd’hui, la version 2.1 (en développement) me retourne une exception ant à la création d’un nouveau projet)
Téléchargez JBOSS AS 4.2.2.GA
Téléchargez ANT 1.7.0

Extraire JBOSS SEAM dans le répertoire C:\java\jboss-seam-2.0.2.GA\
Extraire JBOSS AS dans le répertoire C:\java\jboss-4.2.2.GA\
Extraire ANT 1.7 dans le répertoire c:\java\ant-1.7.0\

Ajouter ces répertoires dans le path :

  • c:\java\ant-1.7.0\bin\
  • C:\java\jboss-seam-2.0.2.GA\

path-jboss-seam.png

Cliquez sur Ok

Afin de valider que cette modification soit prise en compte tapez la commande

seam help

Vous devriez voir défiler l’ensemble des commandes disponibles, dans le cas contraire vérifiez l’emplacement du répertoire jboss seam ainsi que son paramétrage dans le path windows

Modifier le fichier C:\java\jboss-seam-2.0.2.GA\build.properties présent dans le répertoire afin de le faire pointer sur l’emplacement du serveur d’application jboss, mettez bien les slash dans ce sens, sinon cela ne fonctionnera pas.

jboss.home=C://java//jboss-4.2.2.GA//

Faire fonctionner les exemples

Avant d’écrire le moindre bout de code, il peut être intéressant de tester les exemples fournis (26) avec le framework.
Démarrer le serveur jboss avec la commande :

C:\java\jboss-4.2.2.GA\bin\>run.bat

Ensuite il faut lancer la tache ant correspondante, pour le blog par exemple :

C:\java\jboss-seam-2.0.2.GA\examples\blog>ant deploy

Pour info, le mot de passe pour se logger au blog est tokio

normalement vous devriez voir le blog à l’adresse suivante : http://localhost:8080/seam-blog/
Aperçu des quelques démos :

jboss-seam-demo-bookin.png jboss-seam-demo-contactlist.png jboss-seam-demo-dvd.png

Dans l’ensemble les démos fonctionnaient bien. Les fonctionnalités présentes dans ces applications seront certainement d’une grande aide à l’apprentissage de framework.

Bon point pour jboss de fournir toutes ces démos

Introduction au Framework MVC Spring

27 février 2008 – 9:57

spring-logo.gif
Le design pattern MVC est un modèle de conception adapté à la séparation des couches.

Cette méthode impose de séparer présentation, traitements et données.

En respectant cette méthodologie, le travail en équipe sera facilité par le découpage des tâches et des fichiers. La maintenance du code sera améliorée du fait de sa spécialisation. Bref, que des avantages.

Le Framework Spring implémente ce design pattern.

Dans ce premier article qui lui est consacré, nous allons mettre en pratique cette séparation des couches en utilisant un MultiActionController, qui me semble plus simple pour commencer.

Diagramme de séquence

mvc-tutoriel-introduction.gif

Les portions d’urls ont été volontairement nommées afin de mieux comprendre leurs rôles

DispatcherServlet

Point d’entrée de l’application, le DispatcherServlet effectue le premier mapping de l’application, il distribue les requêtes aux servlets correspondantes.

exemple : /servlet1/* sera renvoyé vers la servlet 1

Toutes les urls de notre application commençant par servlet1 seront « dispatchées » vers cette servlet

Cette configuration est effectuée dans le web.xml :

  1. <servlet>
  2. </servlet><servlet>introduction-spring</servlet>
  3. <servlet>org.springframework.web.servlet.DispatcherServlet</servlet>
  4. <load>1</load>
  5.  
  6. <servlet>
  7. </servlet><servlet>introduction-spring</servlet>
  8. <url>/servlet1/*</url>

SimpleUrlHandlerMapping

Il fait la correspondance entre les urls transmises par la servlet et les controllers adéquats.

/servlet1/controller1/*

Toutes les urls correspondant à ce pattern seront alors mappées à notre controller1

Fichier introduction-spring-servlet.xml :

  1. <bean id=“urlMapping” class=“org.springframework.web.servlet.handler.SimpleUrlHandlerMapping”></bean>
  2.  
  3. <property name=“mappings”>
  4. <props>
  5. <prop key=“/controller1/*”>controller1</prop>     </props>  </property>

MultiActionController

Nous voilà enfin au cœur du sujet, un controller de type MultiActionController est en fait un controller dont les méthodes seront lancées en fonction des urls d’entrées. Pour effectuer cette correspondance, nous utiliserons un PropertiesMethodNameResolver.

Fichier introduction-spring-servlet.xml :

  1. <bean id=“controller1″ class=“com.cestpasdur.controllers.IndexController”></bean>
  2.  
  3. <property name=“methodNameResolver” ref=“methodNameResolver”></property>

PropertiesMethodNameResolver

Effectue la correspondance entre les requêtes entrantes et les méthodes du controller.

Dans notre cas, /controller1/etat1.htm correspond à la méthode etat1Handler de notre controller tandis que /controller1/etat2.htm, à etat2Handler

  1. <bean id=“methodNameResolver” class=“org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver”></bean>
  2.  
  3. <property name=“mappings”>
  4. <props>
  5. <prop key=“/controller1/etat1.htm”>etat1Handler</prop>
  6. <prop key=“/controller1/etat2.htm”>etat2Handler</prop>   </props>         </property>

InternalResourceViewResolver

Il est préconisé de ne pas rendre accessible les jsp directement, celles ci-doivent être dans un répertoire non disponible à la navigation (par opposition aux images et CSS par exemple), dans notre cas : /WEB-INF/vues/* Il n’y aura que les controllers qui pourront y accèder.

Afin d’éviter de coder ce paramètrage en dur dans notre controller, Spring met à notre disposition un resolver de view.

Le handler de notre controller doit retourner un objet de type ModelAndView, celui-ci s’instancie (entre autre) de la manière suivante :

  1. return new ModelAndView(“vue1″) ;

Le rôle de notre resolveur de view, sera de faire correspondre cette vue à une jsp.

La config est la suivante :

  1. <bean id=“jspViewResolver” class=“org.springframework.web.servlet.view.InternalResourceViewResolver”></bean>
  2.  
  3. <property name=“prefix” value=“/WEB-INF/vues/”></property>
  4. <property name=“suffix” value=“.jsp”></property>

Demander la vue1 revient à demander le fichier /WEB-INF/vues/vue1.jsp. Notre controlleur n’a pas donc pas à se soucier de l’emplacement réél des jsp.

Conclusion

Le MultiActionController sera utilisé de préférence pour afficher des pages appelant ou non une base de données.

Pour des pages nécessitant un affichage, soumission ou validation de formulaire, vous devrez vous orienter vers des contrôleurs du type SimpleFormController ou webflow.

introduction-spring-multiactioncontrollerrar.zip