<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Le Touilleur Express &#187; spring</title>
	<atom:link href="http://www.touilleur-express.fr/tag/spring/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.touilleur-express.fr</link>
	<description>Blog sur Java, le métier de développeur et la vie de freelance par Nicolas Martignole</description>
	<lastBuildDate>Wed, 08 Feb 2012 11:54:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Spring Faces+WebFlow+Java classique comparé à Play! Framework</title>
		<link>http://www.touilleur-express.fr/2010/05/13/spring-faceswebflowjava-classique-compare-a-play-framework/</link>
		<comments>http://www.touilleur-express.fr/2010/05/13/spring-faceswebflowjava-classique-compare-a-play-framework/#comments</comments>
		<pubDate>Thu, 13 May 2010 13:23:31 +0000</pubDate>
		<dc:creator>Nicolas Martignole</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[jsf]]></category>
		<category><![CDATA[play]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.touilleur-express.fr/?p=3716</guid>
		<description><![CDATA[
Dans cet article, je vous propose de regarder 2 approches différentes pour résoudre un même problème : construire une application web sécurisée, moderne et Ajaxisé. Je vais vous présenter les différences de conceptions sur la partie Java essentiellement. Cet article ne sera pas une introduction à l&#8217;une ou l&#8217;autre des technologies. Je souhaite vous éclairer sur quelques concepts différents dans Play! par rapport à l&#8217;approche classique.
Pour comparer 2 choses, il faut un référentiel comparable. JBoss Seam propose sur cette page plusieurs versions d&#8217;une application de réservation de chambres d&#8217;hôtels. La ...]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.touilleur-express.fr/wp-content/uploads/2010/05/springwebflow-versus-Play1.jpg"><img src="http://www.touilleur-express.fr/wp-content/uploads/2010/05/springwebflow-versus-Play1.jpg" alt="" title="springwebflow-versus-Play" width="500" height="500" class="alignnone size-full wp-image-3719" /></a><br />
Dans cet article, je vous propose de regarder 2 approches différentes pour résoudre un même problème : construire une application web sécurisée, moderne et Ajaxisé. Je vais vous présenter les différences de conceptions sur la partie Java essentiellement. Cet article ne sera pas une introduction à l&#8217;une ou l&#8217;autre des technologies. Je souhaite vous éclairer sur quelques concepts différents dans Play! par rapport à l&#8217;approche classique.</p>
<p>Pour comparer 2 choses, il faut un référentiel comparable. JBoss Seam propose <a href="http://demo.flamingo.exadel.com/booking/">sur cette page</a> plusieurs versions d&#8217;une application de réservation de chambres d&#8217;hôtels. La version originale basée sur JSF 1.2 n&#8217;est plus toute jeune mais fonctionne très bien. <a href="http://www.touilleur-express.fr/2006/12/12/jboss-seam-linteret-de-la-conversation/">J&#8217;en avais parlé sur le Touilleur Express il y a 3 ans et demie&#8230;</a> Quand je me dis que cela fait plus de 3 ans que j&#8217;ai vu cela, et qu&#8217;à l&#8217;époque je vous avais convaincu de regarder JSF par rapport à Struts, je me dis qu&#8217;il faut que je réussisse dans cet article à vous montrer la nouvelle approche, celle de 2010.</p>
<p>Nous allons prendre Spring Faces et Spring Webflow, une approche que je trouve très intéressante et qui permet de réaliser des applications Webs avec les technologies de Spring.</p>
<h2>I. Le match : télécharger, installer et lancer la démo</h2>
<p>Voyons tout d&#8217;abord comment télécharger, compiler et lancer la démonstration avec chacun des environnements. Je souhaite évaluer la rapidité de prise en main. Je souhaite que le projet soit configuré dans IDEA IntelliJ ou Eclipse pour travailler, et je vais évaluer la facilité à monter chacun des environnements. Je regarderai aussi le temps de démarrage des serveurs Webs testés.</p>
<h3>I.1) Préparation de l&#8217;espace de démo pour Spring</h3>
<p>SpringSource propose &laquo;&nbsp;<a href="http://richweb.springframework.org/swf-booking-faces/spring/intro">Spring Travel</a>&laquo;&nbsp;, une version basée sur <a href="http://www.springsource.org/faces">Spring Faces</a>, Spring WebFlow 2.0.9 et une librairie JSF avancée pour le rendu. J&#8217;ai regardé précisément le code &laquo;&nbsp;booking-faces&nbsp;&raquo; dans le répertoire projects/spring-webflow-samples pour écrire cet article. Si vous souhaitez tester par vous même :<br />
- téléchargez <a href="http://www.springsource.org/download#webflow">la version Spring WebFlow 2.0.9</a> sur le site de SpringSource<br />
- décompressez l&#8217;archive<br />
- ouvrez le répertoire projects/spring-webflow-samples/booking-faces<br />
- tapez <em>mvn eclipse:eclipse</em> pour créer un nouveau projet<br />
- ou sinon tapez <em>mvn idea:idea</em> pour créer un projet IDEA IntelliJ<br />
- ou enfin, si vous avez IDEA IntelliJ, celui-ci importe sans problème le pom.xml et vous prépare un projet configuré&#8230; Pas besoins de plugins.</p>
<p><strong>Faire tourner la démo en local</strong><br />
Pour faire fonctionner la version Spring en local, éditez le pom.xml et ajoutez Jetty dans la balise build/plugins comme ici:</p>
<pre class="brush:xml">   ...
   &lt;build&gt;
        &lt;finalName&gt;swf-booking-faces&lt;/finalName&gt;
        &lt;plugins&gt;
        	...

            &lt;plugin&gt;
                &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
                &lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
            &lt;/plugin&gt;

        &lt;/plugins&gt;
    &lt;/build&gt;
    &lt;properties&gt;
        &lt;spring.version&gt;2.5.6.SEC01&lt;/spring.version&gt;
        &lt;jsf.version&gt;1.2.0.09&lt;/jsf.version&gt;
    &lt;/properties&gt;
&lt;/project&gt;</pre>
<p>Vous pourrez alors lancer la démo avec mvn jetty:run dans le répertoire de la démo de Spring.</p>
<h3>I.2) Configuration de la version Play! Framework</h3>
<p>Play! Framework se télécharge <a href="http://www.playframework.org/">sur le site de Play!</a>. Voici comment suivre mes explications pour la deuxième partie :<br />
- décompressez le zip dans un répertoire C:\Soft\play par exemple<br />
- ajoutez C:\Soft\play à votre PATH</p>
<p>Pour lancer l&#8217;application :<br />
- allez dans le répertoire C:\Soft\play\samples-and-tests\booking<br />
- tapez &laquo;&nbsp;<em>play run</em>&nbsp;&raquo; et connectez-vous sur http://localhost:9000/</p>
<p>Pour travailler avec Eclipse ou IDEA IntelliJ<br />
- allez dans le répertoire C:\Soft\play\samples-and-tests\booking<br />
- tapez <em>play eclipsify</em> pour créer un projet Eclipse<br />
- OU tapez <em>play idealize</em> pour créer un module IDEA IntelliJ<br />
c&#8217;est tout !</p>
<p><strong>I.3) Résultat du match :</strong></p>
<p>Facilité d&#8217;installation : match nul<br />
Qualité de la doc sur le site : match nul<br />
Création du projet dans IDEA IntelliJ : match nul<br />
Serveur : la démo Spring n&#8217;embarque pas de serveur, il a fallut ajouter Jetty pour tester alors que Play! Framework dispose de son propre serveur<br />
Temps de démarrage : avantage Play! qui démarre très rapidement en 2 secondes.</p>
<p><strong>Vainqueur : Play! Framework d&#8217;une courte longueur </strong></p>
<h2>II. Le modèle</h2>
<h3>II.1) Spécification fonctionnelle</h3>
<p>L&#8217;objectif de l&#8217;application est de réaliser un site de réservation d&#8217;hôtel. Pour cela, l&#8217;utilisateur peut chercher un hôtel, puis ensuite créer une réservation (Booking en Anglais).</p>
<p>L&#8217;utilisateur doit s&#8217;authentifier avant de pouvoir terminer sa réservation. Une entité User permet donc de gérer la sécurité facilement avec un moteur de persistence.</p>
<p>Nous utiliserons JPA et une base en mémoire pour les 2 versions. L&#8217;essentiel est que Play! Framework comme la version Spring, utilisent JPA. Donc les entités sont presque identiques.</p>
<h3>II.2) Une entité simple : l&#8217;Hotel</h3>
<p>Prenons tout d&#8217;abord l&#8217;entité Hotel qui représente un hôtel. Voici la version de la démo Spring Webflow/JSF :</p>
<pre class="brush:java">
package org.springframework.webflow.samples.booking;

import java.io.Serializable;
import java.math.BigDecimal;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 * Version Spring Web Flow. La sérialisation est nécessaire pour JSF.
 */
@Entity
public class Hotel implements Serializable {
    private static final long serialVersionUID = 4011346719502656269L;
    private Long id;
    private String name;
    private String address;
    private String city;
    private String state;
    private String zip;
    private String country;
    private BigDecimal price;

    @Id
    @GeneratedValue
    public Long getId() {
	return id;
    }

    public void setId(Long id) {
	this.id = id;
    }

    public String getName() {
	return name;
    }

    public void setName(String name) {
	this.name = name;
    }

    public String getAddress() {
	return address;
    }

    public void setAddress(String address) {
	this.address = address;
    }

    public String getCity() {
	return city;
    }

    public void setCity(String city) {
	this.city = city;
    }

    public String getZip() {
	return zip;
    }

    public void setZip(String zip) {
	this.zip = zip;
    }

    public String getState() {
	return state;
    }

    public void setState(String state) {
	this.state = state;
    }

    public String getCountry() {
	return country;
    }

    public void setCountry(String country) {
	this.country = country;
    }

    @Column(precision = 6, scale = 2)
    public BigDecimal getPrice() {
	return price;
    }

    public void setPrice(BigDecimal price) {
	this.price = price;
    }

    public Booking createBooking(User user) {
	return new Booking(this, user);
    }

    @Override
    public String toString() {
	return "Hotel(" + name + "," + address + "," + city + "," + zip + ")";
    }
}</pre>
<p>Voici la version Play! Framework :</p>
<pre class="brush:java">package models;

import play.db.jpa.*;
import play.data.validation.*;
import javax.persistence.*;
import java.math.*;

/**
 * Version Play! Framework
 */
@Entity
public class Hotel extends play.db.jpa.Model {

    @Required
    @MaxSize(50)
    public String name;

    @MaxSize(100)
    public String address;

    @Required
    @MaxSize(40)
    public String city;

    @Required
    @MaxSize(6)
    @MinSize(2)
    public String state;

    @Required
    @MaxSize(6)
    @MinSize(5)
    public String zip;

    @Required
    @MaxSize(40)
    @MinSize(2)
    public String country;

    @Column(precision=6, scale=2)
    public BigDecimal price;

    public String toString() {
        return "Hotel(" + name + "," + address + "," + city + "," + zip + ")";
    }

}</pre>
<p>Les différences entre les 2 versions :<br />
- Play! Framework étend la classe &laquo;&nbsp;play.db.jpa.Model&nbsp;&raquo; qui fournit le support JPA.<br />
- Les attributs sont publics dans la version Play!, ce qui logiquement évite des getters/setters comme dans la version Spring classique. Moi depuis que l&#8217;encapsulation n&#8217;est plus à la mode en soirée, j&#8217;ai arrêté.<br />
- La syntaxe JPA est un peu plus poussée dans la version Play! Nous verrons si cela permet d&#8217;améliorer l&#8217;expérience utilisateur dans l&#8217;interface graphique ou non.</p>
<p><del datetime="2010-05-14T05:57:30+00:00">Le bean de Spring n&#8217;étend pas une classe de base contrairement à Play!, ce qui permet d&#8217;étendre éventuellement Hotel. Mais est-ce que c&#8217;est quelque chose que nous faisons pour des Entities ? Je me pose la question. Perso je décourage l&#8217;héritage avec JPA. FBI = Fausse bonne idée.</del></p>
<p>[Update] Avec Play! Framework vous pouvez étendre la classe Model afin de simplifier la gestion JPA de l&#8217;entité. Cela fait partie des bonnes pratiques comme expliqué par Nicolas Leroux dans les commentaires. Pour en savoir plus, regardez <a href="http://www.playframework.org/documentation/1.0.2.1/jpa">la doc de la partie JPA de Play!<br />
</a></p>
<p>Play! gère l&#8217;identité dans la class Model avec un attribut Id de type Long par défaut. Si vous souhaitez gérer votre propre id, vous <del datetime="2010-05-14T05:57:30+00:00">devez</del> <em>pouvez</em> par exemple étendre la class <strong>JPASupport</strong> de Play!, puis simplement définir un attribut @Id comme d&#8217;habitude avec JPA. C&#8217;est tout à fait possible.</p>
<p>On voit que dans la version Spring, il y a une méthode &laquo;&nbsp;createBooking&nbsp;&raquo; qui permet de créer au niveau de l&#8217;Hotel une réservation.</p>
<p>Il n&#8217;y a donc pas de vainqueur dans cette partie pour moi. Les 2 approches se valent je pense. Je préfère la simplicité de Play! Framework qui remet en question quelques habitudes du monde Java, comme l&#8217;encapsulation systématique.</p>
<p>Par contre je n&#8217;aime pas trop l&#8217;approche de placer les annotations JPA sur les getters/setters plutôt que sur les attributs de la classe dans la version Spring. On perd beaucoup en lisibilité.</p>
<h3>II.3) Une entité plus compliquée : Booking</h3>
<p>Une réservation est l&#8217;association d&#8217;un User, d&#8217;un Hotel, d&#8217;une date d&#8217;arrivée et de départ et de différents autres attributs. Je vais faire exprès de vous donner la version complète des 2 frameworks, afin de vous montrer les différences flagrantes entre les 2 approches.</p>
<p>La version de la démo Spring WebFlow telle qu&#8217;elle est livrée, sans trucages, sans effets spéciaux :</p>
<pre class="brush:java">package org.springframework.webflow.samples.booking;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.springframework.binding.message.MessageBuilder;
import org.springframework.binding.message.MessageContext;
import org.springframework.binding.validation.ValidationContext;

/**
 * A Hotel Booking made by a User.
 */
@Entity
public class Booking implements Serializable {

    private static final long serialVersionUID = 1171567558348174963L;

    private Long id;
    private User user;
    private Hotel hotel;
    private Date checkinDate;
    private Date checkoutDate;
    private String creditCard;
    private String creditCardName;
    private int creditCardExpiryMonth;
    private int creditCardExpiryYear;
    private boolean smoking;
    private int beds;
    private Amenity amenities;   // Absent de la version Play!

    public Booking() {
    }

    public Booking(Hotel hotel, User user) {
        this.hotel = hotel;
        this.user = user;
        Calendar calendar = Calendar.getInstance();
        setCheckinDate(calendar.getTime());
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        setCheckoutDate(calendar.getTime());
    }

    @Transient
    public BigDecimal getTotal() {
        return hotel.getPrice().multiply(new BigDecimal(getNights()));
    }

