<?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>Florian Boulay - In Fine - Le Blog</title>
	<atom:link href="https://blog.infine.com/author/florian-boulay/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.infine.com</link>
	<description>Le blog des technos de demain !</description>
	<lastBuildDate>Tue, 15 Jan 2013 11:09:43 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.7</generator>

<image>
	<url>https://blog.infine.com/wp-content/uploads/2021/03/cropped-vignette-32x32.png</url>
	<title>Florian Boulay - In Fine - Le Blog</title>
	<link>https://blog.infine.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Bilan de Devoxx France</title>
		<link>https://blog.infine.com/bilan-de-devoxx-france-1987?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=bilan-de-devoxx-france</link>
					<comments>https://blog.infine.com/bilan-de-devoxx-france-1987#comments</comments>
		
		<dc:creator><![CDATA[Florian Boulay]]></dc:creator>
		<pubDate>Fri, 11 May 2012 13:00:20 +0000</pubDate>
				<category><![CDATA[Conférence]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[devoxx]]></category>
		<guid isPermaLink="false">https://blog.infine.com/?p=1987</guid>

					<description><![CDATA[<p><span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">5</span> <span class="rt-label rt-postfix">min.</span></span> La première édition de Devoxx France s&#8217;est terminée depuis quelques jours, voici donc un bref retour d&#8217;expérience ainsi que les réponses au concours que nous avions organisé. L&#8217;organisation était au top. Les gilets rouges ont bien pris en main l’organisation globale, et malgré la jeunesse de l&#8217;évènement, aucun aléa n&#8217;est venu perturbé ces 3 journées. &#8230;</p>
<p>The post <a href="https://blog.infine.com/bilan-de-devoxx-france-1987">Bilan de Devoxx France</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">5</span> <span class="rt-label rt-postfix">min.</span></span><p><a href="https://blog.infine.com/wp-content/uploads/2012/03/logo_devoxx_fr_negate.jpg" class="fancyboxgroup" rel="gallery-1987" title="Logo Devoxx France"><img decoding="async" src="https://blog.infine.com/wp-content/uploads/2012/03/logo_devoxx_fr_negate-300x154.jpg" alt="Logo Devoxx France" title="Logo Devoxx France" width="300" height="154" class="alignleft size-medium wp-image-1984" srcset="https://blog.infine.com/wp-content/uploads/2012/03/logo_devoxx_fr_negate-300x154.jpg 300w, https://blog.infine.com/wp-content/uploads/2012/03/logo_devoxx_fr_negate.jpg 400w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>La première édition de Devoxx France s&#8217;est terminée depuis quelques jours, voici donc un bref retour d&#8217;expérience ainsi que les réponses au concours que nous avions organisé.</p>
<p>L&#8217;organisation était au top. Les gilets rouges ont bien pris en main l’organisation globale, et malgré la jeunesse de l&#8217;évènement, aucun aléa n&#8217;est venu perturbé ces 3 journées. Les sessions étaient très variées, et certaines demandaient un niveau technique assez élevé. D&#8217;autres au contraire permettaient de découvrir des sujets qui ne sont pas forcément connus des développeurs Java comme par exemple la session d&#8217;Alexandre Bertails sur la théorie des langages.</p>
<p><span id="more-1987"></span></p>
<p>D&#8217;un point de vue personnel, j&#8217;ai adoré cette première édition. On sentait que l&#8217;expérience de Stephan Janssen a permis à Devoxx France de paraître déjà rodé. J&#8217;ai pu assisté à de nombreuses sessions très intéressantes et enrichissantes comme celle de Pablo Lopez présentant Hadoop pour gérer les 7Go de logs produites chez son client. J&#8217;en ai malheureusement loupé d&#8217;autres. Vivement que les sessions soient sur Parleys. Devoxx a vraiment été une cure technique revigorante de part la diversité des sujets et la maîtrise technique des speakers.<br />
D&#8217;autre part, en jouant chez divers sponsors j&#8217;ai pu gagner un Samsung Galaxy Tab et un Kindle ! Un petit bonus qui a contribué à passer un excellent moment.</p>
<h2>Application In Fine Devoxx France</h2>
<p>Nous avions mis à disposition des utilisateurs Android <a href="https://play.google.com/store/apps/details?id=com.infine.android.devoxx">une application</a> permettant de gérer son planning pendant les 3 jours de Devoxx France. Les retours des utilisateurs ont été très bons et peu de bugs ont été recensés.<br />
Lors du deuxième jour, le planning a pu indiquer des salles qui ne correspondaient pas à la réalité. Ceci est en fait dû une désynchronisation entre l&#8217;application et l&#8217;API du site Devoxx. L&#8217;API REST ne renvoyait pas les bonnes salles ce qui a pu en gêner certains. Le troisième jour, tout est rentré dans l&#8217;ordre et l&#8217;API renvoyait les données exactes.</p>
<p>Comme nous l&#8217;avons annoncé avant Devoxx France, nous mettons en open source le code de cette application. Le code source est en licence Apache 2 et est disponible sur <a href="https://github.com/fboulay/devoxx-france-android-in-fine">mon GitHub</a>.</p>
<p>Cette application est censée se connecter à un serveur qui renvoie des données JSON qui ont un format spécifiques. Cette partie peut être adaptée facilement pour récupérer les données renvoyées par le serveur devoxx.</p>
<h2>Concours In Fine avec un Mac Book Air à la clé</h2>
<p>En tant que sponsor, nous organisions un concours de code. Le gagnant pouvait emporter un Mac Book Air. Le principe était simple : modifier 6 morceaux de code en sept minutes trente.<br />
La difficulté venait du fait que le code était édité dans un navigateur web et pas dans un IDE ! A chaque modification de code, une compilation automatique était envoyée à un serveur permettant de valider la réponse du candidat.</p>
<p>Les réponses aux questions ne nécessitaient pas de connaître les API du JDK par coeur, seules le nom des classes et leur constructeur étaient utiles. Les questions et réponses sont données un peu plus loin dans ce post.</p>
<p>Nicolas De Loof <a href="http://blog.loof.fr/2012/04/yeahhhhh.html">a emporté haut la main</a> le concours en étant le seul à donner les 6 bonnes réponses dans le temps imparti. Les autres participants n&#8217;ont pas démérité, mais le fait de coder dans un navigateur a dû en déconcerter plus d&#8217;un.</p>
<figure id="attachment_1989" aria-describedby="caption-attachment-1989" style="width: 223px" class="wp-caption aligncenter"><a href="https://blog.infine.com/wp-content/uploads/2012/04/boss_loof_mac_book_air.jpg" class="fancyboxgroup" rel="gallery-1987" title="Antoine Ramponi et Nicolas de Loof sur le stand In Fine"><img fetchpriority="high" decoding="async" src="https://blog.infine.com/wp-content/uploads/2012/04/boss_loof_mac_book_air-223x300.jpg" alt="Antoine Ramponi et Nicolas de Loof sur le stand In Fine" title="Antoine Ramponi et Nicolas de Loof sur le stand In Fine" width="223" height="300" class="size-medium wp-image-1989" srcset="https://blog.infine.com/wp-content/uploads/2012/04/boss_loof_mac_book_air-223x300.jpg 223w, https://blog.infine.com/wp-content/uploads/2012/04/boss_loof_mac_book_air.jpg 537w" sizes="(max-width: 223px) 100vw, 223px" /></a><figcaption id="caption-attachment-1989" class="wp-caption-text"><em>Nicolas de Loof vient de gagner le Mac Book Air. Il fete ça en présence du boss Antoine Ramponi</em></figcaption></figure>
<h3>Questions du concours</h3>
<p>Chaque question comprend un énoncé, une partie de code éditable par l&#8217;utilisateur ainsi que du code non éditable. Les imports se font automatiquement.</p>
<h4>Question 1</h4>
<p>Comment faire en sorte que myMap puisse garder l&#8217;ordre d&#8217;insertion</p>
<pre class="brush: java; title: ; notranslate">
// Début de la partie éditable

Map&lt;String, Integer&gt; myMap = new HashMap&lt;String, Integer&gt;();

// Fin de la partie éditable
myMap.put(&quot;val2&quot;, 2);
myMap.put(&quot;val1&quot;, 1);
myMap.put(&quot;val3&quot;, 4);

Iterator&lt;Integer&gt; i = myMap.values().iterator();
assert(result = i.next() == 2 &amp;&amp; i.next() == 1 &amp;&amp; i.next() == 4);
</pre>
<h4>Réponse 1</h4>
<p>Il faut une certaine connaissance des collections Java. TreeMap n&#8217;est pas utilisable ici car il réordonne les entréés à chaque insertion.</p>
<pre class="brush: java; title: ; notranslate">
Map&lt;String, Integer&gt; myMap = new LinkedHashMap&lt;String, Integer&gt;();
</pre>
<h4>Question 2</h4>
<p>Le test est valide lorsque myVar vaut 66666</p>
<pre class="brush: java; title: ; notranslate">
// Début de la partie éditable

long myVar = 5432l;

// Fin de la partie éditable
myVar += 12345;
assert(myVar == 66666);
</pre>
<h4>Réponse 2</h4>
<p>Il fallait mettre un 1 au lieu du l minuscule. Cette question est une référence à Josh Bloch.</p>
<pre class="brush: java; title: ; notranslate">
long myVar = 54321;
</pre>
<h4>Question 3</h4>
<p>Ecrivez une méthode qui calcule la factorielle d&#8217;un nombre n . Si n est négatif alors on retourne Double.NaN</p>
<pre class="brush: java; title: ; notranslate">
// Début de la partie éditable
double fact(int n) {
    return 0;
}
// Fin de la partie éditable
</pre>
<h4>Réponse 3</h4>
<p>Faire une fonction récursive était la manière la plus évidente et la plus naturelle.</p>
<pre class="brush: java; title: ; notranslate">
double fact(int n) {
    if (n == 0)
        return 1;
    else if (n == 1)
        return 1;
    else if (n &lt; 0)
        return Double.NaN;
    return n * fact(n-1);
}
</pre>
<h4>Question 4</h4>
<p>Ecrivez la méthode getDayOfWeek qui prend en entrée le nombre de jour depuis le 1 Janvier 1970 ( ce jour était un jeudi ) et qui retourne le jour correspondant.</p>
<pre class="brush: java; title: ; notranslate">
public final static int SUNDAY = 1;
public final static int MONDAY = 2;
public final static int TUESDAY = 3;
public final static int WEDNESDAY = 4;
public final static int THURSDAY = 5;
public final static int FRIDAY = 6;
public final static int SATURDAY = 7;

// Début de la partie éditable
int getDayOfWeek(int day) {
    return 0;
}
// Fin de la partie éditable
</pre>
<h4>Réponse 4</h4>
<p>Cette question probablement était probablement la plus difficile. Ceux qui ont essayé de trouver une formule qui marche sur une ligne avec un modulo ont tous échoué. D&#8217;autres ont essayé d&#8217;utiliser la classe Calendar, mais sans auto-complétion et sans connaissance de l&#8217;API ils ont échoué également. La solution la plus simple est celle ci-dessous.</p>
<pre class="brush: java; title: ; notranslate">
int getDayOfWeek(int day) {
    int moduloDay = day % 7;
    switch(moduloDay){
        case 0 : return THURSDAY;
        case 1 : return FRIDAY;
        case 2 : return SATURDAY;
        case 3 : return SUNDAY;
        case 4 : return MONDAY;
        case 5 : return TUESDAY;
        default : return WEDNESDAY;
    }
}
</pre>
<h4>Question 5</h4>
<p> Modifiez le code pour que le resultat de la soustraction soit égal à 0.9</p>
<pre class="brush: java; title: ; notranslate">
void substract() {
// Début du code éditable

    BigDecimal a = new BigDecimal(2.00);
    BigDecimal b = new BigDecimal(1.10);
	
// Fin du code éditable
    assert(a.subtract(b).doubleValue() == 0.9);
}
</pre>
<h4>Réponse 5</h4>
<p>Un énoncé et une réponse simple encore une fois. Il fallait connaître les spécifités de ce constructeur. En initialisant un BigDecimal avec un double, la valeur initialisée est une valeur approchante au paramètre. En utilisant un paramètre de type String, alors c&#8217;est la valeur exacte qui est utilisée.</p>
<pre class="brush: java; title: ; notranslate">
    BigDecimal a = new BigDecimal(&quot;2.00&quot;);
    BigDecimal b = new BigDecimal(&quot;1.10&quot;);
</pre>
<h4>Question 6</h4>
<p>Comment accède-t&#8217;on dans la méthode getSuperVal à l&#8217;attribut val de la classe B ?</p>
<pre class="brush: java; title: ; notranslate">
class B {

    int val = 2;
    A a = new A();

    class A {
        final public int val = 3;

        int getSuperVal() {
            // Début du code éditable
            return ;
            // Fin du code éditable

        }
    }
}
</pre>
<h4>Réponse 6</h4>
<p>Syntaxe peu utilisée, mais encore une fois cette réponse était simple à donner dans un navigateur sans auto-complétion.</p>
<pre class="brush: java; title: ; notranslate">
return B.this.val;
</pre>
<h4>Question 7</h4>
<p>NB : Cette question a remplacé 6 la question le dernier jour de Devoxx France.<br />
Comment faire en sorte que myMap ait une taille de 3 ? La Map ne doit contenir que des clés &#8220;test&#8221;.</p>
<pre class="brush: java; title: ; notranslate">
// Début du code éditable
Map&lt;String, Integer&gt; myMap = new HashMap&lt;String, Integer&gt;();
// Fin du code éditable

myMap.put(new String(&quot;test&quot;), 1);
myMap.put(new String(&quot;test&quot;), 2);
myMap.put(&quot;test&quot;, 3);

int size = myMap.size();
assert(size == 3);
</pre>
<h4>Réponse 7</h4>
<p>Encore une fois il fallait un peu connaître les classes qui composent l&#8217;API Collection.</p>
<pre class="brush: java; title: ; notranslate">
Map&lt;String, Integer&gt; myMap = new IdentityHashMap&lt;String, Integer&gt;();
</pre>
<p>Merci à tous ceux qui sont venus nous voir sur le stand, on a passé de bon moments. A l&#8217;année prochaine !</p><p>The post <a href="https://blog.infine.com/bilan-de-devoxx-france-1987">Bilan de Devoxx France</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.infine.com/bilan-de-devoxx-france-1987/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>L&#8217;application Devoxx France d&#8217;In Fine est disponible sur le Google Play Store</title>
		<link>https://blog.infine.com/lapplication-devoxx-france-din-fine-est-disponible-sur-le-google-play-store-1954?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lapplication-devoxx-france-din-fine-est-disponible-sur-le-google-play-store</link>
					<comments>https://blog.infine.com/lapplication-devoxx-france-din-fine-est-disponible-sur-le-google-play-store-1954#comments</comments>
		
		<dc:creator><![CDATA[Florian Boulay]]></dc:creator>
		<pubDate>Fri, 30 Mar 2012 11:21:45 +0000</pubDate>
				<category><![CDATA[Conférence]]></category>
		<category><![CDATA[Mobile (Android/iOS)]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[devoxx]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[play framework]]></category>
		<guid isPermaLink="false">https://blog.infine.com/?p=1954</guid>

					<description><![CDATA[<p><span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">2</span> <span class="rt-label rt-postfix">min.</span></span> In Fine, en tant que partenaire de l&#8217;évènement majeur qu&#8217;est Devoxx France, a le plaisir de mettre à disposition une application pour Devoxx France sur Android. Cette première version permet : De mettre en favoris vos sessions préférées De consulter le planning des sessions, et le détail des speakers De voir ce qui se passe &#8230;</p>
<p>The post <a href="https://blog.infine.com/lapplication-devoxx-france-din-fine-est-disponible-sur-le-google-play-store-1954">L’application Devoxx France d’In Fine est disponible sur le Google Play Store</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">2</span> <span class="rt-label rt-postfix">min.</span></span><p><a href="https://blog.infine.com/wp-content/uploads/2012/03/logo_devoxx_fr_negate.jpg" class="fancyboxgroup" rel="gallery-1954" title="Logo Devoxx France"><img decoding="async" src="https://blog.infine.com/wp-content/uploads/2012/03/logo_devoxx_fr_negate-300x154.jpg" alt="Logo Devoxx France" title="Logo Devoxx France" width="300" height="154" class="alignright size-medium wp-image-1984" srcset="https://blog.infine.com/wp-content/uploads/2012/03/logo_devoxx_fr_negate-300x154.jpg 300w, https://blog.infine.com/wp-content/uploads/2012/03/logo_devoxx_fr_negate.jpg 400w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>In Fine, en tant que partenaire de l&#8217;évènement majeur qu&#8217;est Devoxx France, a le plaisir de mettre à disposition une application pour Devoxx France sur Android. Cette première version permet :</p>
<ul>
<li>De mettre en favoris vos sessions préférées</li>
<li>De consulter le planning des sessions, et le détail des speakers</li>
<li>De voir ce qui se passe sur Twitter avec le tag <em>devoxxfr</em></li>
<li>D&#8217;avoir accès au plan des 2 étages de l&#8217;hôtel où se déroulera la conférence</li>
<li>Et d&#8217;autres fonctionnalités&#8230;</li>
</ul>
<p><span id="more-1954"></span></p>
<p>Cette application fonctionne parfaitement sur téléphone , mais n&#8217;est pas encore totalement adaptée pour les tablettes. Dans les semaines qui viennent, nous allons continuer à mettre à jour l&#8217;application pour qu&#8217;elle soit la plus simple à utiliser possible. Voici une prévision des futures évolutions  :</p>
<ul>
<li>Complète adaptation de l&#8217;ergonomie de l&#8217;application aux tablettes</li>
<li>Ajout de la recherche sur les speakers. Actuellement elle ne fonctionne que sur les sessions</li>
<li>Quand on clique sur une salle, afficher la carte de l&#8217;étage correspondant</li>
<li>Pouvoir mettre en favori des speakers</li>
<li>Et bien d&#8217;autres choses qui dépendront des retours que nous aurons</li>
</ul>
<p>Nous sommes très fiers de mettre à disposition cette application. Elle sera mise en open source au moment de la conférence Devoxx France, certainement en licence Apache 2.<br />
Si vous rencontrez des problèmes ou avez des suggestions, écrivez un commentaire ici, ou envoyer un mail au compte indiqué sur la fiche du Google Play Store.</p>
<p>Dans la suite de l&#8217;article, nous allons approfondir l&#8217;aspect technique de l&#8217;application. Si au contraire vous souhaitez directement aller télécharger l&#8217;application, alors il faut aller ici : <a href="https://play.google.com/store/apps/details?id=com.infine.android.devoxx">Play Store</a></p>
<h2>Architecture technique</h2>
<figure id="attachment_1964" aria-describedby="caption-attachment-1964" style="width: 300px" class="wp-caption aligncenter"><a href="https://blog.infine.com/wp-content/uploads/2012/03/archi_appli_android_devoxx1.png" class="fancyboxgroup" rel="gallery-1954"><img loading="lazy" decoding="async" class="size-medium wp-image-1964" src="https://blog.infine.com/wp-content/uploads/2012/03/archi_appli_android_devoxx1-300x164.png" alt="Architecture applicative de l'application Devoxx France In Fine" width="300" height="164" srcset="https://blog.infine.com/wp-content/uploads/2012/03/archi_appli_android_devoxx1-300x164.png 300w, https://blog.infine.com/wp-content/uploads/2012/03/archi_appli_android_devoxx1.png 660w" sizes="(max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-1964" class="wp-caption-text"><em>Architecture applicative de l&#039;application Devoxx France In Fine</em></figcaption></figure>
<p>Comme le montre le schéma ci-dessus, nous n&#8217;avons pas directement connecté l&#8217;application Android avec les API RESTful fournies par le site Devoxx. En effet les temps de réponse sont très variables, certains service ont déjà mis plus de 5 minutes à répondre. D&#8217;autre part, certains service renvoient des données en double ou incomplètes.<br />
Le serveur intérmédiaire permet donc de mieux maîtriser les données. Grâce à Play et à Mongo DB, les temps de réponse sont excellents et la charge que peut encaisser le serveur est bien au dessus de ce que nous atteindrons. Un test JMeter a mesuré que le serveur pouvait encaisser 300 requêtes par secondes. La plupart des requêtes répondent en moins de 0.1 seconde. Nous estimons que le serveur aurait à supporter, au maximum de son activité, 25 requêtes par minute</p><p>The post <a href="https://blog.infine.com/lapplication-devoxx-france-din-fine-est-disponible-sur-le-google-play-store-1954">L’application Devoxx France d’In Fine est disponible sur le Google Play Store</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.infine.com/lapplication-devoxx-france-din-fine-est-disponible-sur-le-google-play-store-1954/feed</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>J&#8217;ai testé le livre : Apache Maven version 2 et 3 par Nicolas De Loof et Arnaud Héritier</title>
		<link>https://blog.infine.com/jai-teste-le-livre-apache-maven-version-2-et-3-par-nicolas-de-loof-et-arnaud-heritier-1248?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=jai-teste-le-livre-apache-maven-version-2-et-3-par-nicolas-de-loof-et-arnaud-heritier</link>
					<comments>https://blog.infine.com/jai-teste-le-livre-apache-maven-version-2-et-3-par-nicolas-de-loof-et-arnaud-heritier-1248#comments</comments>
		
		<dc:creator><![CDATA[Florian Boulay]]></dc:creator>
		<pubDate>Fri, 20 Jan 2012 12:30:34 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[livre]]></category>
		<category><![CDATA[maven]]></category>
		<guid isPermaLink="false">https://blog.infine.com/?p=1248</guid>

					<description><![CDATA[<p><span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">4</span> <span class="rt-label rt-postfix">min.</span></span> La seconde édition de ce livre est sortie il y a déjà quelques mois. Cette nouvelle édition apporte le support de Maven 3 ainsi que des corrections. Je n&#8217;avais entendu que du bien de la première version, allons voir ce que donne cette seconde édition ! Depuis quelques années j&#8217;utilise 2 ressources principales afin de &#8230;</p>
<p>The post <a href="https://blog.infine.com/jai-teste-le-livre-apache-maven-version-2-et-3-par-nicolas-de-loof-et-arnaud-heritier-1248">J’ai testé le livre : Apache Maven version 2 et 3 par Nicolas De Loof et Arnaud Héritier</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">4</span> <span class="rt-label rt-postfix">min.</span></span><p><a href="https://blog.infine.com/wp-content/uploads/2011/09/apache_maven.jpg" class="fancyboxgroup" rel="gallery-1248"><img loading="lazy" decoding="async" class="alignleft size-medium wp-image-1249" src="https://blog.infine.com/wp-content/uploads/2011/09/apache_maven-300x300.jpg" alt="apache maven cover" width="200" height="200" srcset="https://blog.infine.com/wp-content/uploads/2011/09/apache_maven-300x300.jpg 300w, https://blog.infine.com/wp-content/uploads/2011/09/apache_maven-150x150.jpg 150w, https://blog.infine.com/wp-content/uploads/2011/09/apache_maven.jpg 500w" sizes="(max-width: 200px) 100vw, 200px" /></a></p>
<p>La seconde édition de ce livre est sortie il y a déjà quelques mois. Cette nouvelle édition apporte le support de Maven 3 ainsi que des corrections. Je n&#8217;avais entendu que du bien de la première version, allons voir ce que donne cette seconde édition !<br />
Depuis quelques années j&#8217;utilise 2 ressources principales afin de m&#8217;aider dans mon utilisation quotidienne de Maven : la documentation officielle et l&#8217;ebook <em>Maven The Definitive Guide</em> dont j&#8217;ai toujours une copie dans ma dropbox. Cet ebook a beaucoup de lacunes et n&#8217;approfondie par certaines notions Maven qui pourtant le mériteraient, mais je le consulte tout de même régulièrement.</p>
</p>
<p>Je me considère comme un bon utilisateur de Maven, mais je suis loin d&#8217;être un expert. Cela fait déjà plusieurs années que je le pratique, et je l&#8217;utilise quotidiennement dans le cadre de mes missions chez les clients. En lisant le livre <em>Apache maven</em> l&#8217;objectif était double :</p>
<ul>
<li>Apprendre de nouvelles choses ou appronfondir certaines notions que j&#8217;utilise peu</li>
<li>Trouver un complément à <em>Maven The Definitive Guide</em> qui date désormais quelque peu</li>
</ul>
<p><span id="more-1248"></span></p>
<h2>Ce livre propose un scénario&#8230;</h2>
<p>Ceci peut paraître étrange pour un livre d&#8217;informatique, mais il y a effectivement un scénario. Arnaud et Nicolas sont 2 compères qui retrouvent un vieille application sur une disquette gérant une liste de courses. Cette application se construit grâce à des scripts spécifiques à chaque OS : un fichier <code>.bat</code> et un fichier <code>.sh</code>.</p>
<p>Ils décident d&#8217;améliorer l&#8217;application en lui ajoutant de nouvelles fonctionnalités. D&#8217;une simple application, elle deviendra un vrai gros site web. Qui dit grosse application, dit industrialisation dans le process de livraison, de tests etc&#8230; Et c&#8217;est là que Maven intervient.</p>
<figure id="attachment_1884" aria-describedby="caption-attachment-1884" style="width: 300px" class="wp-caption aligncenter"><a href="https://blog.infine.com/wp-content/uploads/2012/01/csi_maven.png" class="fancyboxgroup" rel="gallery-1248" title="CSI Maven"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2012/01/csi_maven-300x258.png" alt="CSI Maven" title="CSI Maven" width="300" height="258" class="size-medium wp-image-1884" srcset="https://blog.infine.com/wp-content/uploads/2012/01/csi_maven-300x258.png 300w, https://blog.infine.com/wp-content/uploads/2012/01/csi_maven.png 383w" sizes="(max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-1884" class="wp-caption-text"><em>Et en plus, cet ouvrage est drôle</em></figcaption></figure>
<p>Déboussolés par les divers problèmes qui se posent à eux, Nicolas et Arnaud seront aidés dans leur quête à créer l&#8217;application de gestion de course ultime, par d&#8217;autres personnes ayant les connaissances nécessaires afin de surmonter ces épreuves. Citons parmi ces seconds couteaux Olivier Lamy, Vincent Massol, Antonio Goncalves, Guillaume Laforge et bien d&#8217;autres.<br />
Désolé de vous avoir spoilé une bonne part du scénario, mais je vous assure qu&#8217;il y a encore beaucoup de rebondissements dont je ne vous ai pas parlé.</p>
<p>Avoir un scénario est déroutant pour un livre d&#8217;informatique. La forme habituelle didactique est ici changé en &#8220;roman&#8221; avec ses rebondissements et une belle fin. Par conséquent ce livre se lit d&#8217;une traite malgré le sujet qui peut sembler difficile au premier abord. Le livre prend le parti de montrer des situations concrètes issues des expériences de Nicolas et Maven, et nous propose une solution généralement grâce à une fonctionnalité de Maven ou à l&#8217;un de ses plugins.</p>
<h2>&#8230; Et du contenu</h2>
<p>En effet Maven est généralement considéré comme compliqué. Cet ouvrage veut prouver le contraire. Maven est prévu pour répondre à plusieurs problématiques courantes des projets. Ce qui le rend difficile (son cycle de vie, ses plugins&#8230;) est abordé progressivement dans le livre au travers de problèmes que n&#8217;importe quel utilisateur de Maven pourrait rencontrer sur un projet.</p>
<p>Le livre n&#8217;aborde pas que les bases de Maven et par exemple des plugins peu courants sont présentés tels que le <em>maven-osgi-compiler-plugin</em> ou le <em>flexmojos-maven-plugin</em>. D&#8217;autres points liés à Maven sont abordés tels qu&#8217;une comparaison des IDE ou des différents gestionnaires de dépôt.</p>
<p>Cette seconde édition apporte évidemment quelques nouveautés. La plus importante est lié à Maven 3. Dans cette édition, la plupart des chapitres contiennent un encart détaillant les spécificités de Maven 3. Ces encarts ne sont pas très nombreux, Maven 3 étant en grande partie compatible avec Maven 2. Les autres nouveautés concernent les corrections de la première édition, ainsi que l&#8217;ajout d&#8217;un chapitre. Pour être clair, si vous possédez la première édition, les nouveautés ne justifient pas de se procurer la nouvelle.</p>
<h2>Le livre parfait ?</h2>
<p>Ce livre comporte de très nombreuses qualités. Le sujet est bien maitrisé et l&#8217;apprentissage est progressif sans pour autant être trop lent. L&#8217;approche est très pragmatique et les fonctionnalités de Maven sont présentées par une approche très pratique, plutôt que par une approche théorique que de nombreux ouvrages d&#8217;informatique indigestes privilégient. De plus les livres en français et de qualité sont rares, celui-ci en fait partie, et je le recommande vivement. Apprendre Maven ou se perfectionner n&#8217;aura jamais été plus facile.</p>
<figure id="attachment_1887" aria-describedby="caption-attachment-1887" style="width: 300px" class="wp-caption aligncenter"><a href="https://blog.infine.com/wp-content/uploads/2012/01/Extreme_makeover_maven.png" class="fancyboxgroup" rel="gallery-1248" title="Extreme Makeover Maven"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2012/01/Extreme_makeover_maven-300x128.png" alt="Extreme Makeover Maven" title="Extreme Makeover Maven" width="300" height="128" class="size-medium wp-image-1887" srcset="https://blog.infine.com/wp-content/uploads/2012/01/Extreme_makeover_maven-300x128.png 300w, https://blog.infine.com/wp-content/uploads/2012/01/Extreme_makeover_maven.png 577w" sizes="(max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-1887" class="wp-caption-text"><em>Quand je vous disais qu'il était drôle</em></figcaption></figure>
<p>Me concernant j&#8217;ai trouvé le parfait complément à <em>Maven The Definitive Guide</em>. Il ne me manque plus qu&#8217;une version électronique afin de l&#8217;avoir dans ma Dropbox, et je pourrais presque me passer de <em>Maven The Definitive Guide</em>.</p>
<p>Chaque lecteur, en fonction de sa propre expérience, trouvera des choses à redire. Pour ma part, j&#8217;aurais souhaité que certains points soient approfondis comme les extensions ou l&#8217;écriture de plugins. Cette seconde édition apporte certainement son lot de correction, mais inévitablement les nouvelles parties ajoutées comportent leur lot d&#8217;erreurs. Heureusement elles restent mineures et ne nuisent pas à la compréhension du passage concernée. La perle étant le listing du code de la page 185 (à lire si vous avez le bouquin sous la main <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ).</p>
<p>Assez de bavardages, cet excellent ouvrage est à mettre entre toutes vos mains, car vous utilisez tous Maven. Voici la <a href="http://www.pearson.fr/livre/?GCOI=27440100487310" target="_blank">page du livre chez l&#8217;éditeur</a> contenant la table des matières ainsi que des extraits.</p><p>The post <a href="https://blog.infine.com/jai-teste-le-livre-apache-maven-version-2-et-3-par-nicolas-de-loof-et-arnaud-heritier-1248">J’ai testé le livre : Apache Maven version 2 et 3 par Nicolas De Loof et Arnaud Héritier</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.infine.com/jai-teste-le-livre-apache-maven-version-2-et-3-par-nicolas-de-loof-et-arnaud-heritier-1248/feed</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Devoxx 2011 &#8211; Ceylon</title>
		<link>https://blog.infine.com/devoxx-2011-ceylon-1414?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=devoxx-2011-ceylon</link>
					<comments>https://blog.infine.com/devoxx-2011-ceylon-1414#respond</comments>
		
		<dc:creator><![CDATA[Florian Boulay]]></dc:creator>
		<pubDate>Wed, 30 Nov 2011 15:00:49 +0000</pubDate>
				<category><![CDATA[Conférence]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[demo]]></category>
		<category><![CDATA[devoxx]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[language]]></category>
		<guid isPermaLink="false">https://blog.infine.com/?p=1414</guid>

					<description><![CDATA[<p><span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">5</span> <span class="rt-label rt-postfix">min.</span></span> Ceylon est un nouveau langage s&#8217;exécutant sur la JVM. Il rejoint une liste désormais assez longue qui comprend notamment : Groovy Jython Jruby Scala Kotlin Fantom Gosu &#8230; Gavin King a créé Ceylon parce qu&#8217;il était frustré par les limitations de Java. Cette session a été animée par deux français, Emmanuel Bernard et Stéphane Epardaud &#8230;</p>
<p>The post <a href="https://blog.infine.com/devoxx-2011-ceylon-1414">Devoxx 2011 – Ceylon</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">5</span> <span class="rt-label rt-postfix">min.</span></span><p><a href="https://blog.infine.com/wp-content/uploads/2011/11/ceylon-logo.png" class="fancyboxgroup" rel="gallery-1414" title="ceylon logo"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2011/11/ceylon-logo.png" alt="ceylon logo" title="ceylon logo" width="325" height="100" class="alignright size-full wp-image-1417" srcset="https://blog.infine.com/wp-content/uploads/2011/11/ceylon-logo.png 325w, https://blog.infine.com/wp-content/uploads/2011/11/ceylon-logo-300x92.png 300w" sizes="(max-width: 325px) 100vw, 325px" /></a></p>
<p>Ceylon est un nouveau langage s&#8217;exécutant sur la JVM. Il rejoint une liste désormais assez longue qui comprend notamment :</p>
<ul>
<li>Groovy</li>
<li>Jython</li>
<li>Jruby</li>
<li>Scala</li>
<li>Kotlin</li>
<li>Fantom</li>
<li>Gosu</li>
<li>&#8230;</li>
</ul>
<p>Gavin King a créé Ceylon parce qu&#8217;il était frustré par les limitations de Java. Cette session a été animée par deux français, Emmanuel Bernard et Stéphane Epardaud qui sont commiters sur le projet. Ils ont débuté la session en définissant les objectifs de Ceylon, avant de continuer sur ses fonctionnalités à l&#8217;aide de code. Je ne vais pas reproduire le code qu&#8217;ils ont utilisé pendant la présentation dans cet article, je vais essayer d&#8217;être plus concis.</p>
<p><span id="more-1414"></span></p>
<p>Emmanuel commence par nous indiquer les objectifs de Ceylon :</p>
<ul>
<li>Permettre d&#8217;écrire du code plus simple que l&#8217;équivalent en java</li>
<li>Éviter au développeur de tomber dans les principaux pièges de java</li>
</ul>
<p>Ceylon est pensé pour être lu facilement par des développeurs venant du monde Java. Emmanuel insiste bien sur ce point : Ceylon doit être simple à utiliser mais également simple à lire. Le code ne doit pas soulever d’ambiguïté. </p>
<h1>Principes de base</h1>
<h2>Classe simple</h2>
<pre class="brush: java; title: ; notranslate">
shared class User(String username, Natural age) {
    shared String username = username;
    shared Natural age = age;

    shared void printUser() {
        print(&quot;User name : &quot; username &quot; with age &quot; age &quot; is printed&quot;);
    }
}
</pre>
<p>Cette classe est courte, mais il y a déjà plusieurs choses à dire dessus :</p>
<ul>
<li>Le mot-clé <code>class</code> indique évidemment qu&#8217;il s&#8217;agit d&#8217;une déclaration de classe</li>
<li>Le mot-clé <code>shared</code> est l&#8217;équivalent du <code>public</code> de Java. Si le mot-clé <code>shared</code> est omis, alors la visibilité est privée (visibilité par défaut en Ceylon)</li>
<li>A la suite de la déclaration de la classe <code>User</code> se trouvent des paramètres <code>(String username, Natural age)</code>, il s&#8217;agit de la déclaration du constructeur. Je dis bien <strong>du</strong> car une Ceylon interdit la surcharge de méthode et donc un seul constructeur est autorisé</li>
<li><code>Natural</code> est l&#8217;objet représentant un nombre entier naturel. En Ceylon, il n&#8217;y a pas de type primitif</li>
<li>Les attributs de la classe sont obligatoirement initialisés, il n&#8217;y a pas de valeur par défaut, même <code>null</code> n&#8217;est pas implicite. Ici, les valeurs sont celles fournies au constructeur</li>
<li>La déclaration de la méthode <code>printUser</code> se fait comme en Java, le mot-clé <code>shared</code> en plus si on souhaite l&#8217;exposer</li>
<li>La concaténation de chaîne de caractère peut se faire sans le caractère <strong>+</strong>. La concaténation avec le caractère <strong>+</strong> fonctionne également</li>
</ul>
<h2>Méthodes</h2>
<pre class="brush: java; highlight: [2,6,12,22]; title: ; notranslate">
shared class Parent() {
    shared default void printMe() {
         print(&quot;I'm in parent class&quot;);
    }

    shared void printMessage(String messageToPrint = &quot;default argument value&quot;) {
         print(&quot;I'm in parent class and I print &quot; + messageToPrint);
    }
}

shared class Child() extends Parent() {
    shared actual void printMe() {
         print(&quot;I'm in child class&quot;);
    }
}

void testCeylon() {
    // appel de méthodes
    Parent p = Parent();
    p.printMe();
    p.printMessage(); // default value of parameter used - will work on milestone 2
    p.printMessage(&quot;message given as argument&quot;);  // classic call
    p.printMessage {  // name argument used
        messageToPrint = &quot;message with named arguments&quot;;
    };
}
</pre>
<p>Encore une fois, malgré la petite taille de code et sa lisibilité, plusieurs fonctionnalités sont à décrire :</p>
<ul>
<li>Comme dit plus haut, les méthodes ne sont pas surchargeables. Pour palier à cette obligation les paramètres peuvent avoir des valeurs par défaut (ligne 6), des <em>varargs</em> peuvent être utilisés (comme en java), ou des <em>union types</em> peuvent être utilisés (voir la doc pour plus de détails)</li>
<li>Les paramètres des méthodes sont nommés &#8211; ligne 22</li>
<li>Les méthodes peuvent être redéfinies dans les classes filles mais il faut l&#8217;autoriser explicitement grâce au mot clé <code>default</code> dans la classe parent (équivalent du <code>virtual</code> du C++ utilisé dans la classe parent) &#8211; ligne 2</li>
<li>Lors de la rédéfinition de la méthode dans une classe fille, il faut obligatoirement utiliser le mot-clé <code>actual</code> (équivalent à l&#8217;annotation <code>@Override</code> de Java) &#8211; ligne 12</li>
</ul>
<h2>null et immuabilité</h2>
<p>Par défaut toutes les variables sont immuables en Ceylon. Afin de les rendre modifiables il faut explicitement adapter la syntaxe de déclaration d&#8217;une variable en ajoutant le mot-clé <code>variable</code> et effectuer l&#8217;affectation avec l&#8217;opérateur <strong>:=</strong> : </p>
<pre class="brush: java; title: ; notranslate">
shared class ImmutableExample(Natural year) {
    // immutable
    Natural year = year;
    // Mutable
    variable Natural writableYear := year;
}
</pre>
<p>Afin d&#8217;éviter les trop nombreux <code>NullPointerException</code> de Java, une variable qui pourrait contenir la valeur  <code>null</code> doit être déclaré à l&#8217;aide d&#8217;un <code>?</code>. Ceci a des conséquences sur la manière d&#8217;utiliser ces variables comme le montre le code ci-dessous :</p>
<pre class="brush: java; title: ; notranslate">
// myBestVariable can be null
String? myBestVariable = functionThatCanReturnNull();
// to work on myBestVariable, a null check must be done
if (exists myBestVariable) {
    functionThatNeedAString(myBestVariable);
}
else {
    functionThatNeedAString(&quot;default value&quot;);
}
</pre>
<h2>Autres fonctionnalités</h2>
<p>Emmanuel et Stéphane ont présenté d&#8217;autres fonctionnalités importantes de Ceylon telles que les <em>union type</em> et les <em>intersection type</em>. Pour plus de détails, reportez vous à la <a href="http://ceylon-lang.org/documentation/tour/types/">documentation officielle.</a><br />
Malgré les arguments nommés, il est possible d&#8217;utiliser les generics. Les annotations sont également disponibles.<br />
La compatibilité entre Java et Ceylon est également disponible. Ceylon peut utiliser du code écrit en Java, et Java peut appeler du code Ceylon.</p>
<h1>En pratique</h1>
<p>Emmanuel et Stéphane, après avoir transmis les bases à l&#8217;auditoire, effectuent une démo en live de Ceylon dans Eclipse. Un plugin Eclipse a été développé et est déjà fontionnel. L&#8217;autocomplétion fonctionne bien, la coloration syntaxique et le refactoring également. Plus d&#8217;infos sur le <a href="https://github.com/ceylon/ceylon-ide-eclipse">repo git</a> associé.</p>
<p>Aucune version de Ceylon n&#8217;a encore été releasée. La prochaine version à sortir sera la milestone 1 qui ne comprendra pas encore toutes les fonctionnalités de la spécification. Trois milestones sont prévues avant que la version 1.0 ne sorte.</p>
<h2>Test de Ceylon</h2>
<p>Il est évidemment possible aujourd&#8217;hui de tester dès aujourd&#8217;hui Ceylon et pour cela, j&#8217;ai réalisé un petit screencast afin de vous montrer qu&#8217;avoir le compilateur Ceylon utilisable sur son poste est vraiment simple et rapide.</p>
<p>Les prérequis sont d&#8217;avoir sur sa machine Java 6, Ant et Git. Dans le screencast, je clone les trois repositories Git nécessaires à la création du compilateur. Chacun nécessite Ant afin d&#8217;être compilé. Une fois le compilateur généré, je le teste en compilant l&#8217;exemple de code que j&#8217;ai donné ci-dessus dans le paragraphe <em>Méthodes</em>, et je l&#8217;exécute.</p>
<p><iframe loading="lazy" src="http://player.vimeo.com/video/32661574?title=0&amp;portrait=0&amp;color=ff9933" width="660" height="371" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></p>
<p>Pour ceux qui veulent tester, je vous retranscrits les commandes utilisées dans le screencast afin de faciliter le copier coller</p>

<table id="wp-table-reloaded-id-1-no-1" class="wp-table-reloaded wp-table-reloaded-id-1">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Repository Git</th><th class="column-2">Commande pour compiler le repository</th>
	</tr>
</thead>
<tbody class="row-hover">
	<tr class="row-2 even">
		<td class="column-1">git://github.com/ceylon/ceylon.language.git</td><td class="column-2">ant clean publish</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">git://github.com/ceylon/ceylon-spec.git</td><td class="column-2">ant clean tree publish</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">git://github.com/ceylon/ceylon-compiler.git</td><td class="column-2">ant clean build</td>
	</tr>
</tbody>
</table>

<p>Une fois le compilateur généré, je l&#8217;ai testé. Mon fichier source se nomme <em>florian_boulay.ceylon</em> et se trouve dans le répertoire <em>samples</em>. Le répertoire <em>build</em> contient les fichiers Ceylon compilés. <em>testCeylon</em> correspond au nom de la fonction appelée pour lancer le programme.</p>

<table id="wp-table-reloaded-id-2-no-1" class="wp-table-reloaded wp-table-reloaded-id-2">
<tbody class="row-hover">
	<tr class="row-1 odd">
		<td class="column-1">Compilation du fichier Ceylon</td><td class="column-2">~/ceylon/ceylon-compiler/bin/ceylonc -src samples -out build samples/florian_boulay.ceylon</td>
	</tr>
	<tr class="row-2 even">
		<td class="column-1">Exécution du fichier Ceylon</td><td class="column-2">~/ceylon/ceylon-compiler/bin/ceylon -cp build/unversioned/default_module-unversioned.car testCeylon</td>
	</tr>
</tbody>
</table>

<p>Ceylon est un langage simple à comprendre pour qui vient de Java. En écrire est également à la portée de tous. Jusque là les objectifs de Gavin King sont atteints.</p>
<h2> Fin de la session</h2>
<p>Pour finir, Emmanuel nous indique que Ceylon a enfin sont site web : <a href="http://ceylon-lang.org">http://ceylon-lang.org</a></p>
<p>Il contient une documentation très complète, la spécification du langage écrite par Gavin King, un blog et tout ce qu&#8217;il faut pour contribuer au développement du langage. C&#8217;est là bas qu&#8217;il faut aller si vous souhaitez tester le langage qui n&#8217;a pas encore été releasé, mais peut être testé via la récupération du code source sur Github.</p>
<p>Comme vous le voyez, le logo de Ceylon est un éléphant, est-ce un hommage à PHP ? On peut lui souhaiter qu&#8217;il ait le même succès que PHP</p>
<p>De nombreux nouveaux langages ont émergé ces derniers mois fonctionnant sur la JVM (Eclipse Xtend, JetBrains Kotlin). Comme dit plus haut, Ceylon veut rester accessible à tout le monde en restant simple et facilement compréhensible. Est-ce que ces atouts seront suffisants pour faire de Ceylon une alternative à Java réellement utilisée, comme l&#8217;est Scala aujourd&#8217;hui ? Faites vous votre propre opinion et essayez le.</p><p>The post <a href="https://blog.infine.com/devoxx-2011-ceylon-1414">Devoxx 2011 – Ceylon</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.infine.com/devoxx-2011-ceylon-1414/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Devoxx 2011 &#8211; annonces</title>
		<link>https://blog.infine.com/devoxx-2011-annonces-1397?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=devoxx-2011-annonces</link>
					<comments>https://blog.infine.com/devoxx-2011-annonces-1397#respond</comments>
		
		<dc:creator><![CDATA[Florian Boulay]]></dc:creator>
		<pubDate>Wed, 16 Nov 2011 15:29:36 +0000</pubDate>
				<category><![CDATA[Conférence]]></category>
		<category><![CDATA[devoxx]]></category>
		<category><![CDATA[play framework]]></category>
		<guid isPermaLink="false">https://blog.infine.com/?p=1397</guid>

					<description><![CDATA[<p><span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">2</span> <span class="rt-label rt-postfix">min.</span></span> Cette première grosse journée pour Devoxx a été l&#8217;occasion de faire différentes annonces. La première concerne le framework Play et la deuxième concerne le monde Java français. Play La version 2.0 de Play a déjà été annoncée il y a plusieurs semaines. Une pré-version de test avait été mise à disposition. Aujourd&#8217;hui la sortie de &#8230;</p>
<p>The post <a href="https://blog.infine.com/devoxx-2011-annonces-1397">Devoxx 2011 – annonces</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">2</span> <span class="rt-label rt-postfix">min.</span></span><p><a href="https://blog.infine.com/wp-content/uploads/2011/11/devoxx11.png" class="fancyboxgroup" rel="gallery-1397" title="Devoxx 2011"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2011/11/devoxx11.png" alt="Logo Devoxx 2011" title="Devoxx 2011" width="218" height="80" class="alignright size-full wp-image-1407" /></a><br />
Cette première grosse journée pour Devoxx a été l&#8217;occasion de faire différentes annonces. La première concerne le framework Play et la deuxième concerne le monde Java français.</p>
<h1>Play</h1>
<p>La version 2.0 de Play a déjà été annoncée il y a plusieurs semaines. Une pré-version de test avait été mise à disposition. Aujourd&#8217;hui la sortie de la beta a été annoncée.</p>
<p><span id="more-1397"></span></p>
<p>Lors de la présentation faite par Sadek Drobi (<a href="http://twitter.com/Sadache">@Sadache</a>) et Guillaume Bort, les nouveautés ont été détaillées :</p>
<ul>
<li>Intégration de Scala directement dans Play : les templates ne se feront plus en Groovy mais en Scala. Les classes pourront être faites en Java ou en Scala. Cela a pour conséquence la mise à disposition de la console Scala qui permettra, par exemple, d&#8217;appeler directement du code applicatif à parti de la ligne de commande.</li>
<li>Un système de build est désormais intégré, il s&#8217;agit de SBT (Simple Build Tool). Ce choix est certainement la conséquence de l&#8217;intégration de Scala. Cela remplacera l&#8217;ancien système basé sur Ivy.</li>
<li>Intégration d&#8217;Akka</li>
<li>Les scripts javascript et les feuilles de styles sont compilés</li>
</ul>
<p>Plus d&#8217;infos disponibles sur le site officiel : <a href="http://scala.playframework.org/2.0">http://scala.playframework.org/2.0</a></p>
<p>L&#8217;autre annonce est que Play intègre désormais la stack Typesafe. Cela signifie que Typesafe fournira du support sur Play. De plus Guillaume Bort va désormais siégé au board of advisor de Typesafe (Je ne sais pas comment le traduire, conseil d&#8217;administration ?) en tant que conseiller sur les choix techniques web d&#8217;après ce que Guillaume a dit durant sa présentation.</p>
<h1>Devoxx France</h1>
<p><a href="https://blog.infine.com/wp-content/uploads/2011/11/devoxx_france_300_250.gif" class="fancyboxgroup" rel="gallery-1397" title="devoxx_france"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2011/11/devoxx_france_300_250.gif" alt="Bannière Devoxx France" title="devoxx_france" width="250" height="200" class="alignleft size-full wp-image-1405" /></a></p>
<p>Une version française de Devoxx se tiendra du 18 au 20 avril 2012 à Paris ! Elle est inspirée du modèle belge et elle durera 3 jours et sera à 75% en français et 25% en anglais. Elle est organisée par les membres du Paris Jug (Antonio Goncalves, Zouheir Cadi, José Paumard et Nicolas Martignolle). Ce sera la plus grosse conférence Java francophone, venez nombreux !<br />
In Fine sera bien entendu partenaire de cet évènement.<br />
Plus de détails sur le <a href="http://www.touilleur-express.fr/2011/11/16/devoxx-france-2012/">blog de Nicolas Martignolle.</a></p><p>The post <a href="https://blog.infine.com/devoxx-2011-annonces-1397">Devoxx 2011 – annonces</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.infine.com/devoxx-2011-annonces-1397/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Paris JUG : Improve your sex life with Git</title>
		<link>https://blog.infine.com/paris-jug-improve-your-sex-life-with-git-835?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=paris-jug-improve-your-sex-life-with-git</link>
					<comments>https://blog.infine.com/paris-jug-improve-your-sex-life-with-git-835#comments</comments>
		
		<dc:creator><![CDATA[Florian Boulay]]></dc:creator>
		<pubDate>Thu, 14 Apr 2011 15:31:50 +0000</pubDate>
				<category><![CDATA[Conférence]]></category>
		<category><![CDATA[dvcs]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[jug]]></category>
		<category><![CDATA[parisjug]]></category>
		<guid isPermaLink="false">https://blog.infine.com/?p=835</guid>

					<description><![CDATA[<p><span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">7</span> <span class="rt-label rt-postfix">min.</span></span> Mardi soir se tenait une session consacrée entièrement à Git au Paris JUG qui a été sponsorisée par In Fine. Elle a rencontré un énorme succès, les places ont été prises d’assaut en moins de 4h. Néanmoins beaucoup de gens se sont fait recaler à l’entrée. La polémique des inscriptions Certains ont accusé JUG Events &#8230;</p>
<p>The post <a href="https://blog.infine.com/paris-jug-improve-your-sex-life-with-git-835">Paris JUG : Improve your sex life with Git</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">7</span> <span class="rt-label rt-postfix">min.</span></span><p><a href="https://blog.infine.com/wp-content/uploads/2011/04/parisJug1.jpg" class="fancyboxgroup" rel="gallery-835" title="Paris JUG logo"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2011/04/parisJug1.jpg" alt="Paris JUG logo" title="Paris JUG logo" width="300" height="129" class="alignleft size-full wp-image-842" /></a><br />
Mardi soir se tenait une session consacrée entièrement à Git au <a href="http://www.parisjug.org/xwiki/bin/view/Meeting/20110412">Paris JUG</a> qui a été sponsorisée par In Fine. Elle a rencontré un énorme succès, les places ont été prises d’assaut en moins de 4h. Néanmoins beaucoup de gens se sont fait recaler à l’entrée.</p>
<h3>La polémique des inscriptions</h3>
<p>Certains ont accusé <a href="http://www.jugevents.org/jugevents/">JUG Events</a> pour ce désastre au niveau des inscriptions. Quoi qu’il en soit, ce site semble de plus en plus inadapté au succès que rencontre le Paris JUG. Il y a quelques mois Nicolas Martignole avait indiqué que JUG Events était open source, et que toute contribution était la bienvenue pour améliorer le site (<a href="http://code.google.com/p/jugevents/">Google Code de JUG Events</a>). Si vous avez quelques heures pour le faire, n’hésitez pas, toute la communauté des JUG vous en saura gré.</p>
<h3>Quiz et Mac Book</h3>
<p>In Fine, sponsor du JUG a voulu pour cette soirée créer une animation différente : des boîtiers ont été distribués à chaque participant afin de participer à un quiz portant sur Git et Java principalement, présenté par Antoine Ramponi. Le gagnant du quiz s’est vu remettre un Mac Book Air ! Il s’agit de Guillaume Darmont (<a href="http://twitter.com/gdarmont">@gdarmont</a>) qui a fait un sans faute en répondant correctement aux 18 questions. Bravo à lui ! Les photos sont à la fin de l’article.</p>
<h1>Sébastien Douche, l’unique speaker</h1>
<p><a href="https://blog.infine.com/wp-content/uploads/2011/04/SebastienDouche1.jpg" class="fancyboxgroup" rel="gallery-835" title="Sebastien Douche"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2011/04/SebastienDouche1.jpg" alt="Sebastien Douche" title="Sebastien Douche" width="80" height="114" class="alignright size-full wp-image-843" /></a></p>
<p>Sébastien Douche, en habitué, est venu présenté Git en 2 parties : la première théorique est la deuxième avec des cas plus pratiques. Contrairement à sa présentation de l’année dernière sur les DVCS en général, cette soirée est entièrement dédiée à Git.</p>
<p>Mais avant d’attaquer le vif du sujet, rappelons qui est Sébastien Douche. Il se présente comme une personne multi-casquettes. Il est directeur technique, responsable R&#038;D, coach et release manager. Cette dernière a fait qu’il s’est intéressé aux DVCS en général, puisqu’il a également pratiqué Mercurial pendant 2 ans avant de passer à Git. Il a créé un <a href="http://blog.gitfr.net/">blog</a> sur Git (appelé gitfr) qui lui sert surtout de support pour ses présentations. On y trouvera également de nombreux articles intéressants, ainsi gitfr est devenue une ressource francophone de qualité sur Git.<br />
Son espoir : que le gens travaillent ensemble de manière efficace.<br />
Par ailleurs, il fait de l’agilité, du python, aime la bière.<br />
A suivre sur twitter <a href="http://twitter.com/#!/sdouche">@sdouche</a></p>
<p><span id="more-835"></span></p>
<h1>1<sup>ère</sup> partie : le backend de Git</h1>
<p>A première vue, Git peut sembler complexe, pourtant il est fait de concepts simples. Mis ensemble, ils font la puissance de Git. En passant à Git, Sébastien suggère de tout oublier (en visant SVN notamment). Les habitudes que nous av(i)ons avec Subversion ne sont pas transposables avec Git.<br />
Git est très apprécié par ceux qui l’utilisent. Par exemple dans le Git Survey 2010, 95% des utilisateurs sont heureux ou en extase avec Git. Pas sûr que le résultat soit le même avec un outil comme Subversion.<br />
Sébastien résume Git en 3 points :</p>
<ul>
<li>Gestionnaire de contenu </li>
<li>Stocké sous la forme d’un graphe acyclique d’objets </li>
<li>Accessible avec des références </li>
</ul>
<p>Git peut être vu de 2 points de vue : backend et frontend. Le backend est composé de commandes dites “plumbing” et le frontend de commandes dites “porcelain”. Le frontend correspond aux commandes utilisées quotidiennement. Ces commandes font appel aux commandes bas niveau (plumbing) du backend.<br />
Sébastien est convaincu qu’il vaut mieux connaître les concepts clés du backend sur lesquels s’appuie Git afin de mieux l’utiliser et de mieux le maîtriser.</p>
<h2>Concept 1 : Git est un gestionnaire de contenu</h2>
<p>Git est orienté contenu (contrairement à SVN qui est orienté fichier), cela signifie qu’il stocke les fichiers en entier pour chaque commit, alors qu’un gestionnaire orienté fichier stocke seulement les deltas entre 2 commits.</p>
<figure id="attachment_847" aria-describedby="caption-attachment-847" style="width: 300px" class="wp-caption aligncenter"><a href="https://blog.infine.com/wp-content/uploads/2011/04/git-delta-snapshot1.png" class="fancyboxgroup" rel="gallery-835" title="Delta vs Snapshot Git"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2011/04/git-delta-snapshot1-300x225.png" alt="Delta vs Snapshot Git" title="Delta vs Snapshot Git" width="300" height="225" class="size-medium wp-image-847" srcset="https://blog.infine.com/wp-content/uploads/2011/04/git-delta-snapshot1-300x225.png 300w, https://blog.infine.com/wp-content/uploads/2011/04/git-delta-snapshot1.png 1024w" sizes="(max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-847" class="wp-caption-text">Delta vs Snapshot Git (<em>Cliquer pour agrandir</em>)</figcaption></figure>
<p>Les objets sont stockés dans une base de données de type clé/valeur. Les clés sont de type SHA-1. Ce qui assure leur unicité dans le monde entier. Tout objet dans Git peut être identifié à l’aide de son SHA-1.</p>
<blockquote><p><strong>Exemple de SHA-1 :</strong> <code>da39a3ee5e6b4b0d3255bfef95601890afd80709</code> qui peut être raccourci en <code>da39a3</code></p></blockquote>
<p>Git possède 3 types d’objets principaux :</p>
<ul>
<li>Blob : contenu des fichiers </li>
<li>Tree : correspondance entre Blog et nom de fichier </li>
<li>Commit : ensemble de Tree regroupés lors d’un commit </li>
</ul>
<h2>Concept 2 : La relation entre commits est un graphe acyclique (DAG)</h2>
<p>Un graphe acyclique est un graphe sans boucle.<br />
Dans Git, chaque commit connait son ou ses parents, c’est-à-dire quels sont les précédents commits sur le fichier.<br />
<figure id="attachment_848" aria-describedby="caption-attachment-848" style="width: 300px" class="wp-caption aligncenter"><a href="https://blog.infine.com/wp-content/uploads/2011/04/git-dag1.png" class="fancyboxgroup" rel="gallery-835" title="Git DAG"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2011/04/git-dag1-300x68.png" alt="Git DAG" title="Git DAG" width="300" height="68" class="size-medium wp-image-848" srcset="https://blog.infine.com/wp-content/uploads/2011/04/git-dag1-300x68.png 300w, https://blog.infine.com/wp-content/uploads/2011/04/git-dag1.png 972w" sizes="(max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-848" class="wp-caption-text"><em>Cliquer pour agrandir</em></figcaption></figure></p>
<p>Git contient 6 opérations qui permettent d’ajouter du contenu dans le graphe (donc dans la base de données) :</p>
<ul>
<li>commit : ajout de contenu dans le graphe </li>
<li>merge : fusion de 2 branches </li>
<li>rebase : simplification du graphe en transformant 2 branches en une seule </li>
<li>squash : nettoyage du graphe </li>
<li>cherry : copie sans conservation de l’historique </li>
<li>revert : annulation de l’ajout d’un contenu </li>
</ul>
<p>Sébastien insiste pour nous dire que sur Git, seule la vision topologique a un sens, contrairement à la vision chronologique d’autres VCS (i.e. SVN). Ainsi Git offre plusieurs commandes permettant d’avoir cette vision en réarrangeant l’historique.<br />
Dans Git, les objets sont immuables. De plus un historique de toutes les actions est conservé, nommé le <em>reflog</em>. Il permet de défaire toute opération qui aurait mal tourné, tel qu’un rebase qui aurait complètement pourri le projet par exemple.</p>
<h2>Concept 3 : Les objets sont accessibles sous forme de référence</h2>
<p>Deux types de référence existent dans Git :</p>
<ul>
<li>Déplacées par Git : par exemple master qui est l’équivalent de head pour Subversion </li>
<li>Déplacées par l’utilisateur : par exemple un tag léger posé par l’utilisateur </li>
</ul>
<p>Une branche n’est qu’une référence vers un noeud du graphe déplacée par Git. C’est pourquoi une branche est si rapide à créer. Concrètement, une référence n’est qu’un fichier de 40 octets.</p>
<h2>Résumé des concepts</h2>
<p>Git peut être vu comme un empilement de couches (de bas en haut) :</p>
<ul>
<li>Base de données (objets de type blob) </li>
<li>Mini système de fichiers (objets de type tree)  </li>
<li>Relation entre objets (objets de type commit)  </li>
<li>Objets facilement mémorisables (références)  </li>
</ul>
<p>La première partie termine comme elle a commencé, en rappelant que Git n’est pas si compliqué. Git n’est pas magique, il est basé sur des concepts simples et bien implémentés. Git est au niveau de ce qu’on attend d’un VCS aujourd’hui, alors que SVN est basé sur CVS qui date des années 80.</p>
<h1>2<sup>ème</sup> partie : Git en pratique</h1>
<h2>Bien commencer</h2>
<p>Dans cette partie, Sébastien a voulu démontrer la puissance de Git en présentant des bonnes pratiques et des fonctionnalités qui lui sont liées.<br />
Il commence avec de quelques conseils pour démarrer avec Git :</p>
<ul>
<li>Tout d’abord configurer son identité dans Git : mettre son nom et son adresse mail qui apparaîtront dans les commits </li>
<pre class="brush: bash; title: ; notranslate">
git config --global user.name &quot;Florian Boulay&quot;
git config --global user.email &quot;florian.b@mail.com&quot;
</pre>
<li>Utiliser le projet <a href="https://github.com/github/gitignore">gitignore</a> afin de configurer les fichiers ignorés par Git </li>
<li>Utiliser des alias sur les commandes usuelles ou longues. </li>
<pre class="brush: bash; title: ; notranslate">
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
</pre>
<li>Utiliser git prompt afin d’avoir un shell donnant beaucoup d’informations utiles. Plus d’infos sur gitfr </li>
<li>Utiliser la complétion automatique des commandes</li>
</ul>
<p>La complexité de Git n’est qu’apparente. Git possède 145 commandes, dont 37 porcelain. Au quotidien, Sébastien en utilise 18. Cela réduit considérablement l’image de la difficulté supposée de Git.</p>
<p>Git est en moyenne plus rapide que Subversion, et ce même sur des commandes distantes. Par exemple un <em>git clone</em> est en moyenne plus rapide qu’un <em>svn checkout</em>.</p>
<p>En parlant de la commande <em>checkout</em>, elle permet pour Git de se déplacer sur le graphe. On peut donc potentiellement faire un commit sur n’importe quelle version d’un fichier. Cependant Git va considérer qu’un commit qui n’est pas fait sur une référence de type branche sera perdu. Cela signifie que le gc pourra supprimer ces références. Cela s’appelle un <em>detached head</em>.</p>
<h2>L’index</h2>
<p>Git fournit un espace dans lequel l’utilisateur peut mettre les fichiers qu’il souhaite ajouter au commit qui interviendra plus tard. Cet espace se nomme l’index (ou staging area). Ce concept paraît inutile au premier abord, mais Sébastien nous certifie qu’une fois que nous avons pris l’habitude d’utiliser l’index, il est presque impossible de réutiliser un VCS n’en possédant pas. L’index permet de préparer le commit que nous souhaitons faire en y ajoutant les fichiers progressivement une fois le travail effectué sur chacun.</p>
<h2>git stash</h2>
<p>Si un utilisateur doit interrompre son travail de manière inopinée, plutôt que de devoir faire un commit d’un travail à moitié fini, Git met à disposition une commande permettant de mettre le travail en cours de côté afin de pouvoir le reprendre plus tard : il s’agit de la commande <em>git stash<em>.<br />
Les <em>git stash</em> sont empilables. De plus, on peut reprendre le travail en le mettant sur une nouvelle branche en faisant <em>git stash branch nouvelleBranche</em>.</p>
<h2>Récupération des boulettes</h2>
<p><em>git commit –amend</em> permet de modifier le dernier commit effectué.<br />
<em>git reflog</em> permet de revenir en arrière suite à une grosse bêtise tel qu’un rebase ou squash qui n’aurait pas réussi.<br />
<em>git reset</em> permet de revenir en arrière dans le graphe.</p>
<h2>Utilisation avancée de certains concepts</h2>
<h3>tags</h3>
<p>Git possède plusieurs types de tags. Sébastien nous conseille d’utiliser à chaque fois le tag annoté au lieu du tag léger, car il permet d’ajouter un message pour lui donner un sens.</p>
<h3>rebase</h3>
<p>La commande git rebase possède de nombreuses fonctionnalités très puissantes. La documentation à ce sujet est très complète. Quelques unes des puissantes options de rebase sont :</p>
<ul>
<li>–onto : permet de faire un rebase d’une branche 3 vers une branche 1 sans tenir compte des modifications de la branche 2 </li>
<figure id="attachment_836" aria-describedby="caption-attachment-836" style="width: 300px" class="wp-caption aligncenter"><a href="https://blog.infine.com/wp-content/uploads/2011/04/git-rebase-onto1.png" class="fancyboxgroup" rel="gallery-835" title="git rebase onto"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2011/04/git-rebase-onto1-300x99.png" alt="git rebase onto" title="git rebase onto" width="300" height="99" class="size-medium wp-image-836" srcset="https://blog.infine.com/wp-content/uploads/2011/04/git-rebase-onto1-300x99.png 300w, https://blog.infine.com/wp-content/uploads/2011/04/git-rebase-onto1.png 560w" sizes="(max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-836" class="wp-caption-text"><em>Cliquer pour agrandir</em></figcaption></figure>
<li>-i : permet de faire un rebase interactif. Cela donne accès aux options suivantes : édition d’un commit, squash d’un commit, changement de l’ordre des commits </li>
</ul>
<h3>filter-branch</h3>
<p>Cette commande possède plusieurs fonctionnalités et notamment celle de modifier l’historique d’une partie du graphe. Par exemple, si des fichiers binaires ont été mis en contrôle de source, <em>git filter-branch</em> permet d’effacer ces fichiers binaires sur un ensemble de commits.</p>
<h3>Github</h3>
<p>Github est le sourceforge des années 2010. En plus de gérer des repository Git, il permet de mettre en avant le développeur au lieu du projet. Cette dimension sociale se retrouve partout dans l’interface de Git. Plus d’informations sur gitfr.<br />
On finit par…<br />
« Git a-t-il amélioré la vie sexuelle de ses utilisateurs ? », certainement oui.<br />
Git redonne le sourire aux développeurs après tant d’années à batailler avec des VCS non adaptés à leur besoin. Git propose de nombreuses autres fonctionnalités à découvrir : le manuel est complet et intelligible, les ressources sont abondantes sur le net, il ne reste plus aux sceptiques qu’à essayer. </p>
<h1>Photos</h1>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="300" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="flashvars" value="offsite=true&amp;lang=en-us&amp;page_show_url=%2Fphotos%2F61727838%40N06%2Fsets%2F72157626366071083%2Fshow%2F&amp;page_show_back_url=%2Fphotos%2F61727838%40N06%2Fsets%2F72157626366071083%2F&amp;set_id=72157626366071083&amp;jump_to=" /><param name="allowFullScreen" value="true" /><param name="src" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="600" height="400" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowfullscreen="true" flashvars="offsite=true&amp;lang=en-us&amp;page_show_url=%2Fphotos%2F61727838%40N06%2Fsets%2F72157626366071083%2Fshow%2F&amp;page_show_back_url=%2Fphotos%2F61727838%40N06%2Fsets%2F72157626366071083%2F&amp;set_id=72157626366071083&amp;jump_to="></embed></object></p><p>The post <a href="https://blog.infine.com/paris-jug-improve-your-sex-life-with-git-835">Paris JUG : Improve your sex life with Git</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.infine.com/paris-jug-improve-your-sex-life-with-git-835/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Ce que j&#8217;aime dans Play!</title>
		<link>https://blog.infine.com/ce-que-j%e2%80%99aime-dans-play-10?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ce-que-j%25e2%2580%2599aime-dans-play</link>
					<comments>https://blog.infine.com/ce-que-j%e2%80%99aime-dans-play-10#comments</comments>
		
		<dc:creator><![CDATA[Florian Boulay]]></dc:creator>
		<pubDate>Fri, 18 Feb 2011 09:59:53 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[full-stack]]></category>
		<category><![CDATA[play]]></category>
		<category><![CDATA[play framework]]></category>
		<category><![CDATA[web]]></category>
		<guid isPermaLink="false">https://blog.infine.com/?p=10</guid>

					<description><![CDATA[<p><span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">3</span> <span class="rt-label rt-postfix">min.</span></span> Je suis devenu un adepte du framework Play!. Je ne le pratique pas depuis longtemps, seulement depuis 10 mois environ. Mais la courbe d&#8217;apprentissage est vraiment rapide. Une semaine est suffisante pour être à l&#8217;aise et être autonome. J&#8217;ai la modeste prétention, dans cet article, de montrer 2 ou 3 trucs qui font de ce &#8230;</p>
<p>The post <a href="https://blog.infine.com/ce-que-j%e2%80%99aime-dans-play-10">Ce que j’aime dans Play!</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">3</span> <span class="rt-label rt-postfix">min.</span></span><p><a href="https://blog.infine.com/wp-content/uploads/2011/01/play_logo.png" class="fancyboxgroup" rel="gallery-10"><img loading="lazy" decoding="async" class="alignleft size-full wp-image-447" src="https://blog.infine.com/wp-content/uploads/2011/01/play_logo.png" alt="play logo" width="144" height="65" /></a>Je suis devenu un adepte du framework Play!. Je ne le pratique pas depuis longtemps, seulement depuis 10 mois environ. Mais la courbe d&#8217;apprentissage est vraiment rapide. Une semaine est suffisante pour être à l&#8217;aise et être autonome. J&#8217;ai la modeste prétention, dans cet article, de montrer 2 ou 3 trucs qui font de ce framework une nouvelle manière de voir le web en Java.</p>
<p>Pour commencer, Play! est très simple à installer. Il suffit de décompresser le zip dans un répertoire, et de créer une variable <em>PLAY_HOME</em> qui pointe sur ce répertoire. Play! a uniquement besoin de Java comme pré-requis pour fonctionner. Et c&#8217;est tout ! Pour rappel, la plupart des autres frameworks web Java ont au moins besoin d&#8217;un serveur d&#8217;application&#8230;</p>
<p>Comme Play! embarque un serveur web, il se suffit à lui-même. Cette notion est appelée &#8220;full-stack&#8221;. Elle signifie que Play! est autonome à la fois dans son mode de développement en proposant tout ce qu&#8217;il faut pour faire une application web, de la couche présentation à l&#8217;accès aux données, et également lors de l&#8217;exécution des applications Play! qui tournent grâce au serveur web intégré.</p>
<p>Play! propose de nombreuses fonctionnalités peu répandues dans le monde du web en java. Par exemple, le code modifié est pris à chaud par le serveur web, il suffit de rafraîchir le navigateur pour voir sa modification ! La gestion d&#8217;erreur est également poussée. Lorsqu&#8217;une exception se produit, l&#8217;erreur s&#8217;affiche très clairement dans le navigateur. Comme le montre l&#8217;image suivante :<br />
<figure id="attachment_458" aria-describedby="caption-attachment-458" style="width: 300px" class="wp-caption aligncenter"><a href="https://blog.infine.com/wp-content/uploads/2011/01/play_exception_page.png" class="fancyboxgroup" rel="gallery-10"><img decoding="async" src="https://blog.infine.com/wp-content/uploads/2011/01/play_exception_page-300x160.png" alt="Play exception page" /></a><figcaption id="caption-attachment-458" class="wp-caption-text"><em>Cliquez sur l'image pour l'agrandir</em></figcaption></figure></p>
<p>Le développement rapide est une des caractéristiques de Play! On passe beaucoup plus de temps à coder qu&#8217;à faire de la configuration ou de l&#8217;installation. Et ce n&#8217;est pas tout, Play! propose beaucoup de moyens d&#8217;accélérer le développement. Je vais donc vous en montrer quelques uns. Je ne compte pas énumérer tout ce qui fait que Play! permet de développer rapidement, mais seulement donner un aperçu.<br />
Play! propose sur son site, une documentation très complète, ainsi qu&#8217;un tutoriel bien fait qui permet de se familiariser avec les notions principales du framework. Si on peut paraître sceptique devant tant de d&#8217;enthousiasme, faire le tutoriel permettra à quiconque de se rendre compte de la rapidité avec laquelle le développement se fait avec Play!.</p>
<p><span id="more-10"></span></p>
<h1>Arborescence</h1>
<p>Ceux qui connaissent Ruby on Rails et Grails ont déjà les bases pour Play!. Par exemple, l&#8217;arborescence des répertoires est très similaire :<br />
<a href="https://blog.infine.com/wp-content/uploads/2010/05/play_directory_structure.png" class="fancyboxgroup" rel="gallery-10" title=""><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2010/05/play_directory_structure.png" alt="Play directory structure" title=""Play directory structure" width="90" height="108" class="alignnone size-full wp-image-451" /></a><br />
Les répertoires ont des noms explicites, par exemple le répertoire <em>public</em> permet au serveur web de renvoyer des ressources directement, telles que des images ou des scripts.<br />
Le répertoire <em>conf</em> contient les fichiers de configuration comme son nom l&#8217;indique. Par défaut, Play! en crée trois : </p>
<ul>
<li>Un pour l&#8217;application de l&#8217;application et du serveur web</li>
<li>Un pour définir les URL de l&#8217;application</li>
<li>Un dernier contenant les messages de l&#8217;application</li>
</ul>
<p>D&#8217;autres fichiers de configuration peuvent être créer dans ce répertoire, notamment pour chaque langue gérée par votre application.</p>
<h1>La puissance dans le fichier de configuration</h1>
<p><em>Application.conf</em> est un fichier similaire à un fichier properties. Il est créé par Play! lors de la création d&#8217;une application. Il contient plein de valeurs essentielles pour configurer le serveur web, telles que le port à utiliser, le nom du cookie. Il contient également des propriétés permettant de configurer l&#8217;application comme la base de données, la configuration JPA, du cache&#8230;</p>
<p>Le gros avantage de ce fichier, est qu&#8217;il peut être l&#8217;unique fichier de configuration de l&#8217;application, et ce quel que soit l&#8217;environnement sur lequel est déployé la web app ! En effet Play! intègre un système qui permet de surcharger des valeurs dans le fichier de configuration. Lors du lancement de l&#8217;application, il suffit de préciser un paramètre supplémentaire sur la ligne de commande pour choisir les propriétés à appliquer. Comme ce n&#8217;est sûrement pas clair, voici un exemple :</p>
<pre class="brush: java; title: ; notranslate">
%integration.application.mode=dev
%production.application.mode=prod
application.mode=dev
</pre>
<p>Le fichier ci-dessus est un extrait d&#8217;un fichier de configuration <em>application.conf</em>. Il contient 3 fois la même propriété nommée <em>application.mode</em>. Certaines sont suffixées ce qui permet de donner une valeur précise selon si l&#8217;application est lancée en intégration ou en production. Par défaut, la valeur sera celle de ligne 3 si le paramètre n&#8217;est pas indiqué. C&#8217;est super pratique et très bien pensé !</p>
<h1>Le rechargement à chaud du code et de la conf</h1>
<p>La propriété que j&#8217;ai montré dans l&#8217;extrait du fichier <em>application.conf</em> dans le paragraphe précédent, est une clé très spéciale, qui permet encore à Play! de se distinguer. Elle permet d&#8217;indiquer au framework que l&#8217;application est en mode développement ou production. La distinction est très importante pour le développeur, et pour la sécurité de l&#8217;application.</p>
<p>Le mode <em>dev</em> permet au développeur un gain de temps maximum. Lors du développement, un changement sur un fichier de code ou de configuration sera pris à chaud par le framework. Un rafraîchissement de la page du navigateur, et c&#8217;est pris en compte ! C&#8217;est tout simplement du bonheur de développer dans ces conditions.<br />
Le mode <em>production</em> interdit, bien entendu, le rechargement du code à chaud, mais il permet également de précompiler les fichiers java et les fichiers de templates (qui sont les fichiers permettant l&#8217;affichage des pages web). Les performances sont donc meilleures en mode <em>production</em> qu&#8217;en mode <em>développement</em>.</p>
<h1>Sans état !</h1>
<p>Play! est un framework sans état. Cela signifie qu&#8217;aucune session n&#8217;est conservée du côté du serveur. Cette philosophie est à l&#8217;opposée de la plupart des frameworks java bâtis sur la norme servlet. Cela permet à Play! de se rapprocher de la philosophie initiale du protocole HTTP où chaque requête est indépendante de la précédente, donc sans état. Le framework sait qui effectue la requête grâce au cookie.<br />
Du côté serveur, il faut donc repenser sa manière de gérer les requêtes sans état. Par exemple, si des objets doivent être stockés pour être utilisés lors des requêtes suivantes, il faudra utiliser un cache ou la base de donnée directement. D&#8217;ailleurs à propos du cache, Play! intègre un cache directement basé sur EhCache.<br />
Le fait que Play! soit sans état permet d&#8217;avoir une architecture scalable. Cela permet aussi au framework de gérer très facilement les requêtes de type REST qui sont également des requêtes sans état.<br />
Encore une bonne raison d&#8217;essayer Play!.</p>
<h2>Exemple d&#8217;URL de type REST</h2>
<p>Allez, je vous donne un exemple de REST implémenté dans Play!. L&#8217;exemple suivant permet d&#8217;effacer une personne de l&#8217;application.<br />
L&#8217;unique page de l&#8217;application affiche une liste de personnes. La seule action possible est d&#8217;en effacer une :<br />
<a href="https://blog.infine.com/wp-content/uploads/2011/01/list_person.png" class="fancyboxgroup" rel="gallery-10"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2011/01/list_person.png" alt="list of persons" width="207" height="82" class="aligncenter size-full wp-image-488" /></a><br />
Le fait de cliquer sur le lien <em>delete</em> appelera une URL définie dans le fichier de configuration <em>routes</em> dont voici l&#8217;extrait concerné :</p>
<pre class="brush: java; title: ; notranslate">
DELETE        /person/{id}         Application.deletePerson
</pre>
<p>Ce fichier définie une URL de type REST. Elle signifie qu&#8217;une URL de type <em>/person/348</em> avec la méthode HTTP <em>DELETE</em> appelera la méthode <em>Application.deletePerson</em> avec le paramètre 348.<br />
Lorsqu&#8217;on affiche la page d&#8217;accueil, la log indique :</p>
<pre class="brush: java; title: ; notranslate">
21:00:57,315 INFO  ~ URL called : GET localhost/
</pre>
<p>Ensuite, une fois que nous cliquons sur le lien delete :</p>
<pre class="brush: java; title: ; notranslate">
21:06:24,937 INFO  ~ URL called : DELETE localhost/person/2
</pre>
<p>Evidemment, l&#8217;affichage des personnes fonctionne tel qu&#8217;attendu :<br />
<a href="https://blog.infine.com/wp-content/uploads/2011/01/list_person_with_deleted_person.png" class="fancyboxgroup" rel="gallery-10"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2011/01/list_person_with_deleted_person.png" alt="list with person deleted" width="195" height="55" class="aligncenter size-full wp-image-489" /></a></p>
<p>Le code java est extrêmement simple. Voici la méthode affichant l&#8217;URL et la méthode HTTP pour chaque requête HTTP :</p>
<pre class="brush: java; title: ; notranslate">
@Before
static void printHttpInfos() {
	Logger.info(&quot;URL called : %s %s&quot;, request.method, request.domain + request.path);
}
</pre>
<p>Et voici le code java permettant la suppression d&#8217;une personne :</p>
<pre class="brush: java; title: ; notranslate">
public static void deletePerson(long id) {
	Person.&lt;Person&gt; findById(id).delete();
	index();
}
</pre>
<p>Je ne vais pas vous décrire ce que fait chaque ligne de code. Je voulais simplement montrer à quel point il est facile de faire des choses qui sont plus compliquées sans Play!. Encore une fois, n&#8217;hésitez pas à aller faire le tutoriel sur le site de Play!, on y apprend toutes les bases et notamment ce que je viens de vous montrer.</p>
<h1>Les tests</h1>
<p>Dans un framework moderne, la prise en charge des tests est indispensable, et Play! n&#8217;y échappe pas. Les tests Play! sont basés sur deux librairies très connues : JUnit et Selenium.<br />
En lançant le serveur en mode <em>test</em>, les tests peuvent être lancés via une page dédiée sur l&#8217;application web. C&#8217;est très pratique pour lancer manuellement des tests via le browser.<br />
D&#8217;autre part les données de tests peuvent être initialisées grâce à un fichier YAML. Voici le fichier utilisé pour initialiser les données du paragraphe précédent (dans mon cas je l&#8217;ai utilisé pour initialiser la base de données de mon application) :</p>
<pre class="brush: plain; title: ; notranslate">
Person(test1):
    firstName: Florian
    lastName: Boulay

Person(test2):
    firstName: Antonio
    lastName: Goncalves

Person(test3):
    firstName: Antoine
    lastName: Ramponi
</pre>
<p>Play! permet de créer 3 types de tests :</p>
<ul>
<li>Les tests unitaires : les classes doivent hériter de la classe <em>UnitTest</em>. C&#8217;est l&#8217;équivalent d&#8217;un test JUnit classique.</li>
<li>Les tests fonctionnels : les classes doivent hériter de la classe <em>FunctionnalTest</em>. Ce sont des tests d&#8217;intégration avec l&#8217;application web.</li>
<li>Les tests de validation : ce sont des tests Selenium.</li>
</ul>
<h2>Les tests  fonctionnels</h2>
<p>Je vais faire un petit zoom sur les tests dits fonctionnels.</p>
<p>Pour cela j&#8217;ai un peu modifié l&#8217;exemple utilisé précédemment afin d&#8217;avoir plus de cas de tests possibles. La mini application web ne comporte toujours qu&#8217;une seule page, mais elle est désormais composée de 2 listes : une liste d&#8217;employés disponibles, et une des employés d&#8217;astreinte. L&#8217;interface ressemble à ceci :<br />
<a href="https://blog.infine.com/wp-content/uploads/2011/01/managing_employees_2.png" class="fancyboxgroup" rel="gallery-10" title="Managing employees"><img loading="lazy" decoding="async" src="https://blog.infine.com/wp-content/uploads/2011/01/managing_employees_2-300x167.png" alt="Managing employees" title="Managing employees" width="300" height="167" class="aligncenter size-medium wp-image-582" srcset="https://blog.infine.com/wp-content/uploads/2011/01/managing_employees_2-300x167.png 300w, https://blog.infine.com/wp-content/uploads/2011/01/managing_employees_2.png 340w" sizes="(max-width: 300px) 100vw, 300px" /></a><br />
Le fait de cliquer sur <em>on call</em> permet de faire passer la personne d&#8217;astreinte en la mettant dans la seconde liste. Le fait de cliquer sur <em>free</em> permet de faire l&#8217;inverse.</p>
<p>Comme dit précédemment les classes de test doivent hériter de la classe <em>FunctionnalTest</em>. De plus, le serveur doit être lancé en mode test. Voici un exemple de test fonctionnel permettant de tester l&#8217;unique page de cette application. La première méthode teste l&#8217;état initial, c&#8217;est-à-dire les 3 personnes qui sont présentes dans la liste des employés disponibles. La seconde méthode teste le passage d&#8217;une personne de la première liste à la seconde en cliquant sur le lien <em>on call</em> :</p>
<pre class="brush: java; title: ; notranslate">
public class EmployeesTest extends FunctionalTest {

	@Before
	public void setUp() {
		Logger.debug(&quot;Reloading all data&quot;);
		Fixtures.deleteAll();
		Fixtures.load(&quot;data.yml&quot;);
	}

	@Test
	public void testStartState() throws Exception {
		Response response = GET(&quot;/&quot;);
		// test the 200 status
		assertIsOk(response);
		String httpBody = getContent(response);
		assertTrue(httpBody.length() &gt; 0);
		// test that 3 &lt;li&gt; are returned
		assertContentMatch(&quot;(?s)&lt;ul&gt;\\s*&quot; +
							&quot;&lt;li&gt;Florian Boulay.*&quot; +
							&quot;&lt;li&gt;Antonio Goncalves.*&quot; +
							&quot;&lt;li&gt;Antoine Ramponi.*&quot; +
							&quot;&lt;/ul&gt;&quot;, response);
	}

	@Test
	public void testOnCallPeople() throws Exception {
		// make Antonio Goncalves on call
		Person antonio = Person.find(&quot;byFirstName&quot;, &quot;Antonio&quot;).&lt;Person&gt; first();
		Response response = PUT(&quot;/person/onCall/&quot; + antonio.id, &quot;text/html&quot;, &quot;&quot;);
		// test the 302 response
		assertStatus(302, response);
		String httpBody = getContent(response);
		assertTrue(httpBody.length() == 0);
		java.net.URL locationHeader = new java.net.URL(response.getHeader(&quot;location&quot;));
		response = GET(locationHeader.getPath());
		// test the 200 response
		httpBody = getContent(response);
		assertTrue(httpBody.length() &gt; 0);
		assertContentMatch(&quot;(?s)&lt;ul&gt;\\s*&quot; +
							&quot;&lt;li&gt;Florian Boulay.*&quot; +
							&quot;&lt;li&gt;Antoine Ramponi.*&quot; +
							&quot;&lt;/ul&gt;&quot;, response);
		assertContentMatch(&quot;(?s)&lt;ul&gt;\\s*&quot; +
							&quot;&lt;li&gt;Antonio Goncalves.*&quot; +
							&quot;&lt;/ul&gt;&quot;, response);
	}

}
</pre>
<p>Voici les quelques logs générées :</p>
<pre class="brush: java; title: ; notranslate">
00:39:21,725 DEBUG ~ Reloading all data
00:39:21,777 INFO  ~ URL called : GET localhost/
00:39:22,469 DEBUG ~ Reloading all data
00:39:22,505 INFO  ~ URL called : PUT localhost/person/onCall/8
00:39:22,525 INFO  ~ URL called : GET localhost/
</pre>
<h1>L&#8217;API simple</h1>
<p>Ce qui est très agréable au quotidien avec Play! est la facilité d&#8217;utilisation des API disponibles. Je n&#8217;ai pas montré beaucoup de code dans cet article, mais vous pouvez constater la simplicité de lecture du code fait avec Play!. Cela permet comme presque tout le reste, d&#8217;avoir une marge de progression rapide, d&#8217;être opérationnel bien plus vite qu&#8217;avec d&#8217;autres framework web&#8230; Mais tout ça, je l&#8217;ai déjà dit. Je vais plutôt vous montrer quelques lignes utilisant l&#8217;API de Play!, vous pourrez vous faire une idée bien plus facilement qu&#8217;avec un long discours.</p>
<pre class="brush: java; title: ; notranslate">
// récupérer la requête HTTP courante
Request request = Http.Request.current();

// récupérer l'EntityManager 
EntityManager em = JPA.em();

// faire un appel rapide à un web service
HttpResponse response = WS.url(&quot;http://www.w3schools.com/webservices/tempconvert.asmx?op=FahrenheitToCelsius&quot;).get();

// récupérer toutes les entités Person (entité au sens objet du modèle de donnée)
List&lt;Person&gt; findAll = Person.findAll()
// compter le nombre d'entités Person
long count = Person.count();
// faire des requêtes simple sur l'entité Person
List&lt;Person&gt; allAntos = Person.find(&quot;byFirstNameLike&quot;, &quot;anto%&quot;).fetch();
// etc......
</pre>
<h3>Petit mot de la fin</h3>
<p>Cet article touche à sa fin. J&#8217;aurais tellement voulu vous en montrer plus comme la validation super simple, les templates HTML, comment répondre au client en fonction du format qu&#8217;il demande (XML, JSON&#8230;.), mais c&#8217;est déjà assez long. Je profiterai d&#8217;un prochain article pour me concentrer sur un aspect plus précis du framework.<br />
J&#8217;espère avoir convaincu les quelques sceptiques à propos du framework Play!</p>
<h3>Ressources</h3>
<p>Site officiel du framework Play! : <a href="http://www.playframework.org/">http://www.playframework.org/</a><br />
Le google group très actif : <a href="http://groups.google.com/group/play-framework">http://groups.google.com/group/play-framework</a><br />
Le repository git du code source de Play! : <a href="https://github.com/playframework/play">https://github.com/playframework/play</a><br />
Le premier livre sur Play! : <a href="http://www.the-play-book.co.uk/">http://www.the-play-book.co.uk/</a></p><p>The post <a href="https://blog.infine.com/ce-que-j%e2%80%99aime-dans-play-10">Ce que j’aime dans Play!</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.infine.com/ce-que-j%e2%80%99aime-dans-play-10/feed</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>&#8220;==&#8221;.equals(&#8220;equals()&#8221;)</title>
		<link>https://blog.infine.com/equalsequals-8?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=equalsequals</link>
					<comments>https://blog.infine.com/equalsequals-8#respond</comments>
		
		<dc:creator><![CDATA[Florian Boulay]]></dc:creator>
		<pubDate>Tue, 11 Jan 2011 18:00:08 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[equals]]></category>
		<category><![CDATA[optimisation]]></category>
		<category><![CDATA[performance]]></category>
		<guid isPermaLink="false">https://blog.infine.com/?p=8</guid>

					<description><![CDATA[<p><span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">2</span> <span class="rt-label rt-postfix">min.</span></span> Les fondamentaux En java, la comparaison s&#8217;effectue principalement en utilisant 3 méthodes qui n&#8217;ont pas les mêmes buts : L&#8217;opérateur == est utilisé pour comparer les types primitifs et les objets. Il compare uniquement les références. Cela signifie que l&#8217;opérateur retournera &#8220;true&#8221; uniquement si les 2 objets comparés sont les mêmes en mémoire. La méthode &#8230;</p>
<p>The post <a href="https://blog.infine.com/equalsequals-8">“==”.equals(“equals()”)</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">2</span> <span class="rt-label rt-postfix">min.</span></span><h1>Les fondamentaux</h1>
<p>En java, la comparaison s&#8217;effectue principalement en utilisant 3 méthodes qui n&#8217;ont pas les mêmes buts :</p>
<ol>
<li>L&#8217;opérateur == est utilisé pour comparer les types primitifs et les objets. Il compare uniquement les références. Cela signifie que l&#8217;opérateur retournera &#8220;true&#8221; uniquement si les 2 objets comparés sont les mêmes en mémoire.</li>
<li>La méthode &#8216;equals()&#8217; permet de comparer 2 objets. Toutes les classes ont une méthode &#8216;equals()&#8217; héritée de la classe Object. Cette méthode compare la valeur de 2 objets. S&#8217;ils représentent la même chose, alors la méthode doit renvoyer &#8220;true&#8221;. Cette méthode est plus difficile qu&#8217;il n&#8217;y paraît à implémenter. Je pourrais revenir dessus ultérieurement dans un prochain article.</li>
<li>La méthode &#8216;compareTo()&#8217; permet de comparer 2 objets comme la méthode &#8216;equals()&#8217;. Contrairement à &#8216;equals()&#8217;, les classes ne définissent pas toutes cette méthode. Pour cela il faut hériter de l&#8217;interface Comparable. Cette méthode est utilisée pour pouvoir trier les objets l&#8217;implémentant. Si les 2 objets sont égaux, alors la méthode doit renvoyer 0 ; si un object O1 est considéré précédent un autre object O2 alors il faut renvoyer -1, si O2 précède O1 alors il faut renvoyer 1.</li>
</ol>
<pre class="brush: java; title: ; notranslate">
int i = 5, j = 5, k=8;
Integer int1 = new Integer(42) ;
Integer int2 = new Integer(42) ;
String str1 = &quot;Blog&quot;;

java.util.Date t1 = new java.util.Date();
Thread.sleep(1000l);
java.util.Date t2 = new java.util.Date();

System.out.println (i == j); // print true
System.out.println (int1 == int2); // print false
System.out.println (&quot;Blog&quot;.equals(str1)); // print true
System.out.println (str1 == &quot;Blog&quot;); // déconseillé mais écrit true
System.out.println (t1.compareTo(t2)); // print -1
</pre>
<p>Les comparaisons faites avec &#8216;equals()&#8217; ou &#8216;compareTo()&#8217; entre une variable et une constante doivent être réalisées comme à la ligne 13 de l&#8217;exemple précédent, c&#8217;est-à-dire qu&#8217;il faut comparer la constante avec la variable à tester. Ceci permet d&#8217;éviter une potentielle NullPointerException si l&#8217;on faisait &#8216;str1.equals(&#8220;Blog&#8221;)&#8217;.</p>
<h3>Le cas particuliers des enum</h3>
<p>Depuis java 5, les enum ont été introduits dans java. Les enum pourraient faire l&#8217;objet d&#8217;un article complet, mais il est bon de savoir que les enum ont été créés pour être comparés avec l&#8217;opérateur &#8216;==&#8217;. N&#8217;hésitez donc pas à les utiliser ! En plus d&#8217;être très lisibles, ils sont performants à l&#8217;usage.</p>
<p><span id="more-8"></span></p>
<h2>Les performances unitaires</h2>
<p>Si on a le choix, quel opérateur/méthode utiliser pour faire la comparaison ? Un des critères de choix peut être la performance. Sur une application où les comparaisons sont très nombreuses, il peut être judicieux d&#8217;optimiser les comparaisons et donc de choisir en connaissance de cause.</p>
<p>Voici le petit programme qui m&#8217;a permis de tester les performances de chacun. Dans la boucle j&#8217;ai utilisé une des instructions en commentaire à chaque test :</p>
<pre class="brush: java; title: ; notranslate">
long start = System.currentTimeMillis();
for (long l = 0; l &lt; 2 &lt;&lt; 60; l++) {
    // &quot;1&quot;.equals(&quot;1&quot;);
    // if (&quot;1&quot; == &quot;1&quot;) ;
    // &quot;1&quot;.compareTo(&quot;1&quot;);
}
long end = System.currentTimeMillis();
long timePassedInMs = end - start;
&amp;#91;/sourcecode&amp;#93;

Sans surprise les résultats sont les suivants :
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;==&lt;/strong&gt; : 978 ms de moyenne&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;equals()&lt;/strong&gt; : 991 ms de moyenne, soit 1.35 % que ==&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;compareTo()&lt;/strong&gt; : 1004 ms de moyenne, soit 2.62% de plus que ==&lt;/li&gt;
&lt;/ul&gt;
Quelques remarques sur ces résultats :
&lt;ol&gt;
	&lt;li&gt;La première instruction de la méthode 'equals()' de la classe String est de tester que les 2 objets comparés ont la même référence grâce à l'opérateur ==. La différence de temps entre == et 'equals()' s'explique donc uniquement par l'appel de la méthode et le retour de cette méthode. La différence vient aussi en partie du fait que la JVM va inliner la méthode 'equals()' et que ceci prend un certain temps.&lt;/li&gt;
	&lt;li&gt;'compareTo()' de la classe String effectue plusieurs boucles et de nombreux tests. Il est tout à fait logique qu'elle soit plus lente que les 2 autres comparateurs. Elle n'est pas optimisée pour gagner du temps comme l'est 'equals()'.&lt;/li&gt;
&lt;/ol&gt;
Ces quelques tests montrent bien que faire un == est plus rapide que l'appel d'un 'equals()', même si dans le cas de la classe String la différence est faible. Si vous avez le choix, privilégiez donc le == à 'equals()', même si les performances ont l'air très proches. Il peut arriver que vous utilisiez du code que vous ne pouvez pas modifier (API, framework, librairie partagée...) et dans ce cas la méthode 'equals()' peut être mal écrite et donc bien plus lente qu'elle ne l'est pour la classe String. Mais la question est la suivante : comment faire pour avoir le choix entre == et 'equals()' ? Je vais essayer de vous montrer une manière d'avoir le choix un peu plus loin dans ce post, après vous avoir expliqué un peu plus en détail comment fonctionne la classe String.

Nous laissons de côté 'compareTo()' pour la fin du post, car elle n'a pas la même utilité que les 2 autres méthodes de comparaison.
&lt;h2&gt;Le cas de la classe String&lt;/h2&gt;
Comme nous l'avons vu au début du post, les String doivent être comparés à l'aide de la méthode 'equals()'. Cependant il est tentant de vouloir utiliser l'opérateur == plus rapide et renvoyant quasiment tout le temps le même résultat que la méthode 'equals()'.

La classe String a beaucoup de particularités : c'est la seule classe que l'on peut initialiser sans appel explicite à un constructeur ou méthode statique ; elle possède des opérateurs surchargés... et d'autres spécificités encore. Une de ses particularité est que la JVM garde un pool d'instances des objets String. Ainsi, si deux String sont initialisés avec la même valeur, alors la JVM utilisera le même objet. Mais ce n'est pas vrai dans tous les cas. Regardons cet exemple :

&#x5B;sourcecode language=&quot;java&quot;]
final String TEST_VALUE = &quot;infine&quot;;

String inPool = &quot;infine&quot;;
String inPool2 = &quot;in&quot; + &quot;fine&quot;;
String noPool = new String(&quot;infine&quot;);
String suffix = &quot;fine&quot;;
String noPool2 = &quot;in&quot; + suffix;

System.out.println(inPool == TEST_VALUE);  // true
System.out.println(inPool2 == TEST_VALUE);  // true
System.out.println(noPool == TEST_VALUE);  // false
System.out.println(noPool2 == TEST_VALUE);  // false
</pre>
<p>En voyant les résultats, vous comprenez pourquoi il ne faut pas utiliser l&#8217;opérateur == pour la comparaison de String, le résultat est trop incertain. Lorsqu&#8217;un objet String est créé en utilisant l&#8217;opérateur new (comme pour un objet &#8220;normal&#8221; en fait), alors la JVM ne renvoie pas un objet String du pool, mais crée un nouvel objet (cas de l&#8217;objet &#8220;noPool&#8221;). De plus, si un objet String est calculé à l&#8217;exécution, par une concaténation par exemple, alors il n&#8217;est pas créé à partir du pool (cas de l&#8217;objet &#8220;noPool2&#8221;).</p>
<p>Pour se rendre compte de la manière dont le compilateur gère les String, voici un extrait du bytecode généré obtenu avec la commande <em>javap</em> :</p>
<pre class="brush: java; title: ; notranslate">
0:	ldc	#16; //String infine
2:	astore_1
3:	ldc	#16; //String infine
5:	astore_2
6:	ldc	#16; //String infine
8:	astore_3
</pre>
<p>Dans cet extrait, nous voyons que 3 variables font référence au même objet String valant &#8220;infine&#8221; (matérialisé par la référence #16). Ces 3 variables sont dans le code précédent TEST_VALUE, inPool et inPool2. Elles sont déclarées différemment mais le compilateur ne crée qu&#8217;une seul référence dans le pool de String de la JVM.</p>
<p>Si on souhaite forcer la récupération d&#8217;un objet String à partir du pool, alors il faut utiliser la méthode &#8216;intern()&#8217;. Reprenons l&#8217;exemple ci-dessus, mais en utilisant la méthode &#8216;intern()&#8217; :</p>
<pre class="brush: java; title: ; notranslate">
final String TEST_VALUE = &quot;infine&quot;;

String inPool = &quot;infine&quot;;
String inPool2 = &quot;in&quot; + &quot;fine&quot;;
String noPool = new String(&quot;infine&quot;);
String suffix = &quot;fine&quot;;
String notPool2 = &quot;in&quot; + suffix;

System.out.println(inPool == TEST_VALUE);  // true
System.out.println(inPool2 == TEST_VALUE);  // true
System.out.println(noPool.intern() == TEST_VALUE);  // true !
System.out.println(notPool2.intern() == TEST_VALUE);  // true !
</pre>
<p>Pour en savoir plus, n&#8217;hésitez pas à chercher <em>String literal pool</em> dans votre moteur de recherche préféré.</p>
<h1>Étude de cas : == doit renvoyer la même chose que equals()</h1>
<p>La classe String arrive bien à faire que dans certains cas == et &#8216;equals()&#8217; renvoient le même résultat. Nous allons donc essayer de faire mieux ! Nous allons donc partir d&#8217;un exemple simple dans lequel == et &#8216;equals()&#8217; ne sont pas interchangeables. Enfin, nous allons modifier le code afin d&#8217;utiliser == pour chaque comparaison, ceci dans le but d&#8217;avoir de bonnes performances, et une meilleure gestion de la mémoire.<br />
Bien entendu, nous pourrions gagner des performances de plein de manières différentes, mais ce n&#8217;est pas le but de cet article.</p>
<h2>Présentation du code existant</h2>
<p>Voici une classe permettant de gérer des couleurs RGB. Elle est donc composée de 3 attributs pouvant avoir une valeur comprise entre 0 et 255 chacun. Voici une partie du code de la classe avec son constructeur :</p>
<pre class="brush: java; title: ; notranslate">
public class RgbColor {

    private final int green;
    private final int red;
    private final int blue;

    public RgbColor(int green, int red, int blue) {
        super();
        this.green = green;
        this.red = red;
        this.blue = blue;
    }

    // ...other methods, including hashcode() and equals()
}
</pre>
<p>Comme nous le voyons, cette classe possède un unique constructeur. Il est donc possible de créer autant d&#8217;objet de type RgbColor que nous voulons, et s&#8217;ils sont identiques nous seront obligés de les comparer avec &#8216;Equals()&#8217; car chaque objet RgbColor sera différent.<br />
Ce constructeur est l&#8217;équivalent du &#8216;String test = new String(&#8220;test&#8221;)&#8217; vu précédemment dans ce post. Un appel crée toujours un objet.</p>
<h2>Pool de gestion des instances</h2>
<p>La version améliorée ajoute une nouvelle méthode statique. Cette méthode permet de créer un objet s&#8217;il n&#8217;existe pas encore dans le pool, ou alors de renvoyer l&#8217;objet existant si il a déjà été créé auparavant. Ce pattern est appelé static factory pattern, et est très bien décrit dans le livre <em>Effective Java</em> de <strong>Josh Bloch</strong>.</p>
<p>public class RgbColor {</p>
<p>    private final int green;<br />
    private final int red;<br />
    private final int blue;<br />
    // pooling<br />
    private static Map<Integer, RgbColor> pool = new ConcurrentHashMap<Integer, RgbColor>();</p>
<p>    /**<br />
     * Values must be between 0 and 255.<br />
     *<br />
     * @param green<br />
     * @param red<br />
     * @param blue<br />
     * @return<br />
     */<br />
    public static RgbColor getColor(int green, int red, int blue) {<br />
        if (!isAllowedColorValue(green) || !isAllowedColorValue(red) || !isAllowedColorValue(blue)) {<br />
            throw new IllegalArgumentException(&#8220;Allowed color value is between 0 and 255&#8221;);<br />
        }<br />
        // same key as hashcode<br />
        int key = green << 16 | red << 8 | blue;
        if (pool.containsKey(key)) {
            return pool.get(key);
        }
        RgbColor color = new RgbColor(green, red, blue);
        pool.put(key, color);
        return pool.get(key);
    }

    private static boolean isAllowedColorValue(int color) {
        if (color < 0 || color > 255) {<br />
            return false;<br />
        }<br />
        return true;<br />
    }</p>
<p>    private RgbColor(int green, int red, int blue) {<br />
        super();<br />
        this.green = green;<br />
        this.red = red;<br />
        this.blue = blue;<br />
    }</p>
<p>    @Override<br />
    public boolean equals(Object obj) {<br />
        if (this == obj)<br />
            return true;<br />
        if (obj == null)<br />
            return false;<br />
        if (getClass() != obj.getClass())<br />
            return false;<br />
        RgbColor other = (RgbColor) obj;<br />
        if (blue != other.blue)<br />
            return false;<br />
        if (green != other.green)<br />
            return false;<br />
        if (red != other.red)<br />
            return false;<br />
        return true;<br />
    }</p>
<p>    @Override<br />
    public int hashCode() {<br />
        return green << 16 | red << 8 | blue;
    }

    // ...other methods
}
[/sourcecode]

La méthode statique 'getColor()' permet de gérer un pool de toutes les instances de la classe RgbColor. De plus le constructeur est devenu privé, ce qui oblige l'utilisateur de cette classe à construire un object avec la méthode 'getColor()'. Contrairement à la classe String, tous les objets seront donc comparable avec l'opérateur == car un objet unique est créé par triplet rouge, vert, bleu.
Elle est l'équivalent de la construction d'un object String sans constructeur : String test = "test";

Je ne vous joins pas de classe de test, mais les performances sont désormais améliorées car toutes les instances de RgbColor sont comparables avec l'opérateur ==. La mémoire est également mieux gérée car toutes les instances se retrouvent dans le pool. On pourrait encore améliorer cette classe, en remplaçant la 'ConcurrentHashMap' par une <a href="http://www.javaspecialists.co.za/archive/Issue015.html">SoftHashMap</a> par exemple, avec un peu d&#8217;adaptation du code.</p>
<p><strong>Fichiers joints</strong><br />
Code source utilisé pour faire ce post : <a href='https://blog.infine.com/wp-content/uploads/2010/05/post-equals.zip'>Archive zip</a></p><p>The post <a href="https://blog.infine.com/equalsequals-8">“==”.equals(“equals()”)</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.infine.com/equalsequals-8/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Devoxx 2010, vu de l&#8217;intérieur</title>
		<link>https://blog.infine.com/devoxx-2010-vu-de-linterieur-366?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=devoxx-2010-vu-de-linterieur</link>
					<comments>https://blog.infine.com/devoxx-2010-vu-de-linterieur-366#comments</comments>
		
		<dc:creator><![CDATA[Florian Boulay]]></dc:creator>
		<pubDate>Mon, 06 Dec 2010 18:00:30 +0000</pubDate>
				<category><![CDATA[Conférence]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[cloudbees]]></category>
		<category><![CDATA[devoxx]]></category>
		<category><![CDATA[play framework]]></category>
		<guid isPermaLink="false">https://blog.infine.com/?p=366</guid>

					<description><![CDATA[<p><span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">4</span> <span class="rt-label rt-postfix">min.</span></span> Mise à jour du 6 décembre 2010 :CloudBees a levé 4 millions de dollars. Plus de détails sur le blog de CloudBees. Devoxx 2010 s&#8217;est tenue toute cette semaine à Anvers. Entre 2 présentations de Brian Goetz, Joshua Bloch ou Mark Reinhold, je suis allé voir quelques personnalités du monde java afin d&#8217;en savoir plus &#8230;</p>
<p>The post <a href="https://blog.infine.com/devoxx-2010-vu-de-linterieur-366">Devoxx 2010, vu de l’intérieur</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">4</span> <span class="rt-label rt-postfix">min.</span></span><p><strong>Mise à jour du 6 décembre 2010 :</strong>CloudBees a levé 4 millions de dollars. Plus de détails sur le <a href="http://blog.cloudbees.com/2010/11/cloudbees-raises-4m-usd-from-matrix.html">blog de CloudBees</a>.</p>
<p>Devoxx 2010 s&#8217;est tenue toute cette semaine à Anvers. Entre 2 présentations de Brian Goetz, Joshua Bloch ou Mark Reinhold, je suis allé voir quelques personnalités du monde java afin d&#8217;en savoir plus sur leur actualité et leurs impressions.</p>
<h1>Stephan Janssen</h1>
<p><a href="https://blog.infine.com/wp-content/uploads/2010/11/stephanJanssen.jpg" class="fancyboxgroup" rel="gallery-366" title="Stephan Janssen"><img loading="lazy" decoding="async" class="alignleft size-full wp-image-382" title="Stephan Janssen" src="https://blog.infine.com/wp-content/uploads/2010/11/stephanJanssen.jpg" alt="Stephan Janssen picture" width="92" height="114" /></a>Créateur du BeJUG et de <a href="http://www.devoxx.com">Devoxx</a>. Je suis allé le voir pour avoir quelques détails sur l&#8217;organisation d&#8217;un tel évènement.</p>
<p><strong>Bonjour Stephan, peux-tu  présenter Devoxx à ceux qui ne connaissent pas ?</strong><br />
Devoxx est une conférence annuelle qui est organisée par le Java User Group belge. C&#8217;est déjà la neuvième édition. Quelques statistiques : 3000 personnes qui viennent de 40 pays, et cela dure 5 jours à Anvers dans le deuxième plus grand complexe de cinéma d&#8217;Europe.<br />
<span id="more-366"></span><br />
<strong>Comment expliques-tu le succès de Devoxx ?</strong><br />
D&#8217;abord le prix qui est vraiment pas cher, moins de 500€ pour 5 jours. On a aussi des rock stars qui viennent ! On a des personnes comme Joshua Bloch, Romain Guy etc. Le lieu aussi avec des écrans géants est vraiment chouette.</p>
<p><strong>Penses-tu que Devoxx se déroulera ailleurs dans un futur proche ?</strong><br />
L&#8217;autre endroit possible est le Heysel à Bruxelles, mais le problème est que nous devons créer des salles nous-mêmes, ce qui aurait pour conséquence que le prix de l&#8217;entrée doublerait. Je préfère &#8220;less is more&#8221;.</p>
<p><strong>As-tu eu le temps d&#8217;assister à quelques sessions ?</strong><br />
Oui, j&#8217;en ai vu quelques sessions. Ca roule bien, mais heureusement on également <a href="http://parleys.com">parleys</a> où toutes les sessions seront diffusées.</p>
<p><strong>Merci</strong><br />
Merci</p>
<h1>Sacha Labourey</h1>
<p><a href="https://blog.infine.com/wp-content/uploads/2010/11/sachaLabourey.jpg" class="fancyboxgroup" rel="gallery-366" title="Sacha Labourey"><img loading="lazy" decoding="async" class="alignleft size-full wp-image-384" title="Sacha Labourey" src="https://blog.infine.com/wp-content/uploads/2010/11/sachaLabourey.jpg" alt="Sacha Labourey picture" width="87" height="114" /></a>Après une carrière chez JBoss, Sacha a créé une société <a href="http://cloudbees.com/">CloudBees.</a></p>
<p><strong>Bonjour Sacha, quelle est la raison de ta venue à Devoxx cette année ?</strong><br />
Manger des sandwichs, et boire des coca zero principalement ! Mais surtout présenter CloudBees, ma société.</p>
<p><strong>Présente nous CloudBees.</strong><br />
CloudBees est une société qui vit dans les nuages, et qui vise à rendre les développeurs à nouveau en contrôle de l&#8217;informatique, qui a été trop longtemps volé par ces messieurs de l&#8217;IT.<br />
Le désir est de pouvoir faire totalement faire ses développements dans le cloud, ensuite les tests unitaires et le Q&amp;A de manière générale, et ensuite la mise en production. Donc l&#8217;unité sur laquelle on se focalise en tant que développeur sera vraiment l&#8217;application, on ne se soucie plus du tout de l&#8217;IT, on ne soucie plus du tout de virtual machine, de java virutal machine, d&#8217;operation system, de storage, de backup, tout ça doit disparaître. On se focalise sur l&#8217;application, et nous on fera le reste.</p>
<p><strong>CloudBees est uniquement destiné aux applications java ?</strong><br />
Aujourd&#8217;hui on est orienté sur la machine virtuelle java, ça peut être scala, jRuby ou autre chose. Aujourd&#8217;hui la majorité utilise java malgré sa mort annoncé jour après jour, c&#8217;est quand même un écosystème extrêmement saint et fort, mais rien dans l&#8217;infrastructure qu&#8217;on est en train de mettre en place en terme de process, en terme de provisionning et autre ne dépend réellement de java. C&#8217;est suffisamment générique, mais il faut choisir ses guerres, la notre c&#8217;est celle de java pour l&#8217;instant.</p>
<p><strong>Pour terminer, quelles sont tes impressions sur Devoxx 2010 ?</strong><br />
J&#8217;ai pas encore eu le temps d&#8217;aller voir des sessions, mais je retrouve tout à fait l&#8217;esprit JavaPolis de l&#8217;époque, donc ça se passe très bien, et on est à peine mieux respecté qu&#8217;à JavaOne donc ça fait toujours plaisir.</p>
<p><strong>Merci beaucoup Sacha.</strong><br />
Merci !</p>
<h1>Nicolas Leroux</h1>
<p><a href="https://blog.infine.com/wp-content/uploads/2010/11/nicolasleroux.jpg" class="fancyboxgroup" rel="gallery-366" title="Nicolas Leroux"><img loading="lazy" decoding="async" class="alignleft size-full wp-image-383" title="Nicolas Leroux" src="https://blog.infine.com/wp-content/uploads/2010/11/nicolasleroux.jpg" alt="Nicolas Leroux picture" width="114" height="114" /></a>Nicolas est expatrié aux Pays-Bas où il travaille en tant que développeur pour la société Lunatech. Il est également un des contributeurs les plus actifs du framework  <a href="http://www.playframework.org/">Play!</a>. C&#8217;est à ce titre que je suis allé le voir.</p>
<p><strong>Bonjour Nicolas, quelle est la raison de ta venue à Devoxx cette année ?</strong><br />
Pour voir les conférences, faire du networking et aussi pour promouvoir Play! bien sûr.</p>
<p><strong>Il n&#8217;y a pas de session sur Play! cette année, en avez-vous proposé une ?</strong><br />
Nous avions proposé une vraie session Play!, pas dans le BoF. Vue la concurrence acharnée qu&#8217;il y a à Devoxx, on a été refusé, c&#8217;est pas grave, l&#8217;année prochaine on réessaiera.</p>
<p><strong>Play! 1.1 est sorti il y a un peu moins d&#8217;un mois, quelles sont les prochaines étapes ?</strong><br />
Il y en a beaucoup ! Il y a plusieurs axes de travail. Guillaume Bort est en train de travailler sur une partie qui s&#8217;appelle Evolution, qui permet de migrer ses bases de données très facilement.<br />
Personnellement, quand j&#8217;ai cinq minutes, je travaille sur un meilleur binding entre JSON et java. Après il a plein d&#8217;autres choses à faire. Ce que j&#8217;aimerais faire, c&#8217;est un conteneur pour JBoss.<br />
<strong>Comme c&#8217;est actuellement le cas pour Glassfish.</strong><br />
Erwan Loisant est train d&#8217;améliorer les librairies clientes pour faire des requêtes à des web services et Peter Hilton travaille sur la documentation</p>
<p><strong>Y a-t-il une roadmap pour la version 1.2 ?</strong><br />
Elle est pas encore définitive, mais la roadmap peut être consultée sur le site <a href="http://playframework.org">playframework.org</a> qui a un lien sur le bug tracker qui est Lighthouse, et là on peut voir la roadmap.</p>
<p><strong>Merci Nicolas, à l&#8217;année prochaine pour une session officielle de Play!</strong><br />
Ou alors si vous avez l&#8217;occasion d&#8217;aller à Paris pour voir Zenexity, c&#8217;est des petits gars sympas et ils vous expliqueront tout !</p><p>The post <a href="https://blog.infine.com/devoxx-2010-vu-de-linterieur-366">Devoxx 2010, vu de l’intérieur</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.infine.com/devoxx-2010-vu-de-linterieur-366/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Conférence Agile France 2010 : Jour 2</title>
		<link>https://blog.infine.com/conference-agile-france-2010-jour-2-19?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=conference-agile-france-2010-jour-2</link>
					<comments>https://blog.infine.com/conference-agile-france-2010-jour-2-19#respond</comments>
		
		<dc:creator><![CDATA[Florian Boulay]]></dc:creator>
		<pubDate>Sun, 06 Jun 2010 18:00:22 +0000</pubDate>
				<category><![CDATA[Agilité]]></category>
		<category><![CDATA[Conférence]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[conférence]]></category>
		<guid isPermaLink="false">https://blog.infine.com/?p=19</guid>

					<description><![CDATA[<p><span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">9</span> <span class="rt-label rt-postfix">min.</span></span> Cet article fait suite au précédent article sur la conférence Agile France. Je vais ici vous présenter ma 2eme journée. C&#8217;est par un temps indigne d&#8217;un 1er juin que s&#8217;est déroulée la dernière journée de la conférence. Les différentes sessions sont toutes plus intéressantes les unes que les autres, et faire un choix s&#8217;est avéré &#8230;</p>
<p>The post <a href="https://blog.infine.com/conference-agile-france-2010-jour-2-19">Conférence Agile France 2010 : Jour 2</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></description>
										<content:encoded><![CDATA[<span class="rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Temps de lecture : </span> <span class="rt-time">9</span> <span class="rt-label rt-postfix">min.</span></span><p>Cet article fait suite au <a title="Voir le précédent article" href="conference-agile-france-2010-jour-1-12">précédent article sur la conférence Agile France.</a> Je vais ici vous présenter ma 2eme journée.</p>
<p>C&#8217;est par un temps indigne d&#8217;un 1er juin que s&#8217;est déroulée la dernière journée de la conférence. Les différentes sessions sont toutes plus intéressantes les unes que les autres, et faire un choix s&#8217;est avéré difficile. Comme pour le précédent article, je vais détailler une session en particulier.</p>
<h1>9h00 : Self-help for Self-organizing Teams</h1>
<h6>Keynote par Esther Derby</h6>
<h4>Typologie : modèle</h4>
<p>Le propos d&#8217;Esther, au cours de cette keynote, était de montrer que les équipes, pour être heureuse, ont besoin d&#8217;être autogérées.</p>
<p>Esther commence avec un constat. Quels sont les points communs des membres des équipes heureuses ?</p>
<ul>
<li>Ils      ont un but commun</li>
<li>Leur      travail est interdépendant et leur compétences sont complémentaires</li>
<li>L&#8217;équipe      ne doit pas être trop grande. Cinq membres est la valeur idéale</li>
<li>Les      membres ont une histoire commune</li>
</ul>
<p>A partir de ce constat, Esther nous a dressé les moyens à mettre en œuvre afin qu&#8217;une équipe ait assez d&#8217;autonomie pour être heureuse, et donc productive.</p>
<h1>10h00 : Comment écrire du code testable</h1>
<h6>par Florence Chabanois</h6>
<h4>Typologie : bonnes pratiques</h4>
<p>Cette présentation a pour but de nous indiquer les pièges à éviter lors de développements, afin de pouvoir tester unitairement chaque composant développé. Commençons par définir la finalité du test unitaire : il s&#8217;agit de tester chaque composant développé tout en simulant au maximum les conditions qui peuvent être rencontrés sur un environnement de production. Pour pouvoir tester les composants, il faut qu&#8217;ils soient séparables. L&#8217;idée est donc d&#8217;avoir le moins de dépendance possible d&#8217;un composant vers un autre, ou plus simplement d&#8217;une classe vers une autre. Cela s&#8217;appelle, plus généralement, un couplage faible ; contrainte qui est censée être adoptée également entre les applications elles-mêmes.<br />
<span id="more-19"></span><br />
Le TDD est une méthode de développement qui a pris son essor avec la montée en puissance des méthodes agiles. Il s&#8217;agit de bâtir l&#8217;application à partir des tests, qui seront donc développés avant le code métier. Florence va donc nous énumérer les cas typiques que nous pouvons rencontrer afin de suivre 2 principes fondamentaux pour avoir du code testable :</p>
<ul>
<li>Isolation des composants</li>
<li>Simplicité du code</li>
</ul>
<h4>Constructeur cher</h4>
<p>Il faut éviter les constructeurs qui prennent trop de paramètres. C&#8217;est difficile à tester car les dépendances sont trop nombreuses, et l&#8217;intérieur du constructeur est difficilement testable. Pour y remédier, il faut faire de l&#8217;injection de dépendance. Cela permet lors de la construction de l&#8217;objet, d&#8217;y injecter des mocks par exemple. Il faut respecter le principe de responsabilité unique : un objet doit n&#8217;être responsable uniquement que de sa logique métier.</p>
<h4>Instanciation directe</h4>
<p>La création d&#8217;un objet avec un &#8220;new&#8221; entraîne un couplage fort entre deux composants. Les &#8220;new&#8221; doivent être utiliser uniquement dans des factory. Encore une fois, l&#8217;injection de dépendance remédie au problème, en externalisant les dépendances.</p>
<h4>Bloc statique</h4>
<p>Encore une fois, le bloc statique entraîne un couplage fort entre deux composants. Il est donc très difficile de tester un bloc statique. Il est donc préférable de supprimer les blocs statiques et de les remplacer par de l&#8217;injection de dépendance. Le couplage devient ainsi faible.</p>
<h4>Dynastie de classes</h4>
<p>Lors d&#8217;héritage de nombreuses classes, il peut s&#8217;avérer que les classes filles soient difficiles à tester car un couplage fort est fait avec la ou les classes mères. De plus les tests ont tendances à être fait en double. Afin de changer cela, il est préférable d&#8217;utiliser la composition de classes et de limiter l&#8217;héritage au polymorphisme.</p>
<h4>Etats globaux</h4>
<p>Maintenir des états partagés entre instances d&#8217;une même classe est un comportement très difficile à tester. Les singletons et les méthodes statiques sont à éviter autant que possible, car cela induit des dépendances cachées. Il est préférable de les remplacer par de l&#8217;injection de dépendances.</p>
<h4>Annuaire de service</h4>
<p>Un peu comme à chaque problème énuméré, l&#8217;annuaire de service implique des dépendances cachées. Il faut le remplacer par de l&#8217;injection de dépendances au maximum.</p>
<h4>Interrogation de collaborateurs</h4>
<p>Sous ce nom abscons, se cache en fait l&#8217;utilisation de méthodes à partir d&#8217;objets passés en paramètres de méthodes. Cela implique un couplage fort avec les objets passés en paramètres, et donc le test est plus difficile à initialiser. Cette fois la solution n&#8217;est pas l&#8217;injection de dépendance ! En fait il faut utiliser le principe de connaissance minimale (dit Loi de Demeter). En clair, cela signifie remplacer les paramètres d&#8217;une méthode qui sont des objets complexes, par des types primitifs. La méthode est donc très facilement testable, le couplage devient faible et aucune dépendance n&#8217;est à initialiser.</p>
<h4>Classe hyperactive</h4>
<p>Ces classes sont les classes utilitaires. Ce sont les classes qu&#8217;on retrouve dans chaque projet, et qui permettent de gérer les fichiers XML, les logs, la sécurité&#8230;. Elles portent souvent un nom qui se termine par &#8220;utils&#8221; ou &#8220;helper&#8221;. Ce genre de classe est difficile à maintenir, la lisibilité y est souvent mauvaise. Afin de pourvoir tester facilement ces classes, il faut identifier les responsabilités, créer de nouvelles classes, et déplacer les méthodes de la classe fourre-tout vers ces nouvelles classes.</p>
<h4>Méthode trop chargée</h4>
<p>Ces méthodes sont celles que l&#8217;on voie régulièrement et qui font des longueurs qui donne le vertige. Quelques milliers de lignes est certainement trop pour une méthode. Ce genre de méthode est difficile à maintenir, très difficile à tester, et est trop sensible aux évolutions. Pour dégrossir ce genre de méthode, il faut en créer de nouvelles qui prendront en charge une partie du code de la grosse méthode. Les codes seront donc bien plus faciles à faire et à maintenir. Déléguer une partie du travail à d&#8217;autres classes est également faisable.</p>
<h4>Mélange des objets valeurs et des objets services</h4>
<p>Cette fois c&#8217;est clair. Il s&#8217;agit de laisser aux objets valeurs le soin d&#8217;être instancié et de conserver un état. Les objets service doivent toujours être injectés et jamais instanciés. C&#8217;est lui qui crée généralement les objets valeurs.</p>
<h1>11h30 : Bâtir une communauté de développeurs par l&#8217;agile</h1>
<h6>par Bénédicte Taillebois, Matthieu Demay, Jean-Sébastien Hedde et Guillaume Persinette-Gautrez</h6>
<h4>Typologie : retour d&#8217;expérience</h4>
<p>Une équipe d&#8217;Astria est venu nous présenter leur mise en place de process agiles depuis environ 2 ans. Cette présentation est faite par quatre personnes : la directrice des systèmes d&#8217;information, et trois informaticiens (je n&#8217;ai pas trouvé de meilleur terme).</p>
<p>La présentation a été découpée en quatre grandes phase pour décrire les avancées qui ont été apportées à tout le pôle informatique d&#8217;Astria.</p>
<p>Tout a commencé quand deux équipes ont découvertes qu&#8217;elles avaient eu chacune une problématique semblable, et qu&#8217;elles l&#8217;avaient résolu chacune de leur côté. De ce constat, une bibliothèque commune est née. Aujourd&#8217;hui elle existe encore, et contient 50000 lignes de codes. Chacun dans le service informatique peut y contribuer car elle est transverse. De cette bibliothèque est né un espace de discussion, où les gens concernés se réunissent une fois par semaine pour parler de besoins commun dans cette bibliothèque. De plus une règle a été acceptée par tout le monde : la règle des 2 pieds. Dans un espace commun mis en place à cette occasion, lorsque des gens se réunissent pour divers sujets, si quelqu&#8217;un ne se sent pas concerné, il peut partir à tout moment.</p>
<p>Cette première phase a commencé à bâtir de nouvelles méthodes de travail dans le service, mais tout n&#8217;est pas encore parfait notamment au niveau du process de livraison. Dans l&#8217;espace commun, un dashboard est créé permettant de lister les tâches communes en cours. Les livraisons pénibles sont améliorées avec la création d&#8217;un automate de livraison qui s&#8217;impose comme un standard pour toutes les applications. Une classique intégration continue est mise en place.</p>
<p>La troisième phase a été l&#8217;occasion de mettre en place un partage de connaissances. Des dojos hebdomadaires de développement sont mis en place. Afin de communiquer plus efficacement, les flux RSS ont remplacés les mailing list trop polluantes. Enfin, une présentation nommée &#8220;les cafés du jeudi&#8221; est créée ; il s&#8217;agit de faire la publicité sur la machine à café d&#8217;une présentation courte (moins d&#8217;un heure) qui a lieu le jeudi.</p>
<p>La dernière phase a été pour toutes ces personnes impliquées dans l&#8217;améliorer permanente des process et des connaissance, d&#8217;avoir un nouveau souffle. Le point transverse commençant à perdre de son intérêt, une rétrospective y est ajoutée afin de lui redonner de l&#8217;attrait. Un jeu est créé afin de noter les idées proposer par d&#8217;autres personnes.</p>
<h1>12h30 : Tests d&#8217;acceptation de Workflows automatisés avec Concordion</h1>
<h6>par Jean-Baptiste Vilain et Gabriel Le Van</h6>
<h4>Typologie : retour d&#8217;expérience</h4>
<p>Cette session fut l&#8217;occasion de revenir sur la mise en place de l&#8217;outil de tests Concordion par la société. Cette présentation ne comporte aucun détails technique, sa durée étant courte. Concordion est un framework de test qui se greffe au dessus de Junit, pour les tests Java.</p>
<p>Jean-Baptiste et Gabriel utilisent le terme &#8220;tests d&#8217;acceptation&#8221; en tant que traduction de l&#8217;anglais &#8220;acceptance tests&#8221;. Le terme &#8220;tests de validation&#8221; aurait pu fonctionner.</p>
<p>A partir d&#8217;une application dont la recette est difficile à faire, ils ont voulu améliorer la partie tests. Différentes frameworks ont été étudiés, et Concordion a été choisi pour la documentation qu&#8217;il apporte, et le fait qu&#8217;il s&#8217;intégrait bien dans l&#8217;environnement de développement de l&#8217;équipe. L&#8217;équipe pratiquait déjà l&#8217;XP, mais les aucun tests unitaire ou d&#8217;intégration n&#8217;est présent dans l&#8217;application.</p>
<p>Ce qui a été le plus difficile dans la mise en place de Concordion, a été de convaincre toutes les équipes qui sont parties prenantes. Un PoC a été réalisé, et a convaincu une bonne partie de équipes, aussi bien les équipes qui font la recette car elles ont une application a tester est bien plus fiable, que les décideurs car la mise en place des tests n&#8217;est pas un gouffre financier.</p>
<p>Les résultat ont bien entendu été probants. Ce PoC a entraîné une généralisation à l&#8217;ensemble des modules du projet, puis à tous les autres projets de la société.</p>
<p>Il y a quelques points négatifs à cette mise en place. D&#8217;abord les coûts de maintenance des tests représente un effort supplémentaire. D&#8217;autre part, il est difficile pour les personnes dans un environnement non-agile d&#8217;être impliquées dans la maintenance de ces tests (maîtrise d&#8217;ouvrage par exemple). Les points positifs sont plus nombreux que les négatifs. Concordion fournit une documentation à chaud. La collaboration avec l&#8217;équipe de recette a été grandement améliorée. Un domain specific language est en train d&#8217;émerger.</p>
<h1>14h30 : L&#8217;agilité comme facteur de réussite d&#8217;un projet au forfait</h1>
<h6>par Guillaume Leborgne</h6>
<h4>Typologie : retour d&#8217;expérience</h4>
<p>Guillaume nous présente comment l&#8217;agilité a pu faire réussir un projet au forfait. Ce projet consistait à migrer une application existante vers des nouvelles technologies en y intégrant quelques nouvelles fonctionnalité.</p>
<p>Scrum a été mis en place, avec des sprints de deux semaines. Un espace collaboratif a été mis en place entre le client et le prestataire, de type SharePoint. Une intégration continue a été mise en place.</p>
<p>Quelques difficultés ont été rencontrées. Le client a eu du mal à s&#8217;adapter à une approche incrémentale. Lors des premières versions livrées, il était difficile pour le client de comprendre les parties à tester et les parties qui n&#8217;étaient volontairement pas encore développées. Il a fallu trouver le niveau de souplesse adéquat pour respecter les demandes du client, et les contraintes d&#8217;un forfait.</p>
<p>De nombreux points positifs sont au bilan de ce projet. Le client a été très fortement impliqué. Le prestataire a, grâce à l&#8217;espace collaboratif, été très transparent sur l&#8217;état d&#8217;avancement du projet. L&#8217;application a été testable rapidement, et a pu être testé progressivement, ce qui a allégé la recette finale.</p>
<p>Au final, l&#8217;agilité a permis de répondre dans les délais à la migration de cette application. La version finale a été livrée avec seulement deux semaines de retard, sur un projet de plus de 6 mois. Le client est entièrement satisfait, à la fois par le logiciel, et par la méthode de travail apporté par l&#8217;agilité. En production, l&#8217;application a rencontré très peu d&#8217;anomalies.</p>
<h1>15h00 : Le modèle d&#8217;acquisition des compétences de Dreyfus</h1>
<h6>par Emmanuel Hugonnet</h6>
<h4>Typologie : modèle</h4>
<p>Emmanuel nous présente, au cours de cette présentation, le modèle de Dreyfus. Ce modèle catégorise le niveau de compétence qu&#8217;un individu a sur un sujet. Les niveau sont les suivants :</p>
<ul>
<li>Le      novice</li>
<li>Le      débutant avancé</li>
<li>Le      compétent</li>
<li>L&#8217;efficace</li>
<li>L&#8217;expert</li>
</ul>
<p>Toute la présentation s&#8217;est axée sur la description de chacun des niveau et des interactions possibles entre personnes de niveaux différents. Emmanuel nous donne également quelques conseils pour que nous tendions vers l&#8217;expertise, car ce type de compétence est rare et possède pleins d&#8217;avantages, comme le fait d&#8217;être non délocalisable.</p>
<h1>16h30 : Comment être agile dans sa communication</h1>
<h6>par Eric Bezançon</h6>
<h4>Typologie : bonnes pratiques</h4>
<p>Cette courte présentation avait pour but de nous donner des conseils pour communiquer au mieux en faisant de belles présentations. Eric est consultant Agile, Scrum et expert en communication.</p>
<p>Communiquer signifie délivrer un message. Ce qui est difficile lorsque l&#8217;on sait quelque chose, est de communiquer ce savoir. Le secret est donc de se mettre au niveau des gens qui n&#8217;ont pas ce savoir afin d&#8217;adapter le message qu&#8217;on leur transmet.</p>
<p>Une bonne communication se résume en 6 grands principes que je ne vais pas détailler :</p>
<ul>
<li>simplicité</li>
<li>inattendu</li>
<li>concret</li>
<li>crédibilité</li>
<li>émotion</li>
<li>histoire</li>
</ul>
<p>Pour faire une bonne présentation (powerpoint par exemple), il faut être créatif. Afin de la préparer, il faut éteindre son ordinateur, et faire un story board, par exemple avec des post-it. Lors de la construction de la présentation, il faut utiliser des visuels forts, tels que des images, des photos, et peu de textes. Il ne faut pas répéter ce qui est dit à l&#8217;oral.</p>
<h1>17h00 : Le secret de la Rétrospective</h1>
<h6>par Jacques Couvreur et François Bachmann</h6>
<h4>Typologie : bonnes pratiques</h4>
<p>Cette présentation était entièrement axé sur une mise en pratique. La salle a été séparé en 2 groupes, et à l&#8217;aide d&#8217;un jeu de carte, chacun a endossé un rôle sur un projet fictif. Le projet est la mise en place de Noël. Les rôles sont nombreux, tels que le père noël qui n&#8217;a qu&#8217;une envie, faire plaisir aux enfants. Les enfants n&#8217;hésitent pas à demander tout et n&#8217;importe quoi comme cadeau de noël. Les rennes doivent s&#8217;assurer que les cadeaux arrivent à destination et dans les temps. Les nains ont pour tâche la fabrication des cadeaux. Les elfes doivent vérifier la conformité des cadeaux par rapport à ce que les enfant ont demandés, etc.</p>
<p>A travers ces différents rôles, facilement assimilables à ceux que l&#8217;on peut avoir dans un projet informatique, Jacques et François nous ont distillé les meilleures pratiques sur la rétrospective. Un de leur conseil par exemple, est de mettre en place une petite liste d&#8217;actions a effectué à la fin de la rétrospective. Lors de la prochaine rétrospective, il faut voir quel est l&#8217;état de ces tâches. Si rien n&#8217;a été fait, alors il ne faut en ajouter de nouvelles.</p>
<h1>Fin de la conférence</h1>
<p>Conférence très variée, cadre agréable, temps radieux, cette conférence m&#8217;a permis de connaître des domaines auxquels je ne me serai pas intéressé si je n&#8217;étais pas venu. L&#8217;agilité reste le fil conducteur de chaque présentation, et heureusement qu&#8217;il ne s&#8217;agit pas que de présentations de XP ou Scrum !</p>
<p>Je retiendrai sûrement bon nombres d&#8217;idées à appliquer au quotidien chez mon client. Le plus dur n&#8217;est pas de vouloir le faire, ni de se lancer, mais de convaincre une DSI qui n&#8217;est pas habituée aux méthodes agiles, et qui ne souhaite pas vraiment y adhérer. Voilà ce que je cherchais également, des conseils chez des anciens de l&#8217;agilité, qui ont réussi à imposer dans leur projet les méthodes agiles. Nous verrons dans quelques mois si cela a porté ses fruits pour moi.</p>
<h2>Bibliographie</h2>
<p>Pragmatic Programmer : <a href="http://www.pragprog.com/">http://www.pragprog.com/</a></p>
<p>Concordion : <a href="http://www.concordion.org/">http://www.concordion.org/</a></p>
<p>Génération de personnages (pour les présentations par exemple) : <a href="http://www.weeworld.com/">http://www.weeworld.com/</a></p>
<p>Ancienne présentation sur le modèle de Dreyfus : <a href="http://www.slideshare.net/ehsavoie/le-modle-dacquisition-de-comptences-de-dreyfus">http://www.slideshare.net/ehsavoie/le-modle-dacquisition-de-comptences-de-dreyfus</a></p>
<p>Présentation de Florence Chabanois &#8211; Comment écrire du code testable : <a href="http://www.slideshare.net/foucha/comment-crire-du-code-testable?from=ss_embed">http://www.slideshare.net/foucha/comment-crire-du-code-testable?from=ss_embed</a></p><p>The post <a href="https://blog.infine.com/conference-agile-france-2010-jour-2-19">Conférence Agile France 2010 : Jour 2</a> first appeared on <a href="https://blog.infine.com">In Fine - Le Blog</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://blog.infine.com/conference-agile-france-2010-jour-2-19/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