    @Transient
    public int getNights() {
        if (checkinDate == null || checkoutDate == null) {
            return 0;
        } else {
            return (int) (checkoutDate.getTime() - checkinDate.getTime()) / 1000 / 60 / 60 / 24;
        }
    }

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Basic
    @Temporal(TemporalType.DATE)
    public Date getCheckinDate() {
        return checkinDate;
    }

    public void setCheckinDate(Date datetime) {
        this.checkinDate = datetime;
    }

    @ManyToOne
    public Hotel getHotel() {
        return hotel;
    }

    public void setHotel(Hotel hotel) {
        this.hotel = hotel;
    }

    @ManyToOne
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Basic
    @Temporal(TemporalType.DATE)
    public Date getCheckoutDate() {
        return checkoutDate;
    }

    public void setCheckoutDate(Date checkoutDate) {
        this.checkoutDate = checkoutDate;
    }

    public String getCreditCard() {
        return creditCard;
    }

    public void setCreditCard(String creditCard) {
        this.creditCard = creditCard;
    }

    @Transient
    public String getDescription() {
        DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
        return hotel == null ? null : hotel.getName() + ", " + df.format(getCheckinDate()) + " to "
                + df.format(getCheckoutDate());
    }

    public boolean isSmoking() {
        return smoking;
    }

    public void setSmoking(boolean smoking) {
        this.smoking = smoking;
    }

    public int getBeds() {
        return beds;
    }

    public void setBeds(int beds) {
        this.beds = beds;
    }

    public String getCreditCardName() {
        return creditCardName;
    }

    public void setCreditCardName(String creditCardName) {
        this.creditCardName = creditCardName;
    }

    public int getCreditCardExpiryMonth() {
        return creditCardExpiryMonth;
    }

    public void setCreditCardExpiryMonth(int creditCardExpiryMonth) {
        this.creditCardExpiryMonth = creditCardExpiryMonth;
    }

    public int getCreditCardExpiryYear() {
        return creditCardExpiryYear;
    }

    public void setCreditCardExpiryYear(int creditCardExpiryYear) {
        this.creditCardExpiryYear = creditCardExpiryYear;
    }

    @Transient
    public Amenity getAmenities() {
        return amenities;
    }

    public void setAmenities(Amenity amenities) {
        this.amenities = amenities;
    }

    public void validateEnterBookingDetails(ValidationContext context) {
        MessageContext messages = context.getMessageContext();
        if (checkinDate.before(today())) {
            messages.addMessage(new MessageBuilder().error().source("checkinDate").code(
                    "booking.checkinDate.beforeToday").build());
        } else if (checkoutDate.before(checkinDate)) {
            messages.addMessage(new MessageBuilder().error().source("checkoutDate").code(
                    "booking.checkoutDate.beforeCheckinDate").build());
        }
    }

    private Date today() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return calendar.getTime();
    }

    @Override
    public String toString() {
        return "Booking(" + user + "," + hotel + ")";
    }

}</pre>
<p>Voyons la version Play! Framework de l&#8217;entité Booking maintenant :</p>
<pre class="brush:java">package models;

import play.db.jpa.*;
import play.data.validation.*;
import javax.persistence.*;
import java.util.*;
import java.text.*;
import java.math.*;

@Entity
public class Booking extends Model {

    @Required
    @ManyToOne
    public User user;

    @Required
    @ManyToOne
    public Hotel hotel;

    @Required
    @Temporal(TemporalType.DATE)
    public Date checkinDate;

    @Required
    @Temporal(TemporalType.DATE)
    public Date checkoutDate;

    @Required(message="Credit card number is required")
    @Match(value="^\\d{16}$", message="Credit card number must be numeric and 16 digits long")
    public String creditCard;

    @Required(message="Credit card name is required")
    @MinSize(value=3, message="Credit card name is required")
    @MaxSize(value=70, message="Credit card name is required")
    public String creditCardName;
    public int creditCardExpiryMonth;
    public int creditCardExpiryYear;
    public boolean smoking;
    public int beds;

    public Booking(Hotel hotel, User user) {
        this.hotel = hotel;
        this.user = user;
    }

    public BigDecimal getTotal() {
        return hotel.price.multiply( new BigDecimal( getNights() ) );
    }

    public int getNights() {
        return (int) ( checkoutDate.getTime() - checkinDate.getTime() ) / 1000 / 60 / 60 / 24;
    }

    public String getDescription() {
        DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
        return hotel==null ? null : hotel.name +
            ", " + df.format( checkinDate ) +
            " to " + df.format( checkoutDate );
    }

    public String toString() {
        return "Booking(" + user + ","+ hotel + ")";
    }

}</pre>
<p>Tout d&#8217;abord il manque des choses dans la version Play! Framework, et on ne compare donc plus exactement la même chose. Notez l&#8217;absence de l&#8217;entité Amenity. Ensuite, la version Spring utilise une approche différente pour l&#8217;attribut @Id et spécifie le générateur alors que la version Play! hérite de ce que la super-classe Model propose.</p>
<p>Ce qui me dérange dans la version Spring c&#8217;est la présence de la méthode <em>validateEnterBookingDetails</em>. Celle-ci est intéressante fonctionnellement, mais dépose une dépendance vers MessageContext un peu trop forte à mon goût.</p>
<p>Regardez aussi la différence sur la validation du numéro de carte de paiement. La version Play! utilise un moteur simple similaire à Hibernate Validation, mais propriétaire à Play! Au contraire la version Spring ne précise rien, et on imagine donc que la validation des 16 digits se fera dans la vue&#8230; et pas dans le modèle.</p>
<p>Conclusion : j&#8217;ai de plus en plus de mal avec la sauce des getters/setters, surtout lorsque les entités dépasse les &laquo;&nbsp;HelloWorld&nbsp;&raquo; et que l&#8217;on commence à sortir des cas d&#8217;usages compliqués. Souvenez-vous de ce que je vous disais : pour résoudre des problèmes compliqués il faut des solutions simples&#8230;</p>
<h2>III. Le contrôleur</h2>
<p>Après avoir regardé 2 entités différentes pour le modèle, voyons maintenant la différence d&#8217;approche entre Spring WebFlow et Play! Framework. Je vais étudier le cas de l&#8217;affichage de la liste des Hôtels, lorsque l&#8217;utilisateur clique sur le bouton Search par exemple.</p>
<h3>III.1) Spring WebFlow</h3>
<p>L&#8217;approche de Spring WebFlow est la suivante : afin d&#8217;éviter d&#8217;écrire un controller classique, Spring propose de définir les chemins logiques de navigation en XML, et d&#8217;associer directement des méthodes sur des services pour récupérer la partie Model. Cette approche a l&#8217;avantage de simplifier le développement de workflow webs complexes. Je vais vous présenter le concept.</p>
<p>Pour commencer, nous définissions un flow en XML pour l&#8217;action qui affiche la liste des Hotel correspondant à un critère de recherche. Je ne vous montre que la view-state &laquo;&nbsp;reviewHotels&nbsp;&raquo; afin de ne se concentrer que sur l&#8217;exemple :</p>
<p>&laquo;&nbsp;<em>main-flow.xml</em>&nbsp;&raquo;</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;flow xmlns="http://www.springframework.org/schema/webflow"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"&gt;

	&lt;var name="searchCriteria" class="org.springframework.webflow.samples.booking.SearchCriteria" /&gt;

	&lt;view-state id="enterSearchCriteria"&gt;
		// Effacé pour simplifier l'exemple...
	&lt;/view-state&gt;

	&lt;view-state id="reviewHotels"&gt;
		&lt;on-render&gt;
			&lt;evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" result-type="dataModel" /&gt;
		&lt;/on-render&gt;
        &lt;transition on="sort"&gt;
            &lt;set name="searchCriteria.sortBy" value="requestParameters.sortBy" /&gt;
            &lt;render fragments="hotels:searchResultsFragment" /&gt;
        &lt;/transition&gt;
		&lt;transition on="previous"&gt;
			&lt;evaluate expression="searchCriteria.previousPage()" /&gt;
			&lt;render fragments="hotels:searchResultsFragment" /&gt;
		&lt;/transition&gt;
		&lt;transition on="next"&gt;
			&lt;evaluate expression="searchCriteria.nextPage()" /&gt;
			&lt;render fragments="hotels:searchResultsFragment" /&gt;
		&lt;/transition&gt;
		&lt;transition on="select" to="reviewHotel"&gt;
			&lt;set name="flowScope.hotel" value="hotels.selectedRow" /&gt;
		&lt;/transition&gt;
		&lt;transition on="changeSearch" to="changeSearchCriteria" /&gt;
	&lt;/view-state&gt;</pre>
<p><strong>Le point fort de Spring WebFlow/JSF ici :</strong> il sera possible de ne redessiner qu&#8217;une partie de l&#8217;interface. En effet, vous avez noté le tag &lt;render fragments=&nbsp;&raquo;"/&gt; ? Grâce à ce système très pratique avec Spring WebFlow et JSF, si vous avez une partie cliente en Ajax il devient alors possible de ne redéfinir qu&#8217;une partie de l&#8217;interface.</p>
<p>Dans la démo Play! Booking, ce mécanisme est implémenté &laquo;&nbsp;à la main&nbsp;&raquo; dans la page index.html. Tout est fait avec du jQuery et le tag jsAction de Play!, qui appelle des actions du controller Play. Celui-ci retourne alors des fragments de HTML, ce qui fait que la version Play! est aussi ajaxisé. Je reconnais que c&#8217;est moins évident et facile, mais les 2 se discutent.</p>
<p>Il y a donc un BookingService avec une méthode <strong>findHotels</strong> pour rechercher la liste des hôtels, d&#8217;après le Flow XML. Il s&#8217;agit d&#8217;une interface, ce qui permet de changer l&#8217;implémentation. Dans notre cas nous n&#8217;aurons que la version JPA. Si vous avez une forte envie de faire une version <em>PasJPA</em> notez que c&#8217;est super utile&#8230;</p>
<pre class="brush:java">public interface BookingService {
   // j'ai effacé les autres méthodes ici pour ne garder que l'essentiel

    public List&lt;hotel&gt; findHotels(SearchCriteria criteria);

}</pre>
<p>Le service implémente l&#8217;interface, j&#8217;ai supprimé une bonne partie du code afin de ne vous laissez que ce qui nous intéresse. Mais croyez-moi, la version complète est assez verbeuse. Ce qui nous intéresse ici c&#8217;est uniquement la méthode <em>findHotels</em></p>
<pre class="brush:java">@Service("bookingService")
@Repository
public class JpaBookingService implements BookingService {

    private EntityManager em;

    @PersistenceContext
    public void setEntityManager(EntityManager em) {
        this.em = em;
    }

   // Note : j'ai effacé du code ici pour ne garder que quelques méthodes

    @Transactional(readOnly = true)
    @SuppressWarnings("unchecked")
    public List findHotels(SearchCriteria criteria) {
        String pattern = getSearchPattern(criteria);
        return em.createQuery(
                "select h from Hotel h where lower(h.name) like " + pattern + " or lower(h.city) like " + pattern
                        + " or lower(h.zip) like " + pattern + " or lower(h.address) like " + pattern + " order by h."
                        + criteria.getSortBy()).setMaxResults(criteria.getPageSize()).setFirstResult(
                criteria.getPage() * criteria.getPageSize()).getResultList();
    }

   // Note 2 : j'ai effacé du code ici pour ne garder que quelques méthodes

   // helpers
   private String getSearchPattern(SearchCriteria criteria) {
        if (StringUtils.hasText(criteria.getSearchString())) {
            return "'%" + criteria.getSearchString().toLowerCase().replace('*', '%') + "%'";
        } else {
            return "'%'";
        }
    }

}</pre>
<p>Le plus intéressant est donc la méthode findHotels. Elle permet d&#8217;effectuer la recherche, de retourner une List d&#8217;Hotel à la vue, que nous verrons tout à l&#8217;heure si vous êtes toujours motivé.</p>
<h3>III.2) Le contrôleur version Play! Framework</h3>
<p>L&#8217;approche de Play! est un peu plus simple mais demande un peu plus de code Java.<br />
Je précise tout de suite : j&#8217;ai modifié l&#8217;exemple afin de retirer la partie Authentification et pour ne me concentrer que sur le Use-Case de récupérer la liste des Hotel correspondant à un critère entré dans l&#8217;interface utilisateur.</p>
<pre class="brush:java">public class Hotels extends Controller {

    public static void list(String search, Integer size, Integer page) {
        List hotels = null;
        page = page != null ? page : 1;
        if(search.trim().length() == 0) {
            hotels = Hotel.all().fetch(page, size);
        } else {
            search = search.toLowerCase();
            hotels = Hotel.find("lower(name) like ? OR lower(city) like ?", "%"+search+"%", "%"+search+"%").fetch(page, size);
        }
        render(hotels, search, size, page);
    }
   ...
    // Note : code effacé pour ne conserver que la méthode list
   ...
}</pre>
<p>L&#8217;approche de Play! Framework est donc la suivante :<br />
- écrire une classe dans le répertoire &laquo;&nbsp;controllers&nbsp;&raquo; qui étend la class Controller de Play!<br />
- écrire une méthode public static avec en argument les paramètres de la vue. Play! se charge de vous récupérer ce que l&#8217;utilisateur a entré. Notez ensuite l&#8217;appel pour récupérer la liste des Hotels :</p>
<pre class="brush:java">            search = search.toLowerCase();
            hotels = Hotel.find("lower(name) like ? OR lower(city) like ?", "%"+search+"%", "%"+search+"%").fetch(page, size);</pre>
<p>La méthode find est une méthode statique définie dans la classe JPASupport. Elle permet d&#8217;exécuter des requêtes JPA. Vous pouvez aussi écrire une méthode dans l&#8217;entité Hotel pour éviter de placer ici du code technique par exemple. Les 2 approches se valent.</p>
<h3>III.3) Différence d&#8217;approche</h3>
<p>La version Spring WebFlow demande plus de XML, ce qui personnellement me dérange. Je trouve que la définition des flows n&#8217;est pas simple. C&#8217;est même une fausse bonne idée. Je préfère une approche fortement typée en Java, où par contre pour que la magie opère, je dois étendre des classes spécialisées de Play! Framework.</p>
<p>Côté test, il est assez simple de <a href="http://static.springsource.org/spring-webflow/docs/2.0.x/reference/htmlsingle/spring-webflow-reference.html#testing">tester Spring WebFlow</a>, mais je n&#8217;ai pas testé personnellement.</p>
<p>Je vais être méchant avec Spring WebFlow : je trouve cela bien compliqué pour résoudre un problème simple. Ici quel est l&#8217;apport du XML ? Des annotations ? Est-ce que notre vie est plus simple grâce à ce système ? Permettez-moi d&#8217;en douter.</p>
<p>C&#8217;est peut-être une révolution par rapport à l&#8217;approche Struts, mais tant qu&#8217;à faire la révolution, il ne faut pas s&#8217;arrêter à un concept basé sur un fichier XML pour définir la navigation d&#8217;une application Web.</p>
<h3>III. 4) Synthèse</h3>
<h4>Avantages de Spring Web Flow</h4>
<p>- possibilité de déclarer en quelques lignes un bout de code pour que la vue récupère le Model sans devoir définir un controller.<br />
- gestion de la navigation de l&#8217;utilisateur fine dans le site<br />
- se repose sur des Services facile à tester pour s&#8217;assurer que le Model est correct<br />
- bien meilleur que l&#8217;approche classique où les DAO dans les Services ne servent à rien<br />
- Spring MVC récupère les paramètres de la vue et les dénormalise, ce qui est très pratique.<br />
- bonne intégration de la sécurité</p>
<h4>Inconvénients de Spring Web Flow</h4>
<p>- clairement plus compliqué que Play! sur ce point<br />
- XML tu aimes ou tu n&#8217;aimes pas, mais c&#8217;est <strong>ton</strong> environnement de développement Web<br />
- gestion pas facile pour les débutants entre les view-states, les action-states, les transitions etc.<br />
- l&#8217;EntityManager à la main dans le service : pas top. Mais c&#8217;est quelque chose qui est souvent factorisé dans des classes de GenericService par exemple, avec un DAO&#8230; Bref encore 3 ou 4 classes Java en plus.</p>
<h4>Avantages de Play! Framework :</h4>
<p>- le controlleur déclare des méthodes static et public qui deviennent autant d&#8217;URL dans la vue<br />
- le framework se charge de récupérer et dénormaliser les paramètres de la vue<br />
- approche full java<br />
- les entités ont un moteur comme GORM en Grails mais plus simple. Cela permet d&#8217;avoir des finders comme méthode statique sur l&#8217;entité Hotel. C&#8217;est cependant statique et plus limité que Grails/GORM.</p>
<h4>Inconvénients de Play! Framework :</h4>
<p>- le controller de base étend une class de Play! (si la spécialisation vous dérange plutôt que la composition)<br />
- la gestion des workflows compliqué demande un effort de développement par rapport à Spring WebFlow, qui sera capable de retomber sur ses pieds.</p>
<h2>IV. La Vue</h2>
<p>Je vais maintenant évaluer plusieurs critères :<br />
- la création d&#8217;une page pour chacune des technos<br />
- la qualité de l&#8217;expérience utilisateur avec l&#8217;utilisation d&#8217;Ajax<br />
- la taille des pages webs et les temps de chargement</p>
<h3>IV.1) Créer une page avec Spring Faces</h3>
<p>Basé sur JSF, cette partie sera donc essentiellement une discussion sur JSF plutôt que sur Spring. Je parlerai un peu de la taglibs de Spring pour la partie validation du côté client, que je trouve très bien fait. Mais l&#8217;essentiel du débat porte plus sur JSF ici.</p>
<p>Dans le projet Spring Webflow, les pages sont construites à partir d&#8217;un template, avec la technologie Facelets. Très pratique, cela vous permet de construire le canevas de votre site, puis de spécialiser vos vues en écrivant peu de code.</p>
<p>Le template standard.xhtml :</p>
<pre class="brush:html">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;f:view xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
	  xmlns:c="http://java.sun.com/jstl/core"
	  xmlns:sf="http://www.springframework.org/tags/faces"
	  contentType="text/html" encoding="UTF-8"&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;
	&lt;title&gt;Spring Faces: Hotel Booking Sample Application&lt;/title&gt;

	&lt;sf:includeStyles/&gt;
	&lt;sf:resourceGroup&gt;
		&lt;sf:resource path="/css-framework/css/tools.css"/&gt;
		&lt;sf:resource path="/css-framework/css/typo.css"/&gt;
		&lt;sf:resource path="/css-framework/css/forms.css"/&gt;
		&lt;sf:resource path="/css-framework/css/layout-navtop-localleft.css"/&gt;
		&lt;sf:resource path="/css-framework/css/layout.css"/&gt;
	&lt;/sf:resourceGroup&gt;
	&lt;sf:resource path="/styles/booking.css"/&gt;
	&lt;ui:insert name="headIncludes"/&gt;
&lt;/head&gt;
&lt;body class="tundra spring"&gt;
&lt;div id="page"&gt;
	&lt;div id="header" class="clearfix spring"&gt;
		&lt;div id="welcome"&gt;
			&lt;div class="left"&gt;Spring Travel: A Spring Faces Reference Application&lt;/div&gt;
			&lt;div class="right"&gt;
				&lt;c:if test="${not empty currentUser.name}"&gt;
	            	Welcome, ${currentUser.name} | &lt;a href="${request.contextPath}/spring/logout"&gt;Logout&lt;/a&gt;
				&lt;/c:if&gt;
				&lt;c:if test="${empty currentUser.name}"&gt;
	            	&lt;a href="${request.contextPath}/spring/login"&gt;Login&lt;/a&gt;
				&lt;/c:if&gt;
			&lt;/div&gt;
		&lt;/div&gt;
		&lt;div id="branding" class="spring"&gt;
			&lt;a href="#{request.contextPath}"&gt;&lt;img src="${request.contextPath}/resources/images/header.jpg" alt="Spring Travel"/&gt;&lt;/a&gt;
		&lt;/div&gt;
	&lt;/div&gt;
	&lt;div id="content" class="clearfix spring"&gt;
		&lt;div id="local" class="spring"&gt;
			&lt;a href="http://www.thespringexperience.com"&gt;
				&lt;img src="${request.contextPath}/resources/images/diplomat.jpg" alt="generic hotel" /&gt;
			&lt;/a&gt;
			&lt;a href="http://www.thespringexperience.com"&gt;
				&lt;img src="${request.contextPath}/resources/images/tse.gif" alt="The Spring Experience" /&gt;
			&lt;/a&gt;
			&lt;p&gt;
			&lt;/p&gt;
		&lt;/div&gt;
		&lt;div id="main"&gt;
			&lt;ui:insert name="content"/&gt;
		&lt;/div&gt;
	&lt;/div&gt;
	&lt;div id="footer" class="clearfix spring"&gt;
		&lt;a href="http://www.springframework.org"&gt;&lt;img src="${request.contextPath}/resources/images/powered-by-spring.png" alt="Powered by Spring" /&gt;&lt;/a&gt;
	&lt;/div&gt;
&lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;
&lt;/f:view&gt;</pre>
<p>La page &laquo;&nbsp;reviewHotels.xhtml&nbsp;&raquo; avec 52 balises HTML+JSF permet d&#8217;afficher la liste des Hôtels :</p>
<pre class="brush:html">&lt;!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;ui:composition 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:sf="http://www.springframework.org/tags/faces"
				template="/WEB-INF/layouts/standard.xhtml"&gt;

&lt;ui:define name="content"&gt;

&lt;h:form id="hotels"&gt;
	&lt;div class="section"&gt;
		&lt;h2&gt;Hotel Results&lt;/h2&gt;
		&lt;p&gt;
			&lt;sf:commandLink value="Change Search" action="changeSearch"/&gt;
		&lt;/p&gt;
		&lt;ui:fragment id="searchResultsFragment"&gt;
			&lt;div id="searchResults"&gt;
				&lt;h:outputText id="noHotelsText" value="No Hotels Found" rendered="#{hotels.rowCount == 0}"/&gt;
				&lt;h:dataTable id="hotels" styleClass="summary" value="#{hotels}" var="h" rendered="#{hotels.rowCount &gt; 0}"&gt;
					&lt;h:column&gt;
						&lt;f:facet name="header"&gt;
							&lt;sf:commandLink id="sortByNameLink" action="sort" value="Name" processIds="*"&gt;
								&lt;f:param name="sortBy" value="name" /&gt;
							&lt;/sf:commandLink&gt;
						&lt;/f:facet&gt;
						#{h.name}
					&lt;/h:column&gt;
					&lt;h:column&gt;
						&lt;f:facet name="header"&gt;Address&lt;/f:facet&gt;
						#{h.address}
					&lt;/h:column&gt;
					&lt;h:column&gt;
						&lt;f:facet name="header"&gt;
							&lt;sf:commandLink id="sortByCity" action="sort" value="City, State" processIds="*" &gt;
								&lt;f:param name="sortBy" value="city" /&gt;
							&lt;/sf:commandLink&gt;
						&lt;/f:facet&gt;
						#{h.city}, #{h.state}, #{h.country}
					&lt;/h:column&gt;
					&lt;h:column&gt;
						&lt;f:facet name="header"&gt;Zip&lt;/f:facet&gt;
						#{h.zip}
					&lt;/h:column&gt;
					&lt;h:column&gt;
						&lt;f:facet name="header"&gt;Action&lt;/f:facet&gt;
						&lt;sf:commandLink id="viewHotelLink" value="View Hotel" action="select"/&gt;
					&lt;/h:column&gt;
				&lt;/h:dataTable&gt;
				&lt;div class="buttonGroup"&gt;
					&lt;sf:commandLink id="previousPageLink" value="Previous results" action="previous" rendered="#{searchCriteria.page &gt; 0}"/&gt;
					&lt;sf:commandLink id="nextPageLink" value="More Results" action="next" rendered="#{not empty hotels and hotels.rowCount == searchCriteria.pageSize}"/&gt;
				&lt;/div&gt;
			&lt;/div&gt;
		&lt;/ui:fragment&gt;
	&lt;/div&gt;
&lt;/h:form&gt;
&lt;/ui:define&gt;
&lt;/ui:composition&gt;</pre>
<p>Ce que j&#8217;apprécie à titre personnel avec JSF :<br />
- possibilité d&#8217;écrire du code de mise en forme sans avoir besoin de faire trop de CSS<br />
- moteur de construction de page assez proche d&#8217;une vue client lourd<br />
- possibilité d&#8217;écrire avec la syntaxe JSF et d&#8217;avoir un rendu riche sans se prendre la tête avec du Javascript ou des feuilles de style.<br />
&lt;HUMOUR&gt;De toutes les façons, je suis pas développeur Web. Donc mort aux CSS&#8230;&lt;/HUMOUR&gt;</p>
<p>Ce qui me fait un peu tiquer, c&#8217;est que l&#8217;on dit au développeur Java : tu n&#8217;auras pas besoin d&#8217;apprendre à faire une mise en page compliquée en HTML et CSS&#8230;</p>
<p>Mais bon, vous vous foutez pas un peu de nous là ?</p>
<p>La page demande 52 balises. Et ce dataTable pourrait très bien être un simple TABLE en HTML avec une CSS non ? Ce qui d&#8217;ailleurs est le cas au final non ?</p>
<h3>IV.2) Créer une page avec Play! Framework</h3>
<p>Attention cela pique les yeux. Comme JSF ou Wicket, vous pouvez utiliser un éditeur HTML pour construire votre page. En effet, le format des pages de Play! Framework est très original <strong>puisque c&#8217;est du HTML</strong> ni plus, ni moins. Il y a cependant l&#8217;utilisation de Groovy qui risque de faire peur à quelques uns. Je note cela comme un inconvénient par rapport à JSF.</p>
<p>La version livrée avec Play! utilise jQuery et Ajax à fond. Il y a en fait une page principale, puis un ensemble de fonction Javascript pour ne charger rapidement que ce qui change dans un DIV au format HTML. C&#8217;est radicalement différent, et peut-être moins facile d&#8217;abord pour des gens n&#8217;ayant jamais fait de Web. Je vous montre donc plutôt ici ma version &laquo;&nbsp;<em>gars qui a fait du Java et du Web et qui découvre Play</em>&nbsp;&raquo;</p>
<p>Play! Framework dispose aussi d&#8217;un moteur de template. Je vais donc vous montrer 2 fichiers. Le fichier main.html est un template de base que j&#8217;utilise pour le site :</p>
<pre class="brush:html">&lt;!DOCTYPE html&gt;

&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;#{get 'title' /}&lt;/title&gt;
        &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;
        &lt;link rel="stylesheet" type="text/css" media="screen" href="@{'/public/stylesheets/main.css'}"&gt;
        #{get 'moreStyles' /}
        &lt;link rel="shortcut icon" type="image/png" href="@{'/public/images/favicon.png'}"&gt;
        &lt;script src="@{'/public/javascripts/jquery-1.3.2.min.js'}" type="text/javascript" charset="utf-8"&gt;&lt;/script&gt;
        &lt;script src="@{'/public/javascripts/sessvars.js'}" type="text/javascript" charset="utf-8"&gt;&lt;/script&gt;
        #{get 'moreScripts' /}
    &lt;/head&gt;
    &lt;body&gt;

        &lt;div id="header"&gt;
            &lt;h1&gt;play framework booking demo&lt;/h1&gt;
            #{if user?.id}
                &lt;div id="options"&gt;
                    Connected as ${user.username}
                    |
                    &lt;a href="@{Hotels.index()}"&gt;Search&lt;/a&gt;
                    |
                    &lt;a href="@{Hotels.settings()}"&gt;Settings&lt;/a&gt;
                    |
                    &lt;a href="@{Application.logout()}"&gt;Logout&lt;/a&gt;
                &lt;/div&gt;
            #{/if}
        &lt;/div&gt;

        &lt;div id="content"&gt;
            #{if flash.error}
                &lt;p class="fError"&gt;
                    &lt;strong&gt;${flash.error}&lt;/strong&gt;
                &lt;/p&gt;
            #{/if}
            #{if flash.success}
                &lt;p class="fSuccess"&gt;
                    &lt;strong&gt;${flash.success}&lt;/strong&gt;
                &lt;/p&gt;
            #{/if}

            #{doLayout /}

        &lt;/div&gt;

        &lt;div id="footer"&gt;
            Created with &lt;a href="http://www.playframework.org"&gt;play framework&lt;/a&gt; and really inspirated from the booking sample application provided by &lt;a href="http://seamframework.org/"&gt;seam framework&lt;/a&gt;
        &lt;/div&gt;

    &lt;/body&gt;
&lt;/html&gt;</pre>
<p>Voici la page qui affiche la liste des Hotels. Le fichier s&#8217;appelle &laquo;&nbsp;list.html&nbsp;&raquo; comme le nom de la méthode <em>list</em> du Controller Hotels que nous avons vu plus haut. Il est bien entendu possible de déclarer un nom différent et de configurer une autre route avec Play! Framework.</p>
<p>Le fichier est assez simple : il reçoit un objet List&lt;Hotel&gt;, il itère en Groovy avec un tag spécifique à Play et il affiche le résultat dans un tableau HTML :</p>
<pre class="brush:html">
#{extends 'main.html' /}
#{set title:'Search result'/}

#{if hotels}
&lt;table&gt;
    &lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Name&lt;/th&gt;
        &lt;th&gt;Address&lt;/th&gt;
        &lt;th&gt;City, State&lt;/th&gt;
        &lt;th width="8%"&gt;Zip&lt;/th&gt;
        &lt;th width="13%"&gt;Action&lt;/th&gt;
    &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
    #{list hotels, as:'hotel'}
    &lt;tr&gt;
        &lt;td&gt;${hotel.name}&lt;/td&gt;
        &lt;td&gt;${hotel.address}&lt;/td&gt;
        &lt;td&gt;${hotel.city}, ${hotel.state}, ${hotel.country}&lt;/td&gt;
        &lt;td&gt;${hotel.zip}&lt;/td&gt;
        &lt;td&gt;
            &lt;a href="@{show(hotel.id)}"&gt;View Hotel&lt;/a&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
    #{/list}
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
    &lt;a id="nextPage" href="${page+1}"&gt;More results&lt;/a&gt;
&lt;/p&gt;
#{/if}

#{else}
&lt;p&gt;
    No more results
&lt;/p&gt;
#{/else}</pre>
<p>La version Play! est très dépouillée. L&#8217;inconvénient : il sera nécessaire dans les 2 cas (JSF comme Play!) d&#8217;apprendre la technologie de rendu et les tags pour travailler efficacement. Mais Play! n&#8217;est pas orienté composant comme JSF. Il n&#8217;y a pas d&#8217;utilisation de l&#8217;Expression Language, ici c&#8217;est Groovy. Ce moteur Groovy est un poil plus lent que <a href="http://www.playframework.org/modules/japid">Japid</a>, un autre moteur Java qui est disponible pour Play!</p>
<p>Regardez aussi <a href="http://www.playframework.org/modules">la liste des modules de Play! Framework</a>. Il y a du lourd comme le support de Scala, le moteur NoSQL MongoDB, Guice, GWT ou le module Search avec Lucene (comme Hibernate Search en plus simple).</p>
<p>Un inconvénient de Play! pour les personnes qui n&#8217;ont jamais fait de Web : la mise en page et la partie CSS. Lorsque je monte un projet avec Play! Framework, j&#8217;utilise par exemple <a href="http://960.gs/">CSS 960 grid system</a>. Je connais ces systèmes car j&#8217;ai un gros background Web. Pour le CSS, pour sélectionner des couleurs qui ne font pas vomir l&#8217;utilisateur, j&#8217;ai pleins d&#8217;outils comme <a href="http://kuler.adobe.com/">Kuler</a> d&#8217;Adobe pour préparer des styles&#8230; Donc pour moi qui suit très Web : je peux faire un truc joli avec Play! Framework. Je pourrai styliser mes tableaux sans soucis. Je pense que ce qui est bien avec JSF, c&#8217;est que cela vous aide à monter vos pages facilement, à construire vos formulaires ou vos tableaux sans devoir devenir une bête en HTML/CSS. Mais c&#8217;est un peu dommage, lorsque l&#8217;on voit le potentiel d&#8217;HTML 5 pour les années qui viennent.</p>
<h3>IV.3) Expérience utilisateur</h3>
<p>J&#8217;ai lancé les 2 applications et j&#8217;ai effectué une comparaison en tant qu&#8217;utilisateur. Je donne l&#8217;avantage à la version Spring Faces. Je trouve que la librairie de Spring de validation du côté client est très sympa.</p>
<p>En terme de rapidité, la version Play! Framework est vraiment plus réactive. Si je clique comme un dingue avec un script Selenium, la version Spring WebFlow est à la peine alors que la version Play! se tourne les pouces sans s&#8217;essoufler.</p>
<h3>IV.5) Taille des pages Webs</h3>
<p>La page d&#8217;affichage de la liste des Hôtels sur Spring WebFlow (cliquez sur l&#8217;image pour l&#8217;afficher en grand) :<br />
<a href="http://www.touilleur-express.fr/wp-content/page_spring_webflow_result.jpg"><img class="alignnone size-medium wp-image-3739" title="page_spring_webflow_result" src="http://www.touilleur-express.fr/wp-content/page_spring_webflow_result-300x236.jpg" alt="" width="300" height="236" /></a></p>
<p>La version Play! Framework :<br />
<a href="http://www.touilleur-express.fr/wp-content/page_hotels_play.jpg"><img class="alignnone size-medium wp-image-3740" title="page_hotels_play" src="http://www.touilleur-express.fr/wp-content/page_hotels_play-300x261.jpg" alt="" width="300" height="261" /></a></p>
<p>Mes tests avec YSlow en effectuant 10 chargements de la page puis en prenant la moyenne :</p>
<p><strong>Moyenne des temps de chargement de la page liste des Hotels pour 10 hotels:</strong><br />
- Play! Framework en mode Dev ou Prod : 0,234 secondes<br />
- Spring WebFlow avec Jetty : 1.286 secondes<br />
- Spring WebFlow avec Tomcat 6.0.20 : 1.092 secondes</p>
<p>Le mode Prod de Play! ne prend qu&#8217;un peu plus de temps à démarrer, mais je n&#8217;ai pas constaté de différence une fois le serveur lancé.</p>
<p><strong>Volume de la partie HTML sans CSS/Images et temps de chargement :</strong><br />
Si je ne regarde que la partie HTML sans prendre en compte le temps de chargement des images, je teste réellement que la partie serveur.</p>
<p>Play! Framework : chargement de 3.1 kb en un temps moyen de 14ms<br />
Tomcat+Spring : chargement de 14kb en un temps moyen de 52 ms</p>
<p>Donc pour un affichage similaire, vous voyez le souci ? <strong>la version Spring Faces de cette démonstration est 5 fois plus lourde et demande 4 à 5 fois plus de temps</strong>. Je ne dis pas qu&#8217;en général c&#8217;est le cas, mais pour notre exemple oui c&#8217;est le cas. Et nous sommes sur le même cahier des charges : afficher dans un tableau une liste d&#8217;Hôtel.</p>
<h2>V. Conclusion</h2>
<p>Si vous avez pris le temps de lire cet énorme article jusqu&#8217;au bout, merci. Revenez voir le code des deux version en détail. Téléchargez chacune des versions et donnez vos propres arguments techniques en faveur de l&#8217;un ou de l&#8217;autre.</p>
<p>J&#8217;ai envie de taper du poing sur la table : <strong>il est temps de revoir le développement Web en Java</strong>.<br />
Le développement Web demande des compétences. Si vous ne les avez pas, ne prenez pas une techno pour couvrir vos lacunes. Apprenez à faire du Web. Désolé, le XML ne m&#8217;excite pas. Play! est plus facile à apprendre que toute la stack Spring que je vous ai présenté. Car elle est plus simple et tout aussi puissante.</p>
<p>Pour construire une application Web compliquée ou d&#8217;entreprise, est-ce que dans 5 ans nous ferrons toujours du JSF ? ou est-ce que nous ferrons du HTML+CSS+jQuery ? Je pose la question. Evidemment, Play! Framework doit encore faire ses preuves et on peut me retourner l&#8217;argument. Mais c&#8217;est plus simple, plus réaliste et plus facile à maintenir.</p>
<p>Le point faible de Play! par rapport à un framework comme Spring Faces+Spring WebFlow+JSF c&#8217;est qu&#8217;il faut plus d&#8217;efforts pour construire ses composants dans la partie vue. D&#8217;un autre côté, lorsque vous avez un framework aussi puissant que JSF, vous avez envie de prendre des tableaux avancés, des richTables, ou des composants plus puissants. Cela entraîne parfois le risque de prendre des composants qui font trop par rapport à un tableau simple. D&#8217;ailleurs, si vous ne preniez pas ces composants, quel intérêt à utiliser une librairie JSF ? Je pose la question.</p>
<p>Un risque est donc d&#8217;utiliser des composants riches trop facilement dans une application Web avec JSF. Vous vous retrouvez avec un tableau avec des colonnes triables, alors que vous n&#8217;en n&#8217;avez pas besoin. Et votre page pèse 15-20kb au lieu de peser 2-5kb, et demande de la mémoire et du CPU du côté serveur.</p>
<p>Le site &laquo;&nbsp;<a href="http://www.express-board.fr/">eXpress-Board</a>&nbsp;&raquo; tourne sur la même machine que le blog &laquo;&nbsp;Le Touilleur Express&nbsp;&raquo; avec 3 parts chez Gandi, soit 768Mo. Le process Java tourne avec 128 Mo de mémoire, et prend entre 5 et 16% de l&#8217;utilisation de la machine, bien loin de MySQL qui est très sollicité par WordPress pour le Blog.</p>
<p>Je vais me faire taper par les maîtres Javas qui ne vont pas être d&#8217;accord. Mais c&#8217;est la première fois où j&#8217;en ai rien à faire, car je suis sûr de mes arguments.</p>
<p>Allez SuperTroll, sort du bois, je t&#8217;attends.</p>
<p>On va bien s&#8217;amuser&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.touilleur-express.fr/2010/05/13/spring-faceswebflowjava-classique-compare-a-play-framework/feed/</wfw:commentRss>
		<slash:comments>44</slash:comments>
		</item>
		<item>
		<title>Evénement Spring à Paris le mercredi 4 novembre 2009</title>
		<link>http://www.touilleur-express.fr/2009/10/23/evenement-spring-a-paris-le-jeudi-4-novembre-2009/</link>
		<comments>http://www.touilleur-express.fr/2009/10/23/evenement-spring-a-paris-le-jeudi-4-novembre-2009/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 07:09:47 +0000</pubDate>
		<dc:creator>Nicolas Martignole</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.touilleur-express.fr/?p=2186</guid>
		<description><![CDATA[SFEIR et SpringSource organisent le mercredi 4 novembre les Rencontre SpringSource 2009 à Paris à la Défense . L&#8217;an dernier cela avait été l&#8217;occasion d&#8217;interviewer Guillaume Laforge (chef de projet du langage Groovy), Peter Cooper-Ellis (Vice-president of Engineering and Product Managment) et Jürgen Holler (Architecte en Chef du framework Spring). Vu le programme cette année, je regrette de ne pas être disponible. Voici le communiqué de SpringSource et de SFEIR.
Voir : http://www.rencontres-spring.com/
SpringSource lance une matinée de présentation le 4 novembre à la Défense (adresse plus bas).
Avec l’émergence du cloud, la ...]]></description>
			<content:encoded><![CDATA[<p><strong>SFEIR et SpringSource organisent le mercredi 4 novembre <a href="http://www.springsource.com/fr/blog/les-rencontres-spring-2009">les Rencontre SpringSource 2009</a> à Paris à la Défense . <a href="http://www.touilleur-express.fr/2008/11/13/compte-rendu-des-rencontres-spring-2008/">L&#8217;an dernier</a> cela avait été l&#8217;occasion d&#8217;interviewer Guillaume Laforge (chef de projet du langage Groovy), Peter Cooper-Ellis (Vice-president of Engineering and Product Managment) et Jürgen Holler (Architecte en Chef du framework Spring). Vu le programme cette année, je regrette de ne pas être disponible. Voici le communiqué de SpringSource et de SFEIR.</strong></p>
<p>Voir : <a href="http://www.rencontres-spring.com/">http://www.rencontres-spring.com/</a></p>
<p><em>SpringSource lance une matinée de présentation le 4 novembre à la Défense (adresse plus bas).</p>
<p>Avec l’émergence du cloud, la possibilité d’adapter les ressources système en fonction de ses besoins immédiats devient une réalité. L’intégration de SpringSource au sein de VMWare va permettre de combiner deux technologies en une seule pour révolutionner le cycle de vie complet d’une application dans le cloud.</p>
<p>Pour cet événement, nous faisons venir:</p>
<p>    * Adrian Colyer, le CTO de SpringSource, qui présentera l’ensemble des développements clés de notre roadmap.<br />
    * Javier Soltero, Chief Technology Officer for Management Products, qui montrera tous les avantages à utiliser notre solution de monitoring Hyperic pour manager et déployer dans le cloud.<br />
    * Arjen Poutsma, Senior Entreprise Application Architect, qui dévoilera les fonctionnalités avancées de la nouvelle release Spring 3.0</p>
<p>Leurs présentations seront en Anglais.</p>
<p>Le détail précis du programme ainsi que le formulaire de pré-inscription sont disponibles à cette adresse: http://www.rencontres-spring.com/category/2009</p>
<p>L’événement aura lieu au centre d’affaires NCI ComSquare, en bas de l’esplanade de la Défense, toutes les indications précises sont disponibles à cette adresse: http://www.groupenci.com/fr/ile-de-france/defense.com-square.html</p>
<p>Cette matinée va être la grande première en France pour dévoiler la stratégie entre SpringSource &#038; VMWare. Les sessions seront très interactives et vous donneront l’occasion de poser vos questions et d’obtenir toutes les explications sur le cloud de demain.</p>
<p>En espérant vous compter parmi nous!</em></p>
<p>J&#8217;ai rencontré Adrian Colyer en Suisse, c&#8217;est une personne vraiment intéressante et riche. Si vous voulez vous plonger dans sa présentation de Jazoon 2009, vous pouvez relire <a href="http://www.touilleur-express.fr/2009/06/25/jazoon-day-3-adrian-coyler/">cet article</a> que j&#8217;ai écrit en juin dernier. Si vous êtes plutôt intéressé par Spring 3.0, j&#8217;ai aussi suivi <a href="http://www.touilleur-express.fr/2009/06/23/jazoon-spring-30-whats-new/">la présentation de Jürgen Hoeller</a> toujours à Jazoon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.touilleur-express.fr/2009/10/23/evenement-spring-a-paris-le-jeudi-4-novembre-2009/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Jazoon : Spring 3.0 what&#039;s new ?</title>
		<link>http://www.touilleur-express.fr/2009/06/23/jazoon-spring-30-whats-new/</link>
		<comments>http://www.touilleur-express.fr/2009/06/23/jazoon-spring-30-whats-new/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 21:53:08 +0000</pubDate>
		<dc:creator>Nicolas Martignole</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[jazoon]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.touilleur-express.fr/?p=1547</guid>
		<description><![CDATA[Après Groovy, j&#8217;attaque ma tournée par une conférence d&#8217;une personne absente de Devoxx 2008, Jürgen Holler de SpringSource, pour sa présentation sur Spring 3.0. Il nous présentera une version actualisée par rapport à JavaOne, l&#8217;avantage d&#8217;être à Jazoon.
Voici le plan de sa présentation:
- Java 5 Themes
- REST
- EL expression language
- Annotated web controllers
- RoadMap
Dans un premier temps, Jurgen Hoeler, que j&#8217;avais interviewé en novembre dernier, nous donne la vision de Spring. La version 3.0 sera tout d&#8217;abord le support de Java 5, avec l&#8217;utilisation massif des annotations. Il explique par ...]]></description>
			<content:encoded><![CDATA[<p>Après Groovy, j&#8217;attaque ma tournée par une conférence d&#8217;une personne absente de Devoxx 2008, Jürgen Holler de SpringSource, pour sa présentation sur <a href="http://jazoon.com/en/conference/presentationdetails.html?type=sid&#038;detail=7440">Spring 3.0</a>. Il nous présentera une version actualisée par rapport à JavaOne, l&#8217;avantage d&#8217;être à Jazoon.</p>
<div id="attachment_1549" class="wp-caption alignnone" style="width: 510px"><img src="http://www.touilleur-express.fr/wp-content/img_4128.jpg" alt="Jurgen Hoeler SpringSource Jazoon 2009" title="SpringSource at Jazoon 2009" width="500" height="408" class="size-full wp-image-1549" /><p class="wp-caption-text">Jurgen Hoeler SpringSource Jazoon 2009</p></div>
<p>Voici le plan de sa présentation:<br />
- Java 5 Themes<br />
- REST<br />
- EL expression language<br />
- Annotated web controllers<br />
- RoadMap</p>
<p>Dans un premier temps, Jurgen Hoeler, que j&#8217;avais interviewé <a href="http://www.touilleur-express.fr/2008/11/13/compte-rendu-des-rencontres-spring-2008/">en novembre dernier</a>, nous donne la vision de Spring. La version 3.0 sera tout d&#8217;abord le support de Java 5, avec l&#8217;utilisation massif des annotations. Il explique par exemple que dans Spring MVC, l&#8217;objectif est d&#8217;apporter les améliorations via les Annotations. Pour cette raison il nous encourage à utiliser celles-ci plutôt que le code classique pour les Controllers par exemple.<br />
Le support de l&#8217;expression language (EL) permet d&#8217;offrir des fichiers XML et des classes encore plus configurable. L&#8217;exemple qu&#8217;il a prit nous montre ainsi une DataSource dont le nom exact de la base n&#8217;est connu qu&#8217;à l&#8217;exécution. Si vos fichiers de configuration XML de Spring sont déjà configurables à l&#8217;aide de propriétés externes, cela vous semblera familier.<br />
Viens ensuite la présentation de REST. Dans l&#8217;architecture de Spring 3.0, le support de REST sera là, et vu le temps passé pour nous en parler, on pense à Java EE 6 et au profile Lite qui n&#8217;a justement pas&#8230; JAX-RS en standard.<br />
Le support de la JSR-303 (Bean Validation) aussi présent dans Java EE 6, sera offert par Spring. Comprendre par là, que les annotations seront reconnues et que la validation des beans sera effectuée par le framework Spring. Intéressant à noter.<br />
Les Portlets 2.0 retiennent mon attention, c&#8217;est l&#8217;un des sujets en ce moment chez mon client. Tout d&#8217;abord il explique que la spécification Portlet 1.0 étant assez incomplète, le support des Portlets 2.0 par Spring devrait permettre d&#8217;offrir un socle simple pour écrire des Portlets. Il cite JBoss Portal et eXo Portal.<br />
Concernant le support de Java EE 6, Spring 3.0 attend la sortie de la version finale de Java EE 6. Tout ce qui est JSF2.0 et JPA2.0 ne sont donc pas encore prévu dans la version qui sortira&#8230; courant juillet. Tout du moins pas officiellement, mais en early preview.</p>
<p>Un retour sur Java 5 pour nous montrer ce qu&#8217;il y a de nouveau. Tout d&#8217;abord grâce aux génériques, le framework offrira un typage plus fort comme dans cet exemple:</p>
<pre>
BeanFactory returns typed bean instances as far as possible
T getBean(String name, Class<t> requiredType)
Map<string ,T> getBeansOfType(Class<t> type)
</t></string></t></pre>
<p>Concernant l&#8217;exécution de tâches asynchrones, Spring 3.0 proposera un TaskExecutor (ce n&#8217;est pas déjà le cas ?). La gestion des tâches asynchrones sera plus facile. Pas de mentions des Annotations.</p>
<p>A propos de Spring WebFlow : la nouvelle version propose une version révisée de la gestion du binding et de la conversion de type.<br />
A propos ensuite (vous suivez ?) de la gestion des Annotations standards de Java, Spring offre le support des annotations du projet Java Config, la gestion de l&#8217;instanciation tardive des Beans avec le mot clé @Lazy.</p>
<p>A propos de l&#8217;Expression Language j&#8217;ai pris un exemple de l&#8217;un de ses slides pour vous montrer comment il serait possible d&#8217;injecter une proprieté à l&#8217;exécution :</p>
<pre>
@Repository
public class R {
	@Value("#{systemProps.dbname}")
	public void setDatabaseName(String dbName){
	...
	}

}
</pre>
<p>N&#8217;importe quel de vos Beans Spring est accessible avec l&#8217;EL, ce qui permet aussi de récupérer la valeur d&#8217;une propriété d&#8217;un autre Bean pour l&#8217;injecter en paramètre&#8230; Je ne vous parle pas des problèmes d&#8217;instanciations tardives, car il est tard.</p>
<p>Concernant le support de REST avec Spring 3.0 : Spring MVC offre un support de REST accessible facilement et qui permet d&#8217;ajouter à une application Spring MVC le support de REST. Par contre si vous souhaitez utiliser JAX-RS&#8230; ce n&#8217;est pas possible. C&#8217;est l&#8217;un ou l&#8217;autre&#8230; &laquo;&nbsp;On attendra de voir ce que les clients  veulent&nbsp;&raquo;</p>
<pre>
@RequestMapping(value = "/rewards/{id}",nethod = GET)
public Reward reward (@PathVariable("id") long id){
	return this.rewardsService.findReward(id);
}
</pre>
<p>Du côté du code, on note aussi l&#8217;apparition d&#8217;annotations supplémentaires (youpi déjà qu&#8217;on avait terminé tout l&#8217;autre stock, sympa d&#8217;en remettre encore) pour par exemple lire les paramètres des entêtes HTTP ou des Cookies, ce qui peut être utile pour la gestion de la localisation par exemple. Les 2 annotations sont @RequestHeader et @CookieValue.</p>
<p><strong>Conclusion</strong><br />
Voilà pour la présentation de Spring. Jürgen est un bon speaker qui présente son sujet de manière synthétique. On sent la pression pour sortir en juillet la version, avant la sortie en septembre de son copain Java EE 6. L&#8217;un n&#8217;ayant d&#8217;ailleurs rien à voir avec l&#8217;autre.</p>
<p>Next please !</p>
<p>PS: j&#8217;ai rectifé l&#8217;orthographe de Jürgen, il suffisait de regarder le premier slide au début de cet article.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.touilleur-express.fr/2009/06/23/jazoon-spring-30-whats-new/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSR-299 vs JSR CrazyBob</title>
		<link>http://www.touilleur-express.fr/2009/05/11/jsr-299-crazy-bob/</link>
		<comments>http://www.touilleur-express.fr/2009/05/11/jsr-299-crazy-bob/#comments</comments>
		<pubDate>Mon, 11 May 2009 21:16:21 +0000</pubDate>
		<dc:creator>Nicolas Martignole</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.touilleur-express.fr/?p=1207</guid>
		<description><![CDATA[Prenez le temps de lire les quelques 68 commentaires échangés entre Gavin King (auteur d&#8217;Hibernate, spec lead de la JSR-299 WebBeans) et Bob Lee &#171;&#160;Crazy Bob&#160;&#187; (auteur de Google Guice, lead developer de la librairie Google Android). Je vous renvoie vers le très bon billet écrit par Guillaume Carré sur le blog de Xebia pour le fond du débat, car après avoir lu les échanges, je me suis demandé si quelqu&#8217;un s&#8217;était déjà posé la question suivante : à quoi servent les JSR (Java Specification Requests) ?
Il y a plus ...]]></description>
			<content:encoded><![CDATA[<p>Prenez le temps de lire <a href="http://in.relation.to/Bloggers/CommentsOnAnnotationsForDependencyInjection">les quelques 68 commentaires échangés</a> entre Gavin King (auteur d&#8217;Hibernate, spec lead de la JSR-299 WebBeans) et <a href="http://crazybob.org/2009/05/announcing-javaxinjectinject.html">Bob Lee &laquo;&nbsp;Crazy Bob&nbsp;&raquo;</a> (auteur de Google Guice, lead developer de la librairie Google Android). Je vous renvoie vers <a href="http://blog.xebia.fr/2009/05/11/inject-standardisation-de-linjection-de-dependances/">le très bon billet</a> écrit par Guillaume Carré sur le blog de Xebia pour le fond du débat, car après avoir lu les échanges, je me suis demandé si quelqu&#8217;un s&#8217;était déjà posé la question suivante : à quoi servent les <a href="http://fr.wikipedia.org/wiki/Java_Specification_Requests">JSR</a> (Java Specification Requests) ?</p>
<p>Il y a plus de 10 ans, SUN Microsystems a eu l&#8217;excellente initiative de libérer le processus de définition du langage Java. L&#8217;objectif à l&#8217;époque était de prendre en compte les demandes grandissantes d&#8217;évolution des différents éditeurs du tout jeune langage Java. Rappelons que chaque JSR propose une implémentation de référence de la spécification, avec un code source accessible. Il faut aussi mettre au point un lot de tests afin de proposer un TCK (Technology Compatibility Kit).</p>
<p><strong>Un match de boxe</strong><br />
Gavin King est spec leader de la JSR-299, spécification apparue début 2006 et qui est en phase finale, afin d&#8217;être livrée d&#8217;ici septembre 2009 dans la future version JEE6. Au début de cet année, la spécification initialement présentée comme WebBeans a été renommée &laquo;&nbsp;<a href="http://in.relation.to/Bloggers/RevisedPublicDraftOfJSR299JavaContextsAndDependencyInjection">Java Context and Dependency Injection</a>&laquo;&nbsp;. Derrière tout cela, les acteurs de la communauté avait noté que la spécification avait en effet évolué vers l&#8217;injection de service, le terme WebBeans était alors trop réducteur par rapport à la portée de la spécification. Pourtant en relisant ne serait-ce que les premières lignes de la JSR, on voit que le scope initial, intimement lié à JBoss Seam, était la gestion du cycle de vie dans une application Web&#8230;</p>
<p>La spécification a aujourd&#8217;hui bien évolué, et propose un standard d&#8217;injection de dépendances à Java EE 6. Preuve que le processus communautaire a du bon, il est claire que la future version entreprise de Java sera plus mature et plus flexible que les versions antérieures. L&#8217;effort du JCP, et je pense que les standards ont du bon, est que la spec JSR-299 offre un moyen <strong>standard</strong> donc portable d&#8217;apporter de l&#8217;injection de dépendance à une application d&#8217;entreprise. Je n&#8217;ai rien contre Spring, je pense qu&#8217;il est plutôt bon et raisonnable de conserver le système libre et d&#8217;offrir (tardivement) une spécification d&#8217;injection pour les services et les dépendances.</p>
<p><strong>Un petit pavé</strong><br />
Crazy Bob jette un pavé dans la marre en annonçant <a href="http://crazybob.org/2009/05/announcing-javaxinjectinject.html">le 5 mai dernier</a> une proposition de JSR sponsorisée par Google, SpringSource,PicoContainer, Plexus, Tapestry IoC, et Simject en portant l&#8217;effort sur un scope plus réduit. Il souhaite proposer une spécification afin que l&#8217;injection de dépendance soit un standard dans Java SE 7 par exemple. Il pense même qu&#8217;il sera possible en 5 mois de finaliser cette JSR afin de l&#8217;inclure dans la future version de Java EE6. C&#8217;est tout simplement impossible, voir irréaliste. Cela entraine bien entendu une réaction un peu épidermique des personnes de la spécification JSR-299. Vous suivez toujours ?</p>
<p>Pourtant cette initiative n&#8217;est pas inutile car :<br />
- elle offrirait une gestion de l&#8217;injection native dans Java<br />
- elle ne nous forcerait pas à utiliser tout Java EE6<br />
- elle reste pragmatique et ne se focalise que sur les points précis de l&#8217;IoC que tout le monde utilise (Guice, Spring&#8230;)<br />
- elle nous permettrait de rendre portable notre code d&#8217;injection (Spring vers Guice, Guice vers Spring, Spring vers Spring&#8230;)</p>
<p><strong>JSR-299 une marieuse</strong><br />
Nous avons d&#8217;un côté la JSR-299 qui est pour moi une marieuse : faire se rencontrer les différents composants de votre application d&#8217;entreprise, vous aider à faire collaborer votre application avec la gestion des sources externes. A ce titre je pense qu&#8217;il est indispensable d&#8217;avoir cela sous la forme d&#8217;une spécification. Cela en fait certainement l&#8217;une des JSR les plus complexes.</p>
<p><strong>Le petit nouveau</strong><br />
D&#8217;autre part, nous avons des développeurs utilisateurs de Spring et de Guice qui souhaitent rendre standard l&#8217;injection de dépendance dans une spécification. Cela revient aussi à dire que tout le monde recevrait le support de l&#8217;IoC&#8230; même ceux qui s&#8217;en passent très bien.</p>
<p>Tout ceci ne vous intéressera que si vous faîtes appel à l&#8217;injection de dépendance, que vous le faîtes car vous souhaitez changer de framework d&#8217;IoC, que vous vous fichez du reste des excellents fonctionnalités dans Spring comme la gestion des abstractions (JDBC,JMS,Securité&#8230;), la programmation orientée Aspect, la gestion des Transactions, bref que vous ne vous intéressez QUE à l&#8217;injection de dépendance&#8230; Est-ce bien réaliste ?</p>
<p>N&#8217;oublions pas aussi les &laquo;&nbsp;mauvais&nbsp;&raquo; effet de la surinjection de dépendance. Nous avons tous vu une fois une application avec des fichiers de mapping obèses, où le framework d&#8217;injection de dépendance est sur-utilisé. Rien ne remplace une architecture propre et une bonne utilisation des patterns. Je ne suis pas un fan du &laquo;&nbsp;tout-Spring&nbsp;&raquo; comme je n&#8217;étais pas fan du &laquo;&nbsp;tout EJB&nbsp;&raquo;.</p>
<p><strong>Alors à quoi servent les JSR ?</strong></p>
<p>Le principe des spécifications ouvertes a apporté à Java une bouffée d&#8217;oxygène. Dès 98 cela a été le moyen de sécuriser les investissements des clients finaux. Grâce à la normalisation et aux standards, un code écrit en Java sur Windows et compilé avec la JVM de SUN fonctionne sur votre serveur Solaris, avec votre serveur d&#8217;application Oracle Weblogic et JRockit. Standard est donc synonyme de sécurité, d&#8217;indépendance et de pérennité dans le temps. Les JSR sont donc un ensemble de règles appuyées par une implémentation de référence, avec accès libre au code source, ce qui nous sécurise et évite de devenir dépendant d&#8217;un éditeur de logiciel.</p>
<p><strong>La dure vérité</strong><br />
Deuxième effet notoire : il y a toujours quelqu&#8217;un de plus intelligent que vous. Il y a toujours un petit gars quelque part dans le monde qui a déjà eu cette idée géniale. Il y aura toujours un étudiant prêt à faire 60 heures par semaine pour coder une API. Il y aura toujours un Doug Lea ou un Gavin King avec un oeil d&#8217;artiste sur le code.<br />
Java et donc les JSR vous apprennent une chose : vous êtes une m&#8230; et il va falloir faire avec. Non vous n&#8217;êtes pas génial à avoir pensé vous aussi à un framework d&#8217;inversion de contrôle. Le principe a été décrit en <a href="http://www.laputan.org/drc/drc.html">1988</a> à ma connaissance. Non arrêtez d&#8217;écrire des classes comme &laquo;&nbsp;SynchronizedHashMap&nbsp;&raquo; et reprenez la lecture de la spécification Java.</p>
<p>Les spécifications sont donc un moyen de s&#8217;assurer que les meilleurs principes se diffusent et que la plateforme Java évolue. C&#8217;est un canal de diffusion de la connaissance, qui permet aux éditeurs et aux acteurs de la communauté Open-Source de travailler main dans la main (ou poing dans figure aussi) mais de travailler ensemble. Quelque part, je vois cela comme les tests indépendants <a href="http://www.euroncap.com/home.aspx" target="new">EuroNCAP</a> de crash-test des voitures. Mine de rien, en 10 ans nous avons tous un ABS et bientôt l&#8217;ESP sur nos voitures, car un organisme indépendant a décidé de noter les constructeurs sur la sécurité de nos voitures.</p>
<p><strong>Conclusion</strong><br />
Les standards ont du bon, merci à CrazyBob de penser qu&#8217;une JSR pour une version light de l&#8217;IoC est une bonne idée. Par contre j&#8217;ai franchement du mal à me projeter dans 2 ans, et à imaginer un standard de facto pour l&#8217;IoC. L&#8217;approbation de cette JSR par l&#8217;Expert Group, dont fait partie RedHat (Gavin King) pour sortir d&#8217;ici 5 mois me semble tout simplement impossible. Mais comme je vous le disais : nous sommes bêtes et nous devons donc attendre patiemment que les gourous du JCP s&#8217;organisent afin de s&#8217;accorder sur cette JSR.</p>
<p>Messieurs de RedHat, de SpringSource et de SUN-Oracle : respirez un grand coup et revenez vous assoir afin de travailler ensemble, car le plus gros risque que court Java serait que ce processus soit remis en cause. Il faut que la communauté reste prudente et fasse la distinction entre ce qui est important pour faire évoluer Java, de ce qui est purement manoeuvre de noyautage. Il n&#8217;y a pas de guerre froide entre les grands acteurs (Oracle/SUN, RedHat/JBoss, Google, IBM et SpringSource) et il serait dommage de commencer à casser ce système.</p>
<p>Pour terminer allez lire les échanges entre Gavin King et Bob Lee : <a href=" http://in.relation.to/Bloggers/CommentsOnAnnotationsForDependencyInjection"></p>
<p>http://in.relation.to/Bloggers/CommentsOnAnnotationsForDependencyInjection</a></p>
<p>La page sur la proposition de JSR Light sans sucre d&#8217;injection de dépendance :<br />
<a href="http://google-code-updates.blogspot.com/2009/05/javaxinjectinject.html">http://google-code-updates.blogspot.com/2009/05/javaxinjectinject.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.touilleur-express.fr/2009/05/11/jsr-299-crazy-bob/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spring : keep-it under control</title>
		<link>http://www.touilleur-express.fr/2009/03/10/bovicoja/</link>
		<comments>http://www.touilleur-express.fr/2009/03/10/bovicoja/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 23:01:06 +0000</pubDate>
		<dc:creator>Nicolas Martignole</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.touilleur-express.fr/?p=858</guid>
		<description><![CDATA[Note à mes collègues en particulier : on en parle après le stand-up ?
Dans notre application cet après-midi j&#8217;ai vu un problème de déclaration de propriétés Spring au moment du chargement de mon application.  Un fichier de Properties chargé par Spring lors du démarrage par un PropertyPlaceholderConfiguration n&#8217;était pas à jour, il me manquait 3 propriétés&#8230; soit.
Quelque part, je me demande si le fait de retarder finalement tardivement cette vérification est une si bonne idée. J&#8217;ai dû attendre le démarrage de mon application sur Weblogic et ensuite l&#8217;exécution de ...]]></description>
			<content:encoded><![CDATA[<p><i>Note à mes collègues en particulier : on en parle après le stand-up ?</i></p>
<p>Dans notre application cet après-midi j&#8217;ai vu un problème de déclaration de propriétés Spring au moment du chargement de mon application.  Un fichier de Properties chargé par Spring lors du démarrage par un <a href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html">PropertyPlaceholderConfiguration</a> n&#8217;était pas à jour, il me manquait 3 propriétés&#8230; soit.<br />
Quelque part, je me demande si le fait de retarder finalement tardivement cette vérification est une si bonne idée. J&#8217;ai dû attendre le démarrage de mon application sur Weblogic et ensuite l&#8217;exécution de mon premier batch pour le voir&#8230;<br />
C&#8217;est la vie.<br />
Je n&#8217;ai plus qu&#8217;à aller m&#8217;immoler pour ne pas avoir pensé à mettre à jour mon fichier primeweb.properties&#8230;. ou pas.</p>
<p>Que se passerait-il avec un simple EJB ?  Que se passerait-il avec du code classique old-school qui serait capable de me dire poliment que 3 propriétés ne sont pas renseignées ? Là pour tout vous dire, j&#8217;ai pris une grande exception en pleine face. Je regarderai demain comment au moins mettre un peu de vérification afin de rendre plus polie mon application.</p>
<p>Alors j&#8217;ai regardé le fichier application.xml&#8230; et il y en a du monde.<br />
Un peu comme un car de supporter de l&#8217;OM/du PSG/de l&#8217;OL de retour d&#8217;un match, c&#8217;était un sacré foutoir pour comprendre comment dans ce sac de nœud personne n&#8217;avait été blessé jusqu&#8217;à maintenant. Il y avait au début du fichier une organisation assez simple avec un DAO, deux Beans déclarés normalement.<br />
Et plus je suis entré dans ce fichier de configuration, plus j&#8217;ai eu du mal à comprendre les relations entre Beans&#8230; Un peu comme les acteurs d&#8217;un sitecom, on ne sait plus très bien qui couche avec qui&#8230; Il faut alors configurer votre IDEA (IntelliJ supporte très bien Spring) et il est ensuite tout à fait possible de comprendre les déclarations. Ce n&#8217;est pas la faute de Spring, c&#8217;est notre faute à nous. On est généreux, nous avons mis un peu tout et n&#8217;importe quoi sous la forme de Bean comme un groupe de junkie très excité à l&#8217;idée de s&#8217;injecter des dépendances&#8230;</p>
<p><strong>L&#8217;inversion de contrôle est un concept franchement sympa tant qu&#8217;on garde le contrôle. </strong><br />
<em>Inversion of Control is a nice concept if you keep some sort of control</em>, copyright nicolas martignole pour la version pour l&#8217;export&#8230;<br />
A vouloir trop retourner la responsabilité du code, est-ce que finalement nous n&#8217;avons pas mis dans un fichier XML un peu trop de choses ? Le prix à payer pour cette flexibilité très pratique lors des tests, est qu&#8217;une partie de la vérification qui était effectuée à la compilation, voir au démarrage de l&#8217;application, est maintenant pris en charge par Spring. Et ça, ça me dérange. Ce n&#8217;est pas la faute de Spring, c&#8217;est encore une fois notre faute à nous.<br />
Pour peu que quelqu&#8217;un propose un outil, nous sommes tentés de nous en servir et un peu comme un enfant avec un pistolet ou un bouledogue avec un bébé : aie cela fait mal.</p>
<p>Les EJB3 ont un mérite : ils arrivent après la version actuelle de Spring 2.5. Et à ce titre, je commence vraiment à croire que c&#8217;est une option très sérieuse qui dans le cadre d&#8217;une application de gestion, est tout à fait convenable. J&#8217;ai hâte d&#8217;acheter et de lire <a href="http://www.antoniogoncalves.org/xwiki/bin/view/Main/WebHome">le livre d&#8217;Antonio Goncalves du Paris JUG</a> car je pense qu&#8217;il y aura du bons sens.</p>
<p>Spring reste un très bon framework qui ne fait pas que de l&#8217;IoC (Inversion of Control) mais aussi beaucoup d&#8217;autres tâches barbantes. La gestion de la partie JDBC, des templates JMS ou des Transactions : merci ! cela nous évite de devoir gérer une soupe technique peu intéressante.<br />
Cependant pour certains cas (que je devrai préciser si j&#8217;étais un gars bien) je continuerai à faire du BoViCoJa  (Bon Vieux Code Java) au lieu d&#8217;utiliser Spring.<br />
Que l&#8217;on ne m&#8217;accuse pas de cracher dans la soupe, mais qu&#8217;en même temps les gens prennent conscience qu&#8217;il ne faut pas tout faire faire par Spring. Il sera parfois plus intéressant de faire du code classique et d&#8217;éviter de déclarer une Interface, puis une seule implémentation, pour ensuite l&#8217;injecter dans votre code.</p>
<p>Je vous parlerai la prochaine fois de notre copain NoClassDefFoundError et d&#8217;AspectJ, le tout mijoté avec du Maven2 et des problèmes de dépendance.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.touilleur-express.fr/2009/03/10/bovicoja/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Introduction à Spring Integration</title>
		<link>http://www.touilleur-express.fr/2009/02/19/spring/</link>
		<comments>http://www.touilleur-express.fr/2009/02/19/spring/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 22:04:34 +0000</pubDate>
		<dc:creator>Nicolas Martignole</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[esb]]></category>
		<category><![CDATA[mule]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.touilleur-express.fr/?p=783</guid>
		<description><![CDATA[Spring Integration est la solution d&#8217;intégration proposée par la communauté Spring. Cousin très proche de Mule, Spring Integration vous permet de réduire le code d&#8217;infrastructure technique de votre application. En quelques lignes vous pouvez ainsi lire un fichier sur le disque, vérifier chaque ligne puis ensuite enregistrer vers une base les données chargées.
La version 1.0 a été annoncé en décembre dernier, Mark Fisher propose de vous montrer en 10 minutes comment écrire un service simple et faire fonctionner Spring Integration : http://blog.springsource.com/2009/02/13/982/.
Dans son post dont j&#8217;ai repris le code ci-dessous, ...]]></description>
			<content:encoded><![CDATA[<p>Spring Integration est la solution d&#8217;intégration proposée par la communauté Spring. Cousin très proche de Mule, Spring Integration vous permet de réduire le code d&#8217;infrastructure technique de votre application. En quelques lignes vous pouvez ainsi lire un fichier sur le disque, vérifier chaque ligne puis ensuite enregistrer vers une base les données chargées.</p>
<p>La version 1.0 a été annoncé en décembre dernier, Mark Fisher propose de vous montrer en 10 minutes comment écrire un service simple et faire fonctionner Spring Integration : <a href="http://blog.springsource.com/2009/02/13/982/">http://blog.springsource.com/2009/02/13/982/</a>.</p>
<p>Dans son post dont j&#8217;ai repris le code ci-dessous, nous déclarons un bean Spring et nous allons montrer comment envoyer un message via Spring Integration.</p>
<p>La configuration Spring importe le namespace de Spring Integration et permet de déclarer le bean Shouter :<br />
 </p>
<pre name="code" class="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:si="http://www.springframework.org/schema/integration"
xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/integration

http://www.springframework.org/schema/integration/spring-integration-1.0.xsd"&gt;

&lt;si:channel id="input"/&gt;

&lt;si:channel id="output"&gt;
&lt;si:queue capacity="10"/&gt;
&lt;/si:channel&gt;

&lt;si:service-activator input-channel="input" output-channel="output" ref="shouter" method="shout"/&gt;

&lt;bean id="shouter" class="blog.Shouter"/&gt;

&lt;/beans&gt;
</pre>
<p>Voyons le bean Java qui va recevoir notre message et y ajouter des points d&#8217;exclamation:</p>
<pre class="java">public class Shouter {
    public String shout(String s) {
        return s.toUpperCase().concat("!!!");
    }
}</pre>
<p>Le code Java pour tester le tout est simple :</p>
<pre class="java">public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("blog/config.xml");
    MessageChannel input = (MessageChannel) context.getBean("input");
    PollableChannel output = (PollableChannel) context.getBean("output");

    input.send(new StringMessage("Le Touilleur Express"));
    Message&lt; ?&gt; reply = output.receive();

    System.out.println("received: " + reply);
}</pre>
<p><strong>A quoi sert Spring Integration ?</strong><br />
Spring Integration permet de réduire le code technique de votre application. Vous lisez un message sur une queue JMS, vous voulez envoyer un email, vous souhaitez lire un fichier et le convertir vers un autre format, faire un traitement par batch, télécharger via FTP un fichier ou SSH, alors Spring Integration pourra vous intéresser.</p>
<p><strong>Peut-on comparer Spring Integration à Mule ?</strong><br />
Pour qui connaît un peu <a href="http://www.mulesource.org/display/MULE/Home">Mule 2</a>, la ressemblance est frappante. Ross Mason, l&#8217;auteur de Mule, a tenté un moment de se rapprocher de la communauté Spring, mais celle-ci a préféré offrir une solution basée exclusivement sur Spring. Il n&#8217;y a pas de comparaison possible au sens &laquo;&nbsp;l&#8217;un est mieux que l&#8217;autre&nbsp;&raquo;. Mule a cependant un peu plus de recul, <a href="http://www.muleforge.org/">dispose de beaucoup plus de connecteurs</a> que Spring Integration pour l&#8217;instant. Sa communauté est assez active. Si vous souhaitez utiliser par exemple Tibco Rendezvous ou faire du SSH, il faudra utiliser Mule.<br />
Je pense qu&#8217;il est intéressant de connaître les deux projets et de ne pas s&#8217;aventurer à faire un choix, s&#8217;il faut en faire un.</p>
<p><strong>Est-ce que Spring Integration est un ESB ?</strong><br />
Non, je dirai que c&#8217;est un framework léger d&#8217;intégration comme Apache Camel, mais pas un ESB. Le produit OpenESB basé sur le serveur d&#8217;application Glassfish est un ESB, car il est composé d&#8217;une API d&#8217;une part et d&#8217;un moteur d&#8217;autre part. Mule est un ESB léger, il propose son propre moteur ou il peut fonctionner dans une application Web. Spring Integration est par contre une brique peut-être plus facile à mettre en oeuvre si vos besoins sont avant tout techniques.</p>
<p><strong>Pour aller plus loin</strong><br />
Le site de la communauté muleForge : <a href="http://www.muleforge.org/">http://www.muleforge.org/</a><br />
Le site de Mule 2 : <a href="http://www.mulesource.org">http://www.mulesource.org</a><br />
<a href="http://blog.xebia.fr/2007/12/17/spring-integration-lavenement-des-lightweight-esb/">Article de Cyrille Le Clerc</a> sur le blog de Xebia en 2007<br />
Article de Sébastien Letélié d&#8217;Improve sur les ESB : <a href="http://www.itaware.eu/tag/spring-integration/">Java Camp II DB and ESB</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.touilleur-express.fr/2009/02/19/spring/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SpringFuse beta 2 disponible</title>
		<link>http://www.touilleur-express.fr/2009/01/25/springfuse-beta-2-disponible/</link>
		<comments>http://www.touilleur-express.fr/2009/01/25/springfuse-beta-2-disponible/#comments</comments>
		<pubDate>Sun, 25 Jan 2009 17:29:25 +0000</pubDate>
		<dc:creator>Nicolas Martignole</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[celerio]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.touilleur-express.fr/?p=726</guid>
		<description><![CDATA[Jaxio annonce la sortie de la version beta de SpringFuse, la version hébergée du logiciel Celerio.
SpringFuse est un générateur de projet qui vous fait gagner du temps. En partant de ce que nous avons tous dans nos application, une base de données, il vous permet en quelques minutes de générer du code. Jusqu&#8217;ici vous me dîtes &#171;&#160;&#8230;.comme AppFuse&#171;&#160;. Là où SpringFuse innove je trouve, c&#8217;est sur la qualité de ce qui est généré. Basé sur Spring MVC, Hibernate, SiteMesh, la liste complète de ce que vous recevez quelques minutes après ...]]></description>
			<content:encoded><![CDATA[<p>Jaxio annonce la sortie de la version beta de SpringFuse, la version hébergée du logiciel Celerio.<br />
SpringFuse est un générateur de projet qui vous fait gagner du temps. En partant de ce que nous avons tous dans nos application, une base de données, il vous permet en quelques minutes de générer du code. Jusqu&#8217;ici vous me dîtes &laquo;&nbsp;&#8230;.<i>comme AppFuse</i>&laquo;&nbsp;. Là où SpringFuse innove je trouve, c&#8217;est sur la qualité de ce qui est généré. Basé sur Spring MVC, Hibernate, SiteMesh, <a href="http://www.springfuse.com/signup/features.action">la liste complète</a> de ce que vous recevez quelques minutes après avoir lancé la génération est intéressante.<br />
C&#8217;est surtout sur la qualité du code généré, qui permet de gagner du temps et de reprendre des parties de votre logiciel rapidement, en se concentrant ensuite sur le code métier.<br />
Il est possible de tester gratuitement le service, ce que j&#8217;ai fait par curiosité sur une base chez nous. J&#8217;ai pris une table avec 60 000 entrées, 14 colonnes, des données financières. Après 10 minutes en effet j&#8217;avais mon serveur jetty démarré, mes données affichées, et un code avec tests, documentation, configuration, et des exemples de pages pour continuer tout seul.<br />
Du côté des performances, le code généré par SpringFuse et déployé sur Jetty affiche plus vite les données dans un tableau simple que mon client TOAD !<br />
Derrière c&#8217;est la qualité du code, la configuration du cache de deuxième niveau d&#8217;Hibernate et surtout un modèle de programmation qui reprend les principes vus dans les meilleurs livres. J&#8217;ai ainsi appris de nouvelles astuces en lisant simplement le code généré.</p>
<p>Pour les vieux lecteurs du Touilleur (pas ceux qui n&#8217;ont plus de cheveux, ceux qui me lisent depuis un an) vous savez sans doute que je connais bien Florent Ramière et Nicolas Romanetti de Jaxio dont <a href="http://www.touilleur-express.fr/2008/06/03/rencontre-avec-la-societe-jaxio-et-le-produit-celerio/">je vous ai déjà parlé</a> sur le Touilleur. C&#8217;est donc en toute subjectivité (et pas objectivité) que j&#8217;ai testé l&#8217;outil.</p>
<p>Je vous donne mon avis : pensez au temps gagné en utilisant un outil qui génère en 1 minute ce que vous pouvez écrire en une bonne semaine de travail&#8230;<br />
Testez-le, faîtes-vous votre avis, pensez-y pour faire du refactoring  de votre logiciel. Vous avez une base de données ? vous êtes curieux et prêt à vous remettre en question ? Alors rendez-vous sur <a href="http://www.springfuse.com  ">http://www.springfuse.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.touilleur-express.fr/2009/01/25/springfuse-beta-2-disponible/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Devoxx : ESB in Financial Application</title>
		<link>http://www.touilleur-express.fr/2008/12/27/devoxx-esb-in-financial-application/</link>
		<comments>http://www.touilleur-express.fr/2008/12/27/devoxx-esb-in-financial-application/#comments</comments>
		<pubDate>Fri, 26 Dec 2008 23:00:26 +0000</pubDate>
		<dc:creator>Nicolas Martignole</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[devoxx]]></category>
		<category><![CDATA[esb]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[mule]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.touilleur-express.fr/?p=635</guid>
		<description><![CDATA[Cette année j&#8217;ai eu l&#8217;occasion de présenter un sujet sous la forme d&#8217;un Quickie à Devoxx. Il s&#8217;agit d&#8217;une mini-présentation limitée à 15 minutes, à l&#8217;heure du déjeuner. Au final j&#8217;ai bien aimé cette première expérience, en anglais et devant pas mal de monde mine de rien. Voici la présentation en français.
1. ESB in Financial Application

2. Objectif de la présentation

En quinze minutes, l&#8217;idée de cette présentation est d&#8217;expliquer les besoins rencontrés dans le monde de la finance en terme d&#8217;architecture. Où en sommes-nous aujourd&#8217;hui et quels outils pouvons-nous utiliser afin ...]]></description>
			<content:encoded><![CDATA[<p>Cette année j&#8217;ai eu l&#8217;occasion de présenter un sujet sous la forme d&#8217;un Quickie à <a href="http://www.devoxx.com">Devoxx</a>. Il s&#8217;agit d&#8217;une mini-présentation limitée à 15 minutes, à l&#8217;heure du déjeuner. Au final j&#8217;ai bien aimé cette première expérience, en anglais et devant pas mal de monde mine de rien. Voici la présentation en français.</p>
<p><strong>1. ESB in Financial Application</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.001-001.png"/></p>
<p><strong>2. Objectif de la présentation</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.003-001.png"/><br />
En quinze minutes, l&#8217;idée de cette présentation est d&#8217;expliquer les besoins rencontrés dans le monde de la finance en terme d&#8217;architecture. Où en sommes-nous aujourd&#8217;hui et quels outils pouvons-nous utiliser afin de réduire les coûts et améliorer nos architectures ?</p>
<p><strong>3. Speaker&#8217;s Qualifications</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.004-001.png"/><br />
Après 5 ans 1/2 chez Reuters, j&#8217;ai débuté une nouvelle activité en tant qu&#8217;indépendant. Je travaille actuellement chez BNP-Paribas sur une mission d&#8217;architecture. Je suis membre du Paris Java User Group.</p>
<p><strong>4. ESB</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.005-001.png"/><br />
ESB. Ce mot est à la mode. A Devoxx j&#8217;ai compté 4 conférences cette année. Mule est traité 3 fois par Antoine Borg avec qui j&#8217;ai eu le plaisir de discuter la veille, bref il se passe quelque chose. A noter qu&#8217;aucune conférence ne nous parle de téléphone portable, les thèmes cette année tournent autour de l&#8217;intégration, de la sécurité ou de SOA. Voyons un peu &laquo;&nbsp;dans la vraie vie&nbsp;&raquo; où nous en sommes aujourd&#8217;hui, car moi, plutôt que de parler de SOA ou d&#8217;ESB, j&#8217;aime bien parler du terrain avant tout.</p>
<p><strong>5. A legacy application</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.006-001.png"/><br />
Ce que l&#8217;on constate c&#8217;est que les applications vieillissantes dans le monde Java des applications de gestion et de la finance, se présentent avec un socle d&#8217;architecture bien connu. Autour d&#8217;une architecture trois-tiers, nous retrouvons souvent du Struts pour la partie Web, un serveur d&#8217;application avec encore beaucoup d&#8217;EJB 2.1, et les innovations des dernières années que sont Hibernate, Spring et JMS. Et il est clair que ce type d&#8217;architecture aujourd&#8217;hui en production est encore amené à perdurer pour quelques années.<br />
Votre travail sera donc de faire vivre, d&#8217;améliorer ou de transformer ce type d&#8217;architecture.</p>
<p><strong>6. A legacy application (cont.)</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.006-004.png"/><br />
Dans la finance, une application web communique et échange des ressources avec le monde extérieur en utilisant un certain nombre de connecteurs techniques (boîtes vertes). Ce code est bien souvent du code développé au fur et à mesure des besoins. Il peut s&#8217;agir de lire un fichier, d&#8217;échanger via JMS avec une autre application, de faire appel à un web service, ou d&#8217;envoyer un email. Bref, du code massivement technique. Ce code est le socle de communication de chaque application de gestion.</p>
<p><strong>7. Connect</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.007-001.png"/><br />
Connecter.<br />
Le besoin de Connecter différents systèmes. Ce besoin entraine un travail de médiation, de transformation et d&#8217;interconnexion entre systèmes. Je veux montrer ici qu&#8217;il y a forcément un besoin de connexion, au minimum avec une base de données relationnelles, mais bien souvent avec d&#8217;autres systèmes informatiques ou techniques. C&#8217;est une composante fondamentale de nos solutions, de ce que nous sommes appelés à développer.</p>
<p><strong>8. Ecosystem</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.008-001.png"/><br />
J&#8217;ai représenté sur ce slide une application financière typique de création de rapports, utilisé sur une plateforme de Prime Brokerage. Ce que nous voyons tout d&#8217;abord, c&#8217;est que cette application a besoin d&#8217;un environnement pour fonctionner, un écosystème. Cet écosystème est composé d&#8217;un grand nombre d&#8217;applications, maintenu par d&#8217;autres équipes que la mienne.<br />
Mon application est représentée au milieu avec ses 3 services internes.</p>
<p><strong>9. Ecosystem 2</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.008-003.png"/><br />
Cette application utilise les données du marché ainsi qu&#8217;un service de tenue de Position. Aujourd&#8217;hui les échanges entre les systèmes s&#8217;effectuent avec des fichiers plats via des répertoires partagés ou via JMS. Dans le livre Enterprise Integration Pattern, une excellente présentation explique les avantages et les inconvénients de ces 2 types d&#8217;échange.</p>
<p><strong>10. Ecosystem 3</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.008-009.png"/><br />
Au delà des échanges de mon application, ce qui est encore plus intéressant c&#8217;est de constater que les autres applications échangent elles-aussi des informations entre elles. Il faut donc bien voir que nous sommes là face à un vrai réseau de communication, de médiation et d&#8217;échanges. C&#8217;est le coeur d&#8217;une architecture financière.</p>
<p><strong>11. Ecosystem 4</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.008-012.png"/><br />
Au final je dois prendre en compte que mon application cohabite, échange et transfert ses données avec un nombre assez important d&#8217;applications. Je ne rentre pas dans les détails de la partie métier, car l&#8217;idée ici n&#8217;est pas de vous donner un cours de finance des marchés, simplement d&#8217;expliquer que les systèmes sont massivement connectés en un réseau.</p>
<p><strong>12. Ecosystem 5</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.008-013.png"/><br />
&#8230; En forçant un peu le trait, je peux faire une analogie avec un réseau social comme FaceBook : mon application fait partie d&#8217;un réseau, d&#8217;autres applications m&#8217;envoient des messages, observent même les données que je produis sans que je ne le sache, il y a donc clairement un besoin important à résoudre : ce besoin de communication et d&#8217;échanges avec mes &laquo;&nbsp;amis&nbsp;&raquo;.</p>
<p><strong>13. Collaborate</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.009-001.png"/><br />
Collaborate en anglais, difficile à traduire avec le même sens en français.<br />
Collaborer c&#8217;est apprendre à se connaître : lorsque mon application échange avec d&#8217;autres systèmes financiers, au delà du problème technique à résoudre il y aura une interaction humaine. Et donc, ESB ou non, SOA ou non, ce projet d&#8217;inter-communication doit s&#8217;accompagner de la définition d&#8217;une langue pour se comprendre, d&#8217;un média pour discuter et d&#8217;un contenu pour s&#8217;entendre.<br />
Revenons un peu à notre application financière type pour parler d&#8217;un facteur très important : le temps.</p>
<p><strong>14. Timebox and Adaptive</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.010-001.png"/><br />
J&#8217;ai sélectionné ces deux photos du métro afin d&#8217;illustrer un facteur important dans les applications financières : l&#8217;importance de l&#8217;heure de la journée. Prenons le métro de Paris : le matin entre 07h00 et 09h00 il y a un métro chaque minute. A 14h il y a un métro toutes les 6 minutes. A 23h00 il y a une rame toutes les 15 minutes.<br />
Le nombre de rame de métro par heure s&#8217;adapte selon les heures d&#8217;affluence.<br />
Qu&#8217;en est-il de mon application financière ?<br />
Chaque matin celle-ci a besoin de 10 fois plus de puissance qu&#8217;en pleine journée, car la génération des rapports doit s&#8217;effectuer à la fermeture du marché boursier, dans un intervalle de temps limité. Il n&#8217;est pas possible de lancer la génération tant que le marché est ouvert. D&#8217;autre part celle-ci doit s&#8217;effectuer avant l&#8217;ouverture du marché suivant, en Asie. De fait, nous nous retrouvons avec une architecture qui doit répondre à des demandes fluctuantes selon l&#8217;heure de la journée.<br />
Mais le plus important est que notre application n&#8217;a pas le droit à une deuxième chance. Lorsqu&#8217;un bug survient, il faut que l&#8217;erreur soit corrigée avant l&#8217;ouverture du marché, et ce phénomène n&#8217;est pas contrôlable.<br />
Enfin on constate que passé les quelques heures d&#8217;activité, la plateforme est ensuite peu sollicité en cours de journée.<br />
Or le souci, c&#8217;est qu&#8217;aujourd&#8217;hui mon architecture n&#8217;est pas écologique : 16 serveurs de calcul de risk tournent en permanence, 4 serveurs d&#8217;applications sont sollicités pendant la journée mais l&#8217;utilisation des ressources est assez inégale durant la journée.<br />
Il faut donc retenir que dans la finance, l&#8217;utilisation des ressources et la quantité des échanges avec les autres systèmes varient au cours de la journée. Cependant nous savons à l&#8217;avance nos besoins, et donc idéalement notre système devrait pouvoir s&#8217;adapter et se programmer comme le réseau de transport parisien.<br />
Un site internet qui vend des ordinateurs pourrait être surpris de l&#8217;affluence de visiteur. Pas une application financière : il est possible de connaître à l&#8217;avance les besoins en énergie. Mais pourtant, il est difficile aujourd&#8217;hui de régler et d&#8217;adapter cette énergie.</p>
<p><strong>15. Crisis</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.011-003.png"/><br />
2008 marque le début d&#8217;une crise financière, qui aura un impact dès demain sur les budgets des projets dans le monde de la banque et de la finance. Nos besoins de connexions avec les autres applications financières demeurent. Je pense même qu&#8217;il y aura de nouvelles réglementations pour éviter certains dérapages de 2008. Vu la nervosité des marchés financiers, les calculs de VaR, de risque, d&#8217;appel de marge, de collatéral sur notre application de Prime Brokerage vont aussi certainement être plus intensif&#8230; Bref il va y avoir du sport en 2009.</p>
<p><strong>16. Predictions for 2009</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.012-001.png"/><br />
ll est donc facile d&#8217;imaginer ce qui nous attend : avec moins de budget, moins de liberté et plus de pressions, il va falloir trouver des solutions rapides, économiques et capables de faire réaliser des économies. Pour ma part, un calcul de risque c&#8217;est un appel de marge pour un client. Si la plate-forme sur laquelle je travaille peut traiter 50 000 calculs au lieu de 10 000 car mon architecture évolue, alors je ferai gagner de l&#8217;argent à mon client.<br />
D&#8217;autre part, vu la morosité et la crise du secteur de la finance, je pense que les solutions pragmatiques seront les gagnantes de 2009. J&#8217;ai peur que de gros projets basés sur les ESB des constructeurs souffrent du même phénomène que les constructeurs automobiles. Les gens veulent une voiture ? ils achètent une Logan et pas le dernier 4&#215;4 à la mode.<br />
Votre application a besoin d&#8217;un ESB ? Peut-être que Spring Integration, Mule ou Apache ServiceMix seront suffisants pour vos besoins, que les gros projets sur 6 mois auront plus de mal en 2009 à être validé par les DSI. Il est temps d&#8217;être pragmatique et d&#8217;arrêter de rêver sur des besoins que les grands éditeurs d&#8217;ESB nous ont peut-être inventé, comme les éditeurs de serveur d&#8217;app en 2000&#8230; Etre pragmatique, économe, écologique, réaliste.</p>
<p><strong>17. Toolbox</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.013-001.png"/><br />
En 2009 je pense que vous lirez des articles, que vous testerez, que vous entendrez parler de ces produits : Mule, Apache Service Mix, Apache Camel, Spring Integration, OpenESB project Fuji, Apache Synapse, Apache CXF, Jboss ESB&#8230; car ce sont des solutions qui répondent à un besoin : l&#8217;intégration légère en entreprise.<br />
Après la guerre des serveurs d&#8217;application il y a quelques années, je pense que la prochaine grande bataille sera sur ce front. Les éditeurs du monde open-source savent que la demande va exploser, car lorsque la crise est là comme en 2001, le monde open-source tire son épingle du jeu. En 2002 personne ne se souvient mais c&#8217;était la grande époque des articles sur Linux dans 01 informatique, le Monde informatique ect. L&#8217;administration français a alors fait un grand pas en sélectionnant des solutions comme JBoss Application Server pour traiter&#8230; nos déclarations de revenus.<br />
Economies, pragmatismes, simplifications, réductions des coûts&#8230;</p>
<p><strong>18. A New Approach</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.014-001.png"/><br />
Alors si nous  repensons à notre application de gestion du début, voici comment je la vois en 2009. Tout d&#8217;abord le Web tiers a été déporté de mon architecture. Je ne fais pas une application Web, je fais d&#8217;abord l&#8217;architecture d&#8217;une application de gestion. Le web ne me coûte pas cher, j&#8217;utilise des frameworks légers sur une recopie en lecture seule de ma base de données. Seule une petite partie du code métier est partagée avec mon espace de données principal.<br />
Ensuite on voit que j&#8217;ai cassé ce gros rectangle : je pense que des services sans états et légers sont suffisants pour effectuer les traitements de mon application. Là où auparavant j&#8217;utilisais la base de données pour stocker des données de travail, j&#8217;utilise désormais un espace mémoire en cluster afin de répliquer les données nécessaires à mes traitements de calculs. Cela demande plus de mémoire physique mais quintuple les performances de traitements. La base de données relationnelle n&#8217;intervient que via un service d&#8217;historisation qui effectue des captures de données afin de sauvegarder les données les plus sensibles, essentiellement pour un problème légal. Notez que la base est un petit carré bleu, car finalement elle ne me sert plus à grand chose.<br />
Ces services reprennent la boîte à outil dont nous avons parlé tout à l&#8217;heure. Plutôt que de chercher à faire une grosse boite qui fait tout (un ESB au sens de certains) je crée un ensemble de services qui discutent et s&#8217;échangent des données. Et plutôt que de tenter de résoudre les problèmes de communication avec les applications extérieurs, de tenter de mettre en place un gros chantier afin de mettre tout le monde sur la même plateforme, je conserve et respecte les systèmes extérieurs, je m&#8217;adapte à eux, eux ne s&#8217;adaptent pas à moi. Et là je sais que mon application pour 2009 pourra continuer à exister sans couter une fortune.<br />
Il faut donc oublier ce rêve qui serait de migrer toutes les applications de mon réseau vers un seul et même système. Ce serait un risque si l&#8217;éditeur disparaît (ce qui n&#8217;est pas exclu en ce moment). Ce serait la plus belle décision pour dégrader massivement les performances : pourquoi un système extérieure serait plus rapide que ce que mes équipes ont développé ? Ce serait un risque technique, un risque en terme de sécurité, et finalement, il faudrait attendre 6 mois avant de voir ce type de projet de gouvernance sur les rails.</p>
<p>Pour revenir à l&#8217;image du métro parisien, je rêve aussi de louer de la puissance machine plutôt que de l&#8217;acheter en utilisant par exemple Amazon EC2 et une solution comme Elastic Grid pour piloter mon parc informatique. Pour cette raison mon nouveau système est découpé en services sans état afin de faciliter une migration partielle et rapide de certains services vers ces nouvelles plate-formes de calculs et d&#8217;hébergement. La première banque qui aura déployé une plateforme de calcul de risque hostée comme un service sur internet gagnera certainement beaucoup d&#8217;argent.<br />
Economies, pragmatismes, simples, réduire les coûts, arrêter de croire au père noël, pensez sur 6 mois&#8230;</p>
<p><strong>Code code code</strong><br />
Ensuite j&#8217;ai un slide technique pour montrer un exemple d&#8217;utilisation d&#8217;Apache Camel. Lors de la conférence je n&#8217;ai pas eu assez de temps pour les présenter. Je vous ferrai un article complet sur Camel prochainement, donc revenez en janvier pour voir la suite.<br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.015-001.png"/></p>
<p><strong>Keep it simple</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.016-001.png"/><br />
Pour connecter plusieurs systèmes il est tentant de faire n&#8217;importe quoi, de faire au plus vite ou de chercher une solution chère et trop complexe pour un problème. Soyez simple et vous réussirez à développer une architecture qui fonctionne.</p>
<p><strong>Ne pas faire de l&#8217;intégration pour en faire&#8230;</strong><br />
Comme ces messieurs dans la piscine : ne cherchez pas à faire de l&#8217;ESB pour en faire, et faites attention à votre environnement. Un ESB ne remplace pas une réunion de pilotage avec l&#8217;autre équipe en face qui fait &laquo;&nbsp;l&#8217;autre&nbsp;&raquo; produit.<br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.017-001.png"/></p>
<p><strong>Don&#8217;t buy a solution</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.018-001.png"/><br />
N&#8217;achetez pas les yeux fermés une solution. Au contraire, il faut que vos équipes retroussent leurs manches, repensez à des solutions simples. Dans le monde des applications de gestion, et de la Finance, le temps est certes à l&#8217;économie, mais aussi à un pragmatisme souvent contraire à nos envies d&#8217;architectes et de consultants.</p>
<p><strong>The End</strong><br />
<img src="http://www.touilleur-express.fr/devoxx/02Devoxx2008_quickie_D8_Q_11_04_01_NMartignole.020-001.png"/><br />
En conclusion : nous avons discuté des besoins en architecture dans le monde de la finance : connecter, échanger et collaborer, inter-agir avec d&#8217;autres systèmes. Les solutions d&#8217;intégrations légères seront en 2009 un moyen de réduire les coûts en évitant d&#8217;écrire à la main du code technique sans valeur ajoutée. Je souhaite dépiler un message JMS et envoyer un email, Mule m&#8217;aide à le faire en quelques heures au lieu de perdre mon temps avec du code sans valeur. Face aux réductions de budgets, il est logique de penser que les solutions d&#8217;intégration dans la finance auront le vent en poupe en 2009. Et face à cette crise, il y aura encore plus de travail pour nous, avec encore moins de budgets, d&#8217;où la nécessité de s&#8217;outiller enfin correctement.</p>
<p>Fin de la présentation<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.touilleur-express.fr/2008/12/27/devoxx-esb-in-financial-application/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Devoxx: quel serveur d&#039;application utilisez-vous ?</title>
		<link>http://www.touilleur-express.fr/2008/12/18/devoxx-quel-serveur-dapplication-utilisez-vous/</link>
		<comments>http://www.touilleur-express.fr/2008/12/18/devoxx-quel-serveur-dapplication-utilisez-vous/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 12:01:03 +0000</pubDate>
		<dc:creator>Nicolas Martignole</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[weblogic]]></category>
		<category><![CDATA[websphere]]></category>

		<guid isPermaLink="false">http://www.touilleur-express.fr/?p=621</guid>
		<description><![CDATA[Petit sondage sur l&#8217;un des tableaux blancs installés au premier étage. Avec l&#8217;appareil photo de l&#8217;iphone mes photos étaient toutes plutôt ratées. J&#8217;ai trouvé sur flickr une image d&#8217;un des tableaux qui m&#8217;a valu une bonne discussion là-bas lorsque j&#8217;étais devant avec d&#8217;autres développeurs.
Voici le nombre de résultat par serveur d&#8217;application:

- JBoss Application Server : 136 voix
- Oracle WLS + BEA Weblogic : 75 voix
- GlassFish : 78 voix
- IBM WebSphere : 46 voix (j&#8217;adore &#171;&#160;web fear&#160;&#187;)
- Plain Tomcat, Jetty, Resin : 148 voix
- Geronimo : 5 voix
- Spring App ...]]></description>
			<content:encoded><![CDATA[<div id="attachment_622" class="wp-caption alignnone" style="width: 650px"><img class="size-full wp-image-622" title="devoxx_whiteboard_touilleur_express" src="http://www.touilleur-express.fr/wp-content/devoxx_whiteboard_touilleur_express.jpg" alt="Which application server you use?" width="640" height="432" /><p class="wp-caption-text">Which application server you use?</p></div>
<p>Petit sondage sur l&#8217;un des tableaux blancs installés au premier étage. Avec l&#8217;appareil photo de l&#8217;iphone mes photos étaient toutes plutôt ratées. J&#8217;ai trouvé sur flickr une image d&#8217;un des tableaux qui m&#8217;a valu une bonne discussion là-bas lorsque j&#8217;étais devant avec d&#8217;autres développeurs.</p>
<p>Voici le nombre de résultat par serveur d&#8217;application:</p>
<ul>
<li>- JBoss Application Server : 136 voix</li>
<li>- Oracle WLS + BEA Weblogic : 75 voix</li>
<li>- GlassFish : 78 voix</li>
<li>- IBM WebSphere : 46 voix (j&#8217;adore &laquo;&nbsp;web fear&nbsp;&raquo;)</li>
<li>- Plain Tomcat, Jetty, Resin : 148 voix</li>
<li>- Geronimo : 5 voix</li>
<li>- Spring App Server : 7 voix</li>
<li>- SAP Application Server : 2 voix</li>
<li>- JONAS : 3 voix</li>
</ul>
<p>Bref avec Spring dm Server qui arrive sur ce marché, je pense que nous allons voir l&#8217;an prochain des batailles de discussions sur &laquo;&nbsp;<em>mon mien il est meilleur que ton tiens</em>&nbsp;&raquo; comme il y a quelques années&#8230;</p>
<p>Cela promet des heures de discussions sur les blogs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.touilleur-express.fr/2008/12/18/devoxx-quel-serveur-dapplication-utilisez-vous/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nouveau : un podcast le Touilleur Express</title>
		<link>http://www.touilleur-express.fr/2008/11/15/nouveau-un-podcast-le-touilleur-express/</link>
		<comments>http://www.touilleur-express.fr/2008/11/15/nouveau-un-podcast-le-touilleur-express/#comments</comments>
		<pubDate>Sat, 15 Nov 2008 11:23:48 +0000</pubDate>
		<dc:creator>Nicolas Martignole</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[exo]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[podcast]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.touilleur-express.fr/?p=489</guid>
		<description><![CDATA[C&#8217;est fait, le premier podcast du Touilleur Express est en ligne sur sa page dédiée. Le premier épisode vous propose d&#8217;écouter Guillaume Laforge, le chef de projet du langage Groovy. SpringSource a annoncé le 11 novembre dernier le rachat de sa société, G2One.inc. A l&#8217;occasion de la journée &#171;&#160;Les Rencontres Spring&#160;&#187; nous avons été invité par SFEIR à rencontrer plusieurs personnes de SpringSource. J&#8217;ai enregistré une petite interview de guillaume avec Olivier Croisier, auteur du blog &#171;&#160;The Coder&#8217;s Breakfast&#171;&#160;.
Voici des pointeurs vers des sujets abordés dans le podcast :

article sur ...]]></description>
			<content:encoded><![CDATA[<div id="attachment_501" class="wp-caption alignnone" style="width: 310px"><a href="http://www.touilleur-express.fr/wp-content/nicolas_martignole_guillaume_laforge.jpg"><img src="http://www.touilleur-express.fr/wp-content/nicolas_martignole_guillaume_laforge-300x187.jpg" alt="N.Martignole et G.Laforge" title="nicolas_martignole_guillaume_laforge" width="300" height="187" class="size-medium wp-image-501" /></a><p class="wp-caption-text">N.Martignole et G.Laforge</p></div>
<p>C&#8217;est fait, le premier podcast du Touilleur Express est en ligne sur <a href="http://www.touilleur-express.fr/podcast_page/">sa page dédiée</a>. Le premier épisode vous propose d&#8217;écouter Guillaume Laforge, le chef de projet du langage Groovy. SpringSource a annoncé le 11 novembre dernier le rachat de sa société, G2One.inc. A l&#8217;occasion de la journée &laquo;&nbsp;Les Rencontres Spring&nbsp;&raquo; nous avons été invité par SFEIR à rencontrer plusieurs personnes de SpringSource. J&#8217;ai enregistré une petite interview de guillaume avec Olivier Croisier, auteur du blog &laquo;&nbsp;<a href="http://olivier.croisier.free.fr/blog/">The Coder&#8217;s Breakfast</a>&laquo;&nbsp;.</p>
<p>Voici des pointeurs vers des sujets abordés dans le podcast :</p>
<ul>
<li><a href="http://www.infoq.com/news/2008/11/springsource-g2one">article sur InfoQ</a></li>
<li><a href="http://glaforge.free.fr/weblog/">Le Blog de Guillaume</a></li>
<li><a href="http://www.exoplatform.com/portal/public/en/">The eXo Platform</a></li>
<li><a href="http://www.pilotsystems.net/actus/benjamin-mestrallet-exo-platform-prix-jeune-dirigeant-technologie">Benjamin Mestrallet, fondateur d&#8217;eXo, gagne le prix du jeune dirigeant de la Technologie</a></li>
</ul>
<p>A venir prochainement : interview avec Peter Cooper-Ellis. La qualité n&#8217;étant pas assez bonne, je vous proposerai une transcription de notre rencontre avec Peter prochainement.</p>
<p>En attendant voici une photo prise chez SFEIR, avec donc de gauche à droite : Peter Cooper-Ellis, moi-même et enfin <a href="http://olivier.croisier.free.fr/blog/">Olivier Croisier</a>.<br />
<div id="attachment_490" class="wp-caption alignnone" style="width: 310px"><a href="http://www.touilleur-express.fr/wp-content/img_5744.jpg"><img src="http://www.touilleur-express.fr/wp-content/img_5744-300x200.jpg" alt="Interview Peter Cooper-Ellis avec Nicolas Martignole et Olivier Croisier" title="Interview Peter Cooper-Ellis avec Nicolas Martignole et Olivier Croisier" width="300" height="200" class="size-medium wp-image-490" /></a><p class="wp-caption-text">Interview Peter Cooper-Ellis avec Nicolas Martignole et Olivier Croisier</p></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.touilleur-express.fr/2008/11/15/nouveau-un-podcast-le-touilleur-express/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

