<?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>Blog d&#039;un ingénieur informaticien parmi d&#039;autres...</title>
	<atom:link href="http://blog.courtine.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.courtine.org</link>
	<description>Blog myBlog = BlogFactory.getWordPressBlog();</description>
	<lastBuildDate>Sun, 15 Jan 2012 15:45:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Maven au pays des proxys</title>
		<link>http://blog.courtine.org/2012/01/15/maven-au-pays-des-proxys/</link>
		<comments>http://blog.courtine.org/2012/01/15/maven-au-pays-des-proxys/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 15:45:19 +0000</pubDate>
		<dc:creator>Benoît Courtine</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Systèmes d'information]]></category>
		<category><![CDATA[Java-JEE]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Proxy]]></category>

		<guid isPermaLink="false">http://blog.courtine.org/?p=942</guid>
		<description><![CDATA[Le problème… Il y a quelques temps, j&#8217;ai eu pour mission de stabiliser et de &#171;&#160;mavenizer&#160;&#187; une application legacy, dont le build était devenu ingérable (dépendances dans divers répertoires, mélanges de scripts shell, Ant,  etc.). Au sujet de la mavenization elle-même, je vous recommande cet article, donnant une méthode fiable permettant de retrouver la version&#8230;]]></description>
			<content:encoded><![CDATA[<h3>Le problème…</h3>
<p>Il y a quelques temps, j&#8217;ai eu pour mission de stabiliser et de &laquo;&nbsp;mavenizer&nbsp;&raquo; une application legacy, dont le build était devenu ingérable (dépendances dans divers répertoires, mélanges de scripts shell, <a href="http://ant.apache.org/">Ant</a>,  etc.).</p>
<p>Au sujet de la mavenization elle-même, je vous recommande <a href="http://blog.loof.fr/2011/01/mavenizer-un-projet.html">cet article</a>, donnant une méthode fiable permettant de retrouver la version exacte des dépendances lorsqu&#8217;elles ne sont pas connues. Je passe cependant rapidement sur cette étape qui n&#8217;est pas le sujet ici. Nous arrivons donc directement au moment où nous avons un fichier &laquo;&nbsp;pom.xml&nbsp;&raquo; convenable, dont nous voulons vérifier le bon fonctionnement pour assurer le packaging de l&#8217;application. Et c&#8217;est là que les choses commencent à se compliquer.</p>
<p>Car ce que j&#8217;ai oublier de préciser, c&#8217;est que cette mission est effectuée pour &laquo;&nbsp;Gros client&nbsp;&raquo;, chez qui les règles de sécurité sont strictes : l&#8217;accès internet se fait uniquement au travers d&#8217;un proxy. Et plus particulièrement <a href="http://blog.ronez.net/?p=708">le modèle PALC</a> avec toutes les options : identification individuelle obligatoire sur ledit proxy, mot de passe à modifier tous les 3 mois, verrouillage du compte après 5 tentatives ratées, etc. Pour <a href="http://maven.apache.org/">Maven</a> qui aime bien &laquo;&nbsp;télécharger l&#8217;univers&nbsp;&raquo;, c&#8217;est problématique.</p>
<p>Petite digression sur une mauvaise surprise découverte lors de cette mission… <a href="http://ubuntu-fr.org/">Ubuntu 11.10</a> n&#8217;est pas du tout adapté au travail dans un environnement utilisant un proxy : il souffre en effet d&#8217;une <a href="https://bugs.launchpad.net/ubuntu/+source/gnome-control-center/+bug/843268">régression empêchant le paramétrage d&#8217;exceptions</a> (pour les serveurs du réseau local).</p>
<h3>Paramétrer le proxy pour Maven</h3>
<p>Maven fournit <a href="http://maven.apache.org/guides/mini/guide-proxies.html">un guide pour paramétrer un proxy</a>. L&#8217;opération consiste à renseigner les paramètres du proxy dans le &laquo;&nbsp;settings.xml&nbsp;&raquo; :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;proxies<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;proxy<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;active<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>true<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/active<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;protocol<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/protocol<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;host<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>palc.grosclient.com<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/host<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;port<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>8080<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/port<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;username<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>user<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/username<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;password<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>password<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/password<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;nonProxyHosts<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/nonProxyHosts<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/proxy<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/proxies<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>Une fois ce paramétrage effectué, les dépôts sont bien résolus et les dépendances téléchargées. Mais il reste un soucis : certains dépôts irréductibles résistent encore… Par exemple le <a href="https://repository.jboss.org/nexus/">dépôt JBoss</a>, ou encore <a href="https://oss.sonatype.org/">Sonatype <acronym title="Open Source Software">OSS</acronym></a>. La cause est vite identifiée : ces dépôts utilisent le protocole &laquo;&nbsp;https&nbsp;&raquo; et non &laquo;&nbsp;http&nbsp;&raquo;.</p>
<p>Qu&#8217;à cela ne tienne : on duplique le bloc &laquo;&nbsp;proxy&nbsp;&raquo; en modifiant le protocole. A ceci près que ça ne marche pas… Maven ne sait utiliser qu&#8217;un seul proxy à la fois. Si on utilise le proxy &laquo;&nbsp;https&nbsp;&raquo;, on pert le &laquo;&nbsp;http&nbsp;&raquo;, et inversement. Peut-être une idée de correction à implémenter pour le <a href="http://www.eventbrite.com/event/2737661419">hackergarten de mercredi prochain</a>…</p>
<p>La seule solution que j&#8217;ai pu trouver à ce jour est de paramétrer les proxys au niveau de la ligne de commande :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">mvn
  -Dhttp.proxyHost=palc.grosclient.com
  -Dhttp.proxyPort=<span style="color: #000000;">8080</span>
  -Dhttp.proxyUser=user
  -Dhttp.proxyPassword=password
  -Dhttps.proxyHost=palc.grosclient.com
  -Dhttps.proxyPort=<span style="color: #000000;">8080</span>
  -Dhttps.proxyUser=user
  -Dhttps.proxyPassword=password
  <span style="color: #c20cb9; font-weight: bold;">install</span></pre></td></tr></table></div>

<p>Il est possible de paramétrer un proxy dans le &laquo;&nbsp;settings.xml&nbsp;&raquo; et le deuxième en ligne de commande mais ce n&#8217;est pas très intuitif. J&#8217;aime autant que tous les paramètres soient au même endroit.</p>
<p>Une fois les paramètres correctement configurés, on peut les pérenniser en les enregistrant dans la variable d&#8217;environnement <strong>MAVEN_OPTS</strong>.</p>
<h3>Utiliser un dépôt Maven interne</h3>
<p>Suite au paramétrage correct des proxys (http et https), Maven peut à nouveau télécharger tout internet… et le build peut fonctionner. Nous pouvons donc aller plus loin et installer un dépôt Maven chez &laquo;&nbsp;Gros client&nbsp;&raquo;, afin d&#8217;y publier les artefacts produits.</p>
<p>Cependant, ce serveur peut également servir à régler autrement notre problème de proxy. Pour cela, il y a un pré-requis : le serveur doit être accessible directement depuis le réseau de développement, et avoir accès à internet (si possible sans proxy). Dans notre cas, c&#8217;est <a href="http://nexus.sonatype.org/">Nexus</a> qui fait office de dépôt Maven (mais la même technique doit fonctionner avec <a href="http://www.jfrog.com/products.php">Artifactory</a> ou autre…). Ensuite :</p>
<ul>
<li>On configure différents dépôts de type &laquo;&nbsp;proxy&nbsp;&raquo; vers chacun des dépôts externes dont on a besoin.</li>
<li>On ajoute tous ces dépôts au dépôt groupe &laquo;&nbsp;public&nbsp;&raquo;.</li>
</ul>
<p>Enfin, nous devons expliquer à Maven qu&#8217;il doit systématiquement utiliser notre serveur interne au lieu de tenter d&#8217;accéder directement aux dépôts externes (<a href="http://search.maven.org/">Maven central</a>, etc.). Pour cela, retour dans &laquo;&nbsp;settings.xml&nbsp;&raquo;, mais cette fois dans le bloc mirrors.  Il suffit d&#8217;expliquer à Maven que tous les dépôts dont ont a besoin ont pour miroir notre serveur interne :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mirrors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mirror<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>nexus.grosclient.com<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Serveur Nexus de Gros client<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://nexus.grosclient.com/content/groups/public<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mirrorOf<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>*<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mirrorOf<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mirror<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/mirrors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>Avec cette configuration, le paramétrage des proxys fait précédemment doit être supprimé (ou une exception doit être ajoutée pour le dépôt interne).</p>
<p>Cette dernière configuration présente plusieurs avantages :</p>
<ul>
<li>L&#8217;ensemble des dépôts susceptibles d&#8217;être utilisés dans les différents projets de l&#8217;entreprise sont configurés de manière centrale, au niveau du dépôt. Cela permet <del>à l&#8217;équipe agile</del> au chef de projet (rappel : nous sommes chez Gros client) de contrôler les dépôts/librairies utilisées sur le projet.</li>
<li>Le premier développeur qui demande une librairie au serveur Nexus va déclencher son téléchargement depuis son dépôt initial. Mais celle-ci sera ensuite mise en cache sur le serveur. Ainsi, les appels suivants (par les autres développeurs) se contenteront d&#8217;effectuer un téléchargement sur le réseau local, avec un gain de temps (voire de bande passante) non négligeable.</li>
</ul>
<div class="tweetmeme_button" style="float: left; margin-left: 10px; margin-right: 20px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.courtine.org%2F2012%2F01%2F15%2Fmaven-au-pays-des-proxys%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.courtine.org%2F2012%2F01%2F15%2Fmaven-au-pays-des-proxys%2F&amp;style=normal&amp;service=bit.ly&amp;service_api=bcourtine%3AR_adaa69f468b94402bc961e78ad01d140&amp;hashtags=Java-JEE,Maven,Proxy&amp;b=2" height="61" width="50" /><br />
			</a>
		</div> <p><a href="http://blog.courtine.org/?flattrss_redirect&amp;id=942&amp;md5=31f5e72cc31fb25fb7b93728d7c99fa2" title="Flattr" target="_blank"><img src="http://blog.courtine.org/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.courtine.org/2012/01/15/maven-au-pays-des-proxys/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=bcourtine&amp;popout=1&amp;url=http%3A%2F%2Fblog.courtine.org%2F2012%2F01%2F15%2Fmaven-au-pays-des-proxys%2F&amp;language=fr_FR&amp;category=text&amp;title=Maven+au+pays+des+proxys&amp;description=Le+probl%C3%A8me%E2%80%A6+Il+y+a+quelques+temps%2C+j%26%238217%3Bai+eu+pour+mission+de+stabiliser+et+de+%26laquo%3B%26nbsp%3Bmavenizer%26nbsp%3B%26raquo%3B+une+application+legacy%2C+dont+le+build+%C3%A9tait+devenu+ing%C3%A9rable+%28d%C3%A9pendances+dans+divers+r%C3%A9pertoires%2C+m%C3%A9langes...&amp;tags=Java-JEE%2CMaven%2CProxy%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Utiliser Java 7 dans Talend Open Studio</title>
		<link>http://blog.courtine.org/2011/10/31/utiliser-java-7-dans-talend-open-studio/</link>
		<comments>http://blog.courtine.org/2011/10/31/utiliser-java-7-dans-talend-open-studio/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 08:32:04 +0000</pubDate>
		<dc:creator>Benoît Courtine</dc:creator>
				<category><![CDATA[Talend]]></category>
		<category><![CDATA[Java7]]></category>
		<category><![CDATA[Talend Open Studio]]></category>

		<guid isPermaLink="false">http://blog.courtine.org/?p=927</guid>
		<description><![CDATA[Il y a quelques temps que je n&#8217;avais pas retouché à Talend Open Studio. Mais le Talend Partner Summit du mois dernier m&#8217;a donné l&#8217;occasion de recroiser des connaissances, et d&#8217;en apprendre un peu plus sur l&#8217;avenir du produit (&#171;&#160;plate-forme unifiée&#160;&#187;, &#171;&#160;big-data avec Hadoop&#171;&#160;, etc.). Et surtout, ce fut une journée qui m&#8217;a donné envie de me replonger&#8230;]]></description>
			<content:encoded><![CDATA[<p>Il y a quelques temps que je n&#8217;avais pas retouché à <a href="http://fr.talend.com/products-data-integration/talend-open-studio.php">Talend Open Studio</a>. Mais le <a href="http://www.talend.com/partner-summit/france/">Talend Partner Summit</a> du mois dernier m&#8217;a donné l&#8217;occasion de recroiser des connaissances, et d&#8217;en apprendre un peu plus sur l&#8217;avenir du produit (&laquo;&nbsp;plate-forme unifiée&nbsp;&raquo;, &laquo;&nbsp;big-data avec <a href="http://hadoop.apache.org/">Hadoop</a>&laquo;&nbsp;, etc.). Et surtout, ce fut une journée qui m&#8217;a donné envie de me replonger un peu dans le produit. En particulier, je me suis posé la question de la possibilité de développer de nouveaux composants en utilisant <a href="http://jdk7.java.net/">Java 7</a>. En particulier l&#8217;<acronym title="Application Programming Interface">API</acronym> <a href="http://blog.developpez.com/adiguba/p8061/java/7-dolphin/nio2-file-system-api/">NIO2</a> qui apporte de nombreuses fonctionnalités qu&#8217;il me semble intéressant d&#8217;exploiter :</p>
<ul>
<li>accès (en lecture et en écriture) à de nouvelles propriétés des fichiers : propriétaire, permissions, gestion des liens symboliques et des fichiers cachés, etc.</li>
<li>surveillance native des évènements (création/modification/suppression d&#8217;un fichier)</li>
<li>plus grande simplicité et meilleures performances lors de l&#8217;accès et du parcours des fichiers avec <a href="http://download.oracle.com/javase/7/docs/api/java/nio/file/Files.html">Files</a></li>
<li>etc.</li>
</ul>
<h3>Configurer Talend Open Studio</h3>
<h4>Lancer Talend Open Studio avec Java 7</h4>
<div>La première étape est évidemment de se procurer et d&#8217;installer le <acronym title="Java Development Kit">JDK</acronym> 7. Une fois celui-ci installé, il faut forcer Talend Open Studio à utiliser celui-ci. Cette étape est nécessaire pour permettre l&#8217;exécution de traitements utilisant du Java 7 au sein du studio. L marche à suivre ne surprendra pas les habitués d&#8217;<a href="http://www.eclipse.org/">Eclipse</a> : il faut modifier le <a href="http://wiki.eclipse.org/Eclipse.ini">fichier ini</a> correspondant à votre programme de lancement à la racine du produit, en lui ajoutant 2 lignes permettant de préciser la <acronym title="Java Virtual Machine">JVM</acronym> de lancement. Dans mon cas (sous <a href="http://ubuntu-fr.org/">Ubuntu</a>), le fichier est <em>TalendOpenStudio-linux-gtk-x86_64.ini </em>:</div>
<div>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #660033;">-vm</span>
<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>jvm<span style="color: #000000; font-weight: bold;">/</span>java-<span style="color: #000000;">7</span>-jdk<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>java</pre></td></tr></table></div>

</div>
<div>Evidemment, tant le nom du fichier que le chemin du <acronym title="Java Development Kit">JDK</acronym> sont à adapter à votre environnement.</div>
<h4>Enregistrer le <acronym title="Java Development Kit">JDK</acronym> 7 dans le studio</h4>
<div>Encore une fois, il s&#8217;agit d&#8217;une étape classique de l&#8217;utilisation d&#8217;Eclipse : il faut se rendre dans les &laquo;&nbsp;Préférences&nbsp;&raquo; du Studio (menu &laquo;&nbsp;Fenêtre &gt; Préférences&nbsp;&raquo;). De là, le menu qui nous intéresse est &laquo;&nbsp;Java &gt; <acronym title="Java Runtime Environment">JRE</acronym> installés&nbsp;&raquo;. Il faut alors ajouter le <acronym title="Java Development Kit">JDK</acronym> 7, et le définir comme étant celui utilisé par défaut :</div>
<div>
<div id="attachment_933" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.courtine.org/wp-content/uploads/2011/10/talend_jvm.png"><img class="size-medium wp-image-933 " title="Configuration Java dans Talend Open Studio" src="http://blog.courtine.org/wp-content/uploads/2011/10/talend_jvm-300x248.png" alt="Configuration Java dans Talend Open Studio" width="300" height="248" /></a><p class="wp-caption-text">Configuration Java dans Talend Open Studio</p></div>
</div>
<div>Au passage, on remarque que dans les préférences &laquo;&nbsp;Java &gt; Compilateur&nbsp;&raquo;, le niveau de compatibilité du compilateur ne va que jusqu&#8217;à la version 1.6. Cela signifie qu&#8217;on ne pourra pas utiliser dans un composant les syntaxes introduites dans Java 7 (<a href="http://download.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html">Try with resources</a>, &laquo;&nbsp;diamond&nbsp;&raquo;, etc.). En revanche, cela n&#8217;interdit pas d&#8217;utiliser les nouvelles classes du <acronym title="Java Development Kit">JDK</acronym> 7, ce qui nous intéresse !</div>
<div>Enfin, avant de quitter les préférences, faisons un détour par &laquo;&nbsp;Java &gt; Style de code &gt; Formateur&nbsp;&raquo;, afin d&#8217;y modifier le style par défaut. En effet, Talend utilise des nom de variables particulièrement longs (car ils contiennent l&#8217;identifiant du composant), tels que <em>tos_count_tMSSqlLastInsertId_1</em>. Aussi, lorsque plusieurs de ces variables sont utilisées dans une même instruction, la limite par défaut de 80 caractère à vite fait de la découper en 3 ou 4 lignes, ce qui est particulièrement pénible à relire.</div>
<div>C&#8217;est pourquoi je recommande vivement de passer cette limite à 120, 160&#8230; <a href="http://blog.piwai.info/2011/08/31/les-ide-et-la-regle-des-80-120/">voire à 1000 lignes</a>. Le code généré n&#8217;en sera que plus facile à relire, pour comprendre ce qui ne va pas.</div>
<h3>Utiliser du Java 7 dans Talend Open Studio</h3>
<p>L&#8217;ensemble des préparatifs étant terminé, il est maintenant possible d&#8217;utiliser les classes de Java 7 dans Talend Open Studio :</p>
<ul>
<li>dans les différents composants permettant d&#8217;écrire du code directement (tJava, tJavaRow, tJavaFlex, etc.).</li>
<li>en créant soit-même de nouveaux composants.</li>
</ul>
<div>Afin de vérifier le bon fonctionnement de cette manipulation, un premier composant a été créé : le <a href="http://talendforge.org/exchange/index.php?eid=417&amp;product=tos&amp;action=view">bcFileProperties</a>. Ce composant dérivé du tFileProperties, ajoute la lecture des droits du fichier ainsi que de son propriétaire. Les sources de ce composant sont comme d&#8217;habitude disponibles sur <a href="https://github.com/bcourtine/Composants-Talend-Open-Studio/tree/Java7">GitHub</a>. D&#8217;autres composants utilisant les optimisations offertes par Java 7 devraient suivre de la même manière (dès que j&#8217;aurai le temps&#8230;).</div>
<div>
<div id="attachment_937" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.courtine.org/wp-content/uploads/2011/10/bcFilePropertiesExecution.png"><img class="size-medium wp-image-937" title="Exécution du composant bcFileProperties" src="http://blog.courtine.org/wp-content/uploads/2011/10/bcFilePropertiesExecution-300x206.png" alt="Exécution du composant bcFileProperties" width="300" height="206" /></a><p class="wp-caption-text">Exécution du composant bcFileProperties</p></div>
</div>
<div class="tweetmeme_button" style="float: left; margin-left: 10px; margin-right: 20px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F10%2F31%2Futiliser-java-7-dans-talend-open-studio%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F10%2F31%2Futiliser-java-7-dans-talend-open-studio%2F&amp;style=normal&amp;service=bit.ly&amp;service_api=bcourtine%3AR_adaa69f468b94402bc961e78ad01d140&amp;hashtags=Java7,Talend+Open+Studio&amp;b=2" height="61" width="50" /><br />
			</a>
		</div> <p><a href="http://blog.courtine.org/?flattrss_redirect&amp;id=927&amp;md5=4b2ab4e1c4606a8395ee7ff55b3f3794" title="Flattr" target="_blank"><img src="http://blog.courtine.org/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.courtine.org/2011/10/31/utiliser-java-7-dans-talend-open-studio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=bcourtine&amp;popout=1&amp;url=http%3A%2F%2Fblog.courtine.org%2F2011%2F10%2F31%2Futiliser-java-7-dans-talend-open-studio%2F&amp;language=fr_FR&amp;category=text&amp;title=Utiliser+Java+7+dans+Talend+Open+Studio&amp;description=Il+y+a+quelques+temps+que+je+n%26%238217%3Bavais+pas+retouch%C3%A9+%C3%A0+Talend+Open+Studio.+Mais%C2%A0le+Talend+Partner+Summit%C2%A0du+mois+dernier+m%26%238217%3Ba+donn%C3%A9%C2%A0l%26%238217%3Boccasion+de+recroiser+des+connaissances%2C+et+d%26%238217%3Ben+apprendre+un...&amp;tags=Java7%2CTalend+Open+Studio%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Sauvegarde automatique de l&#8217;historique d&#8217;un document</title>
		<link>http://blog.courtine.org/2011/09/27/sauvegarde-automatique-de-l-historique-d-un-document/</link>
		<comments>http://blog.courtine.org/2011/09/27/sauvegarde-automatique-de-l-historique-d-un-document/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 20:43:36 +0000</pubDate>
		<dc:creator>Benoît Courtine</dc:creator>
				<category><![CDATA[Systèmes d'information]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Open Office]]></category>

		<guid isPermaLink="false">http://blog.courtine.org/?p=914</guid>
		<description><![CDATA[Il est des semaines où on doit troquer son IDE préféré pour des outils bizarres tels que OpenOffice LibreOffice, Microsoft Office, voire pire… Microsoft Project. Or avec ces outils, on a vite fait de perdre plusieurs heures de travail avec une fausse manipulation. Afin de palier à ce problème, j&#8217;ai mis à contribution un de mes&#8230;]]></description>
			<content:encoded><![CDATA[<p>Il est des semaines où on doit troquer son <acronym title="Integrated Development Environment">IDE</acronym> préféré pour des outils bizarres tels que <del><a href="http://www.openoffice.org/">OpenOffice</a></del> <a href="http://www.libreoffice.org/">LibreOffice</a>, <a href="http://office.microsoft.com/fr-fr/">Microsoft Office</a>, voire pire… <a href="http://www.microsoft.com/france/office/project/">Microsoft Project</a>. Or avec ces outils, on a vite fait de perdre plusieurs heures de travail avec une fausse manipulation. Afin de palier à ce problème, j&#8217;ai mis à contribution un de mes outils préférés : <a href="http://git-scm.com/">git</a>. Il n&#8217;y a pas de raison que les documents ne soient pas versionnés, au même titre que du code. D&#8217;autant plus que le coût de mise en place d&#8217;une telle sauvegarde est très faible :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> init
<span style="color: #c20cb9; font-weight: bold;">git</span> add mondocument
<span style="color: #c20cb9; font-weight: bold;">git</span> commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">'Première sauvegarde de mon document'</span></pre></td></tr></table></div>

<h3>Diff entre deux versions</h3>
<p>En commitant régulièrement son document, on en constitue un historique. Et avec les branches, on peut même le décliner en plusieurs versions. Je n&#8217;ai par contre pas réussi à créer de &laquo;&nbsp;feature branch&nbsp;&raquo; documentaire, la fusion automatique de documents binaires avec git se passant bizarrement assez mal.</p>
<p>L&#8217;autre problème avec des documents binaires, c&#8217;est qu&#8217;ils passent assez mal dans le &laquo;&nbsp;diff&nbsp;&raquo;, ce qui fait perdre à la gestion de configuration une partie de son intérêt. Mais pour ce problème là, il existe une solution. Il suffit d&#8217;avoir un outil permettant d&#8217;afficher un document un mode texte. Dans le cas du format <a href="http://fr.wikipedia.org/wiki/OpenDocument">OpenDocument</a>, on peut par exemple utiliser <a href="http://stosberg.net/odt2txt/">odt2txt</a>.</p>
<p>Il faut ajouter dans <em>.gitconfig</em> le bloc suivant, pour déclarer le convertisseur associé au format odf :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #c20cb9; font-weight: bold;">diff</span> <span style="color: #ff0000;">&quot;odf&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>
    <span style="color: #007800;">textconv</span>=odt2txt</pre></td></tr></table></div>

<p>Enfin, dans le répertoire du dépôt du projet, il faut associé ce convertisseur avec les extensions des fichiers OpenOffice. Ca se passe dans le fichier <em>info/attributes</em> :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">*</span>.odt <span style="color: #007800;">diff</span>=odf
<span style="color: #000000; font-weight: bold;">*</span>.ott <span style="color: #007800;">diff</span>=odf
<span style="color: #666666; font-style: italic;"># idem pour les formats ods, ots, odp et otp</span></pre></td></tr></table></div>

<p>Cette modification effectuée, on récupère la possibilité de calculer le différentiel entre deux commits, et toutes les fonctionnalités associées.</p>
<p>Le seul inconvénient, c&#8217;est qu&#8217;il faut répéter cette opération pour chaque dépôt de documents. Je n&#8217;ai pas trouvé le moyen de définir ces comportements dans la configuration globale de git. Si quelqu&#8217;un a une solution, je suis preneur !</p>
<h3>Automatisation de la sauvegarde</h3>
<p>Afin d&#8217;améliorer un peu le processus, il suffit d&#8217;un petit script shell qui automatise l&#8217;enregistrement du document à intervalles réguliers :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #666666; font-style: italic;"># Intervalle entre deux enregistrements</span>
<span style="color: #007800;">SAVE_PERIOD_IN_SECONDS</span>=<span style="color: #000000;">120</span>
<span style="color: #000000; font-weight: bold;">while</span> :
<span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Autosave : <span style="color: #007800;">$(date)</span>&quot;</span>
    <span style="color: #c20cb9; font-weight: bold;">git</span> commit <span style="color: #660033;">-a</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Autosave <span style="color: #007800;">$(date)</span>&quot;</span>
    <span style="color: #c20cb9; font-weight: bold;">sleep</span> <span style="color: #007800;">$SAVE_PERIOD_IN_SECONDS</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></td></tr></table></div>

<p>Ce script utilise une des particularités intéressantes de git : si le fichier n&#8217;a pas évolué pendant l&#8217;intervalle, le commit n&#8217;est pas effectué. Ainsi, l&#8217;historique des versions du document pourra sauter des enregistrements (si on a oublié d&#8217;enregistrer le document entretemps par exemple).</p>
<p>Pour finir, voici donc le script en action :</p>
<p><div id="attachment_920" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.courtine.org/wp-content/uploads/2011/09/git_autosave.png"><img class="size-medium wp-image-920" title="Sauvegarde automatique de document avec git" src="http://blog.courtine.org/wp-content/uploads/2011/09/git_autosave-300x220.png" alt="Sauvegarde automatique de document avec git" width="300" height="220" /></a><p class="wp-caption-text">Sauvegarde automatique de document avec git</p></div>
<div class="tweetmeme_button" style="float: left; margin-left: 10px; margin-right: 20px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F09%2F27%2Fsauvegarde-automatique-de-l-historique-d-un-document%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F09%2F27%2Fsauvegarde-automatique-de-l-historique-d-un-document%2F&amp;style=normal&amp;service=bit.ly&amp;service_api=bcourtine%3AR_adaa69f468b94402bc961e78ad01d140&amp;hashtags=Git,Open+Office&amp;b=2" height="61" width="50" /><br />
			</a>
		</div> <p><a href="http://blog.courtine.org/?flattrss_redirect&amp;id=914&amp;md5=59092347f849b8002d47312b85a78925" title="Flattr" target="_blank"><img src="http://blog.courtine.org/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.courtine.org/2011/09/27/sauvegarde-automatique-de-l-historique-d-un-document/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=bcourtine&amp;popout=1&amp;url=http%3A%2F%2Fblog.courtine.org%2F2011%2F09%2F27%2Fsauvegarde-automatique-de-l-historique-d-un-document%2F&amp;language=fr_FR&amp;category=text&amp;title=Sauvegarde+automatique+de+l%26%238217%3Bhistorique+d%26%238217%3Bun+document&amp;description=Il+est+des+semaines+o%C3%B9+on+doit+troquer+son+IDE+pr%C3%A9f%C3%A9r%C3%A9+pour+des+outils+bizarres+tels+que+OpenOffice%C2%A0LibreOffice%2C+Microsoft+Office%2C+voire+pire%E2%80%A6+Microsoft+Project.+Or+avec+ces+outils%2C+on+a...&amp;tags=Git%2COpen+Office%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Premiers pas sur CloudBees</title>
		<link>http://blog.courtine.org/2011/07/10/premiers-pas-sur-cloudbees/</link>
		<comments>http://blog.courtine.org/2011/07/10/premiers-pas-sur-cloudbees/#comments</comments>
		<pubDate>Sun, 10 Jul 2011 13:54:21 +0000</pubDate>
		<dc:creator>Benoît Courtine</dc:creator>
				<category><![CDATA[Systèmes d'information]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Cloud Foundry]]></category>
		<category><![CDATA[CloudBees]]></category>
		<category><![CDATA[Java-JEE]]></category>
		<category><![CDATA[Play! framework]]></category>

		<guid isPermaLink="false">http://blog.courtine.org/?p=892</guid>
		<description><![CDATA[Mardi dernier se tenait le traditionnel Paris JUG, recevant Patrick Chanezon venu nous parler du Cloud. Au passage, félicitons l&#8217;organisation qui est passée de JugEvent à EventBrite, beaucoup plus fiable (et qui m&#8217;a permis d&#8217;avoir une des dernières places libérées le jour même de la conférence). Dans la nuit qui a suivi, Olivier et Nicolas ont&#8230;]]></description>
			<content:encoded><![CDATA[<p>Mardi dernier se tenait le traditionnel <a href="http://www.parisjug.org/">Paris <acronym title="Java User Group">JUG</acronym></a>, recevant <a href="http://www.chanezon.com/pat/cv/">Patrick Chanezon</a> venu nous parler du <a href="http://fr.wikipedia.org/wiki/Cloud_computing">Cloud</a>. Au passage, félicitons l&#8217;organisation qui est passée de <a href="http://www.jugevents.org/">JugEvent</a> à <a href="http://www.eventbrite.com/">EventBrite</a>, beaucoup plus fiable (et qui m&#8217;a permis d&#8217;avoir une des dernières places libérées le jour même de la conférence).</p>
<p>Dans la nuit qui a suivi, <a href="http://twitter.com/OlivierCroisier">Olivier</a> et <a href="http://twitter.com/nmartignole">Nicolas</a> ont respectivement publié des excellents comptes-rendus de cette soirée. Merci et félicitations à eux donc :</p>
<ul>
<li><a href="http://thecodersbreakfast.net/index.php?post/2011/07/06/Paris-JUG-%22Cloud%22">Paris <acronym title="Java User Group">JUG</acronym> &laquo;&nbsp;Cloud&nbsp;&raquo;</a></li>
<li><a href="http://www.touilleur-express.fr/2011/07/06/patrick-chanezon-au-parisjug/">Patrick Chanezon au Paris <acronym title="Java User Group">JUG</acronym></a>, <a href="http://www.touilleur-express.fr/2011/07/06/didier-girard-sfeir-creation-de-valeur-et-competitivite-avec-le-cloud/">Didier Girard, SFEIR, Création de valeur et compétitivité avec le Cloud</a>, et <a href="http://www.touilleur-express.fr/2011/07/06/cloudfoundry-presente-par-guillaume-laforge-soiree-patrick-chanezon/">CloudFoundry présenté par Guillaume Laforge, Soirée Patrick Chanezon</a></li>
</ul>
<p>Voici donc, modestement, un petit compte-rendu de tests que j&#8217;ai eu l&#8217;occasion de faire sur deux des plate-formes dont il était question à cette soirée.<br />
<span id="more-892"></span></p>
<h3><a href="http://cloudfoundry.com/">Cloud Foundry</a></h3>
<div id="attachment_896" class="wp-caption alignright" style="width: 131px"><a href="http://blog.courtine.org/wp-content/uploads/2011/07/CloudFoundry_logo_120x80.jpg"><img class="size-full wp-image-896" title="Logo CloudFoundry" src="http://blog.courtine.org/wp-content/uploads/2011/07/CloudFoundry_logo_120x80.jpg" alt="Logo CloudFoundry" width="121" height="83" /></a></dt>
</dl>
</div>
<p>J&#8217;ai déjà eu l&#8217;occasion de parler de mes tests de déploiement d&#8217;une application <a href="http://www.playframework.org/">Play Framework</a> sur cette plate-forme, <a href="http://blog.courtine.org/2011/05/01/application-play-framework-sur-cloud-foundry/">ici</a> et <a href="http://blog.courtine.org/2011/05/05/playframework-et-cloudfoundry-reloaded/">là</a>. C&#8217;est un projet que j&#8217;apprécie beaucoup, pour plusieurs raisons :</p>
<ul>
<li>il est Open Source, ce qui permet de monter une plate-forme de cloud privée (voire un &laquo;&nbsp;micro-cloud&nbsp;&raquo;)</li>
<li>il permet de faire tourner des applications de plusieurs types (<a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Java</a>, <a href="http://www.ruby-lang.org/fr/">Ruby</a>, <a href="http://nodejs.org/">NodeJS</a>…), avec des frameworks associés, et le nombre de technologies supportées sera prochainement élargi (par exemple, la gestion native des applications Play est <a href="https://github.com/cloudfoundry/vcap/pull/80">dans les tuyaux</a>)</li>
<li>il est multi-services (<a href="http://www.mysql.fr/">MySQL</a>, <a href="http://www.mongodb.org/">MongoDB</a>, …)</li>
<li>il n&#8217;y a pas d&#8217;<acronym title="Application Programming Interface">API</acronym> spécifique à Cloud Foundry, ce qui évite de se lier avec la plate-forme au point de ne plus pouvoir en sortir facilement</li>
<li>il n&#8217;est pas dépendant d&#8217;une infrastructure particulière : on peut installer le système sur la couche de virtualisation que l&#8217;on souhaite : <a href="http://www.vmware.com/">VMWare</a>, <a href="http://www.virtualbox.org/">VirtualBox</a>, …</li>
</ul>
<div>Je suis très enthousiaste concernant Cloud Foundry, et c&#8217;est pourquoi j&#8217;ai poursuivi mes tests. En particulier, en découvrant le langage <a href="http://www.scala-lang.org/">Scala</a>, j&#8217;ai déployé (toujours avec Play) un simple <a href="http://playsudoku.cloudfoundry.com/">solveur de Sudoku</a> (dont les sources sont accessibles <a href="https://github.com/bcourtine/Sudoku">sur GitHub</a>). C&#8217;est à ce moment que <a href="http://blog.loof.fr/">Nicolas de Loof</a> m&#8217;a proposé de déployer la même application sur son nouveau protégé, afin de comparer les deux solutions :</div>
<h3><a href="http://www.cloudbees.com/">CloudBees</a></h3>
<div class="mceTemp">
<dl id="attachment_897" class="wp-caption alignright" style="width: 170px;">
<dt class="wp-caption-dt"><a href="http://blog.courtine.org/wp-content/uploads/2011/07/CloudBees_logo_160x60.jpeg"><img class="size-full wp-image-897" title="Logo CloudBees" src="http://blog.courtine.org/wp-content/uploads/2011/07/CloudBees_logo_160x60.jpeg" alt="Logo CloudBees" width="160" height="68" /></a></dt>
</dl>
</div>
<h4>Inscription</h4>
<p>La procédure d&#8217;inscription est un poil plus compliquée que celle de Cloud Foundry (mais en même temps, on peut difficilement faire plus simple que le bouton unique de ce dernier). Rien de bien dramatique cependant : en moins d&#8217;une dizaine de minutes tout compris, on a un compte prêt à l&#8217;emploi. Voici donc mes premières impressions, en essayant de les comparer à ce que j&#8217;ai pu voir sur Cloud Foundry.</p>
<h4>Dev@Cloud</h4>
<p>Avec une application Play Framework, je n&#8217;ai pas vraiment pu tester cette partie. Cependant, j&#8217;espère avoir l&#8217;occasion de le faire prochainement : l&#8217;approche est intéressante ! Elle consiste à pouvoir construire son application et la valider dans les nuages. Le principe est d&#8217;empiler à la demande les services dont on peut avoir besoin autour de l&#8217;intégration continue <a href="http://jenkins-ci.org/">Jenkins</a> : dépôts <a href="http://maven.apache.org/">Maven</a> (<a href="http://archiva.apache.org/">Archiva</a>), tests fonctionnels avec <a href="http://seleniumhq.org/">Selenium</a>, analyse de qualité avec <a href="http://www.sonarsource.com/">Sonar</a>… CloudBees propose même de mettre sa gestion de configuration dans les nuages avec des dépôts <a href="http://git-scm.com/">Git</a> (ou autres dont <a href="http://subversion.tigris.org/">on ne doit pas prononcer le nom</a>). Et la gestion de ces différents services dispose d&#8217;une interface très conviviale :</p>
<div class="mceTemp mceIEcenter">
<dl id="attachment_903" class="wp-caption aligncenter" style="width: 310px;">
<dt class="wp-caption-dt"><a href="http://blog.courtine.org/wp-content/uploads/2011/07/CloudBees_Services.png"><img class="size-medium wp-image-903" title="Chaîne des services CloudBees" src="http://blog.courtine.org/wp-content/uploads/2011/07/CloudBees_Services-300x67.png" alt="Chaîne des services CloudBees" width="300" height="67" /></a><p class="wp-caption-text">Chaîne des services CloudBees</p></div>
<h4 style="text-align: left;">RUN@Cloud</h4>
<p>Passons maintenant à la partie déploiement. Depuis une application Play, la procédure pour monter une application dans le Cloud est très proche de celle de Cloud Foundry : il suffit de configurer et d&#8217;utiliser le <a href="http://www.playframework.org/modules/cloudbees-0.2/home">module dédié</a>, Au moment du déploiement, comme pour Cloud Foundry, l&#8217;application est convertie en archive <acronym title="Web ARchive">WAR</acronym>, puis est chargée sur le Cloud via l&#8217;<acronym title="Application Programming Interface">API</acronym> du service.</p>
<p>30 minutes après le premier échange de tweets avec Nicolas, la même application était <a href="http://playsudoku.bcourtine.cloudbees.net/">en ligne</a> sur CloudBees (avec l&#8217;aide de <a href="http://twitter.com/fsarradin">François</a> pour la correction de quelques bugs de la première version). Entre les versions Cloud Foundry et CloudBees, aucune ligne de code n&#8217;a été modifiée pour permettre le déploiement. Le déploiement est donc aussi simple sur les deux environnements. Et dans les deux cas, on n&#8217;est pas lié par des <acronym title="Application Programming Interface">API</acronym> propriétaires. Le coût de sortie est donc faible.</p>
<p>Un petit avantage va cependant à Cloud Foundry : il gère une liste complète des fichiers déjà déployés (quel que soit l&#8217;utilisateur les ayant mis en ligne), et permet de ne charger que ce qui n&#8217;est pas déjà connu en ligne (soit quelques Ko). Sur CloudBees, il n&#8217;y a pas cette liste globale : le premier chargement nécessite donc le transfert complet des 50 Mo de l&#8217;application. Les déploiement suivants se font par contre bien de façon incrémentale (ouf !).</p>
<h4>Monitoring</h4>
<p>Sur ce point, CloudBees gagne sans aucune discussion possible. Sa console d&#8217;administration est graphiquement très agréable, et permet un monitoring complet de l&#8217;application : requêtes, mémoire, temps de réponse, etc.</p>
<div id="attachment_904" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.courtine.org/wp-content/uploads/2011/07/CloudBees_Console.png"><img class="size-medium wp-image-904" title="Console de monitoring CloudBees" src="http://blog.courtine.org/wp-content/uploads/2011/07/CloudBees_Console-300x159.png" alt="Console de monitoring CloudBees" width="300" height="159" /></a><p class="wp-caption-text">Console de monitoring CloudBees</p></div>
<p>Au niveau de Cloud Foundry, il n&#8217;y a pour le moment quasiment aucune possibilité de monitoring, et uniquement via l&#8217;outil &laquo;&nbsp;vmc&nbsp;&raquo;. Il est ensuite possible de palier à ce manque avec des produits tierces : <a href="http://support.hyperic.com/display/hyperforge/Cloud+Foundry">Hyperic</a>, <a href="http://newrelic.com/">NewRelic</a>, etc.</p>
<p>Mais n&#8217;oublions pas que Cloud Foundry est encore en phase de béta. On ne sait pas encore quel sera le mode de pricing de la version finale, ni quels seront les services associés mais cela m&#8217;étonnerait grandement qu&#8217;aucune solution de monitoring ne soit intégrée à l&#8217;offre commerciale.</p>
<h4>Extensibilité</h4>
<p>Une des choses qui m&#8217;a beaucoup séduit dans Cloud Foundry, c&#8217;est son extensibilité avec la possibilité d&#8217;utiliser les services que l&#8217;on souhaite (type de base de données, etc.). Sur ce point, CloudBees devrait proposer une approche similaire, en proposant des services partenaires. A l&#8217;heure actuelle, ce système de services est en place pour la partie DEV@Cloud, mais je ne sais pas ce qui pourra être rendu disponible sur la partie RUN. L&#8217;avantage est donc à Cloud Foundry pour la partie &laquo;&nbsp;services PaaS disponibles&nbsp;&raquo;.</p>
<h4>Performances</h4>
<p>Ma petite application de test n&#8217;utilise pas de base de données. Je m&#8217;attendais donc à ce qu&#8217;elle tourne de manière identique sur les deux environnements, d&#8217;autant plus qu&#8217;ils utilisent tous les deux des serveurs <a href="http://tomcat.apache.org/">Tomcat</a> pour l&#8217;exécution des applications Java. Or, les tests de monitoring que j&#8217;ai pu effectuer montrent que ce n&#8217;est pas le cas :</p>
<ul>
<li>Sur Cloud Foundry, l&#8217;application ne descend pas sous la barre des 200 Mo de RAM consommés</li>
<li>Sur CloudBees, elle reste aux alentours des 60 Mo de RAM consommés</li>
</ul>
<div>Cette différence peut sans doute s&#8217;expliquer par le fait que le Tomcat de Cloud Foundry est installé &laquo;&nbsp;out of the box&nbsp;&raquo;, alors que celui de CloudBees a été largement customisé.</div>
<h4>Conclusion</h4>
<p>Sur la partie DEV@Cloud, CloudBees n&#8217;a pas de concurrent chez Cloud Foundry (je ne sais d&#8217;ailleurs pas s&#8217;il a un concurrent tout court…).</p>
<div>Pour la partie PaaS, CloudBees est moins &laquo;&nbsp;couteau suisse&nbsp;&raquo; que Cloud Foundry, mais en revanche mieux optimisé sur l&#8217;exécution de programmes Java.</div>
<div>Dans un nombre significatif de cas, mes besoins sont uniquement Java + base relationnelle. Si je dois héberger une telle application dans les nuages, les bonnes performances et les possibilités de monitoring me feraient préférer CloudBees… tout en sachant que si mes besoins évoluent, il n&#8217;y a pas d&#8217;adhérence forte à la plate-forme, et que je pourrai l&#8217;héberger facilement ailleurs.</div>
<div class="tweetmeme_button" style="float: left; margin-left: 10px; margin-right: 20px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F07%2F10%2Fpremiers-pas-sur-cloudbees%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F07%2F10%2Fpremiers-pas-sur-cloudbees%2F&amp;style=normal&amp;service=bit.ly&amp;service_api=bcourtine%3AR_adaa69f468b94402bc961e78ad01d140&amp;hashtags=Cloud+Computing,Cloud+Foundry,CloudBees,Java-JEE,Play%21+framework&amp;b=2" height="61" width="50" /><br />
			</a>
		</div> <p><a href="http://blog.courtine.org/?flattrss_redirect&amp;id=892&amp;md5=e0840d65e56dd6ee682b94a58ffcf14c" title="Flattr" target="_blank"><img src="http://blog.courtine.org/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.courtine.org/2011/07/10/premiers-pas-sur-cloudbees/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=bcourtine&amp;popout=1&amp;url=http%3A%2F%2Fblog.courtine.org%2F2011%2F07%2F10%2Fpremiers-pas-sur-cloudbees%2F&amp;language=fr_FR&amp;category=text&amp;title=Premiers+pas+sur+CloudBees&amp;description=Mardi+dernier+se+tenait+le+traditionnel%C2%A0Paris+JUG%2C+recevant+Patrick+Chanezon+venu+nous+parler+du+Cloud.+Au+passage%2C+f%C3%A9licitons+l%26%238217%3Borganisation+qui+est+pass%C3%A9e+de+JugEvent+%C3%A0+EventBrite%2C+beaucoup+plus+fiable+%28et...&amp;tags=Cloud+Computing%2CCloud+Foundry%2CCloudBees%2CJava-JEE%2CPlay%21+framework%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Retour sur le BreizhCamp</title>
		<link>http://blog.courtine.org/2011/06/23/retour-sur-le-breizhcamp/</link>
		<comments>http://blog.courtine.org/2011/06/23/retour-sur-le-breizhcamp/#comments</comments>
		<pubDate>Thu, 23 Jun 2011 21:47:54 +0000</pubDate>
		<dc:creator>Benoît Courtine</dc:creator>
				<category><![CDATA[Divers]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Communauté]]></category>
		<category><![CDATA[Java-JEE]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[Veille Technologique]]></category>

		<guid isPermaLink="false">http://blog.courtine.org/?p=877</guid>
		<description><![CDATA[Vendredi dernier, j&#8217;ai eu la chance de pouvoir participer au premier BreizhCamp, organisé entre autres par Nicolas de Loof. Cette journée, agrémentée d&#8217;un temps &#171;&#160;breton&#160;&#187;, fût très enrichissante, tant par les conférences elles-mêmes que par les discussions que nous avons pu avoir entre ces sessions. Une des particularité de cette journée était de ne pas&#8230;]]></description>
			<content:encoded><![CDATA[<p>Vendredi dernier, j&#8217;ai eu la chance de pouvoir participer au premier <a href="http://www.breizhcamp.org/">BreizhCamp</a>, organisé entre autres par <a href="http://blog.loof.fr/">Nicolas de Loof</a>. Cette journée, agrémentée d&#8217;un temps &laquo;&nbsp;breton&nbsp;&raquo;, fût très enrichissante, tant par les conférences elles-mêmes que par les discussions que nous avons pu avoir entre ces sessions.</p>
<p>Une des particularité de cette journée était de ne pas tourner qu&#8217;autour de <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Java</a>, mais aussi d&#8217;autres langages (<a href="http://www.python.org/">Python</a>, <a href="http://www.ruby-lang.org/fr/">Ruby</a>, <a href="http://www.microsoft.com/net/">.NET</a>). Autre particularité (par rapport à la <a href="http://www.whatsnextparis.com/">What&#8217;s Next</a> notamment), les thèmes de cette journée étaient moins orienté <em><a href="http://fr.wikipedia.org/wiki/Cloud_computing">Cloud</a></em>, et plus <em><a href="http://nosql-database.org/">NoSQL</a></em>.</p>
<p>Voici un petit résumé des conférences qui m&#8217;ont le plus intéressé :</p>
<p><span id="more-877"></span></p>
<h3>La keynote</h3>
<p>La journée a commencé très fort, avec une keynote de <a href="http://twitter.com/sdouche">Sébastien Douche</a> sur les communautés. Après un rapide historique des communautés internet (Newsgroups, <acronym title="Internet Relay Chat">IRC</acronym>, mailing-list, etc.), il nous explique l&#8217;intérêt des communautés :</p>
<ul>
<li>Trouver de l&#8217;information fiable rapidement, en s&#8217;adressant directement à &laquo;&nbsp;ceux qui savent, qui font, qui réfléchissent&nbsp;&raquo;</li>
<li>Progresser plus rapidement que tout seul</li>
<li>Elargir sa vision des choses, et devenir plus créatif, en échangeant avec des personnes qui font différemment</li>
<li>Se constituer des réseaux d&#8217;amis, où l&#8217;on devient reconnu par son implication</li>
</ul>
<p>Parmi les outils de &laquo;&nbsp;réseautage&nbsp;&raquo;, <a href="http://www.twitter.com/">Twitter</a> est particulièrement intéressant. Contrairement à la plupart des autres réseaux sociaux, il permet d&#8217;avoir deux communautés distinctes : les personnes que l&#8217;on suit et les personnes qui nous suivent.</p>
<p>Faire les choses en communauté, c&#8217;est plus efficace, mais surtout, c&#8217;est plaisant. Alors comment importer ce modèle en entreprise, pour avoir plaisir à travailler 8 heures par jour (au moins) ? Plusieurs pistes, mais difficiles à appliquer par chez nous car opposées au modèle hiérarchique français :</p>
<ul>
<li>Tout d&#8217;abord, permettre l&#8217;accès aux communautés externes (ah… nos chers <a href="http://blog.ronez.net/?p=708">PALC</a> d&#8217;entreprise)</li>
<li>Valoriser l&#8217;initiative, la créativité, la prise de risque</li>
<li>Avoir un modèle de collaboration ouvert, sans mettre de frontières entre les services, et former des équipes multi-disciplinaires communiquant beaucoup (tiens, ça rappelle le <a href="http://en.wikipedia.org/wiki/DevOps">DevOps</a> ça…)</li>
</ul>
<p>Conclusion de cette keynote : <strong>adhérez aux communautés</strong> !</p>
<p>Je partage complètement les principes exposés par Sébastien dans cette keynote : en commençant à participer au <a href="http://www.parisjug.org/">Paris <acronym title="Java User Group">JUG</acronym></a> il y a maintenant plus d&#8217;un an, j&#8217;ai effectivement pu constater tous ces bienfaits !</p>
<h3>Les présentations</h3>
<p>Après cette keynote, 7 conférences se sont enchaînées dans la journée, entrecoupées de discussions et d&#8217;un déjeuner galette/crêpe. Voici la liste des présentations auxquelles j&#8217;ai participé qui m&#8217;ont le plus intéressé :</p>
<h4>Le déploiement continu</h4>
<p><a href="http://cfalguiere.wordpress.com/">Claude Falguière</a> nous a présenté deux retours d&#8217;expérience sur la mise en place du <a href="http://www.slideshare.net/claude.falguiere/deploiement-continu-agileffrance-2011">déploiement continu</a>.</p>
<p>Cette présentation m&#8217;a particulièrement plu, car elle présente bien les étapes d&#8217;amélioration du processus de développement/déploiement, et explique bien l&#8217;intérêt de la mise en place des bonnes pratiques <em>(qu&#8217;on a parfois du mal à défendre auprès de certaines directions)</em> :</p>
<ul>
<li>Les tests (unitaires, d&#8217;intégration, etc.)</li>
<li>Le &laquo;&nbsp;fast-fail&nbsp;&raquo;, lié au tests, permettant de découvrir les problèmes au plus tôt et ainsi de limiter leurs impacts</li>
<li>l&#8217;intérêt d&#8217;avoir un retour au plus tôt des utilisateurs</li>
<li>etc.</li>
</ul>
<h4>Le langage Python</h4>
<p>Après la keynote, Sébastien Douche nous a présenté le langage Python, ou plus exactement pourquoi il aimait ce langage.</p>
<p>Un langage est un univers : il est accompagné de paradigmes, d&#8217;une philosophie, qui incite à coder d&#8217;une manière ou d&#8217;une autre. C&#8217;est cet ensemble qui fait qu&#8217;on aime ou non un langage.</p>
<p>Les avantages du langage Python :</p>
<ul>
<li>concis, mais tout en restant lisible (certains langages ont des syntaxes parfois tellement concises et &laquo;&nbsp;magiques&nbsp;&raquo; qu&#8217;elles en deviennent illisibles)</li>
<li>homogène : le langage pousse les développeurs à faire les choses d&#8217;une certaines façon. On peut essayer de faire autrement, mais on développe alors de façon &laquo;&nbsp;non pythonique&nbsp;&raquo; (en ne respectant pas l&#8217;esprit du langage)</li>
<li>explicite et simple : quand on lit du code Python, on comprend directement ce qu&#8217;il fait (31 mots clés seulement, pour un manuel de référence de 100 pages)</li>
<li>extensible</li>
</ul>
<p>Sans être un langage purement fonctionnel, le Python est un langage <a href="http://en.wikipedia.org/wiki/First-class_function">first class</a> : les méthodes peuvent être passée en paramètres ou être retournées (ce qui manque cruellement au Java, et que j&#8217;apprécie donc particulièrement en <a href="http://www.scala-lang.org/">Scala</a> soit dit en passant).</p>
<p>La présentation se poursuit par une présentation du <a href="http://fr.wikipedia.org/wiki/Duck_typing">duck typing</a>, possible en Python. J&#8217;avoue ne pas être particulièrement par cette possibilité : je préfère un typage plus fort, certes plus contraignant, mais donnant un code plus facilement compréhensible.</p>
<p>Cette présentation n&#8217;a pas été sans quelques trolls, mais il est vrai que les discussions avec Sébastien sur les différents langages étaient particulièrement intéressantes. Il a en particulier pointé plusieurs travers du monde Java, qui sont assez vrais :</p>
<ul>
<li>ce monde est tellement vaste qu&#8217;on a tendance à ne pas trop avoir tendance à regarder ce qui se fait à côté, même si c&#8217;est en train de changer ces derniers temps</li>
<li>les développeurs Java ont tendance à plus se focaliser sur la technique et la &laquo;&nbsp;tuyauterie&nbsp;&raquo; des programmes que sur l&#8217;aspect fonctionnel sur lequel ils travaillent</li>
</ul>
<h4>Les bases de données</h4>
<p>Au cours de cette journée, j&#8217;ai assisté à 3 conférences sur le stockage de données : deux présentations sur l&#8217;écosystème <a href="http://hadoop.apache.org/">Hadoop</a> et sur <a href="http://cassandra.apache.org/">Cassandra</a>, ainsi que la présentation de <a href="http://twitter.com/juliendubois">Julien Dubois</a> sur le choix d&#8217;une solution de stockage. En particulier, j&#8217;ai beaucoup apprécié cette dernière conférence, très didactique autour d&#8217;une présentation des différentes façons de répondre à la problématique suivante, lorsqu&#8217;on commence à avoir de nombreux utilisateurs en même temps :</p>
<ul>
<li>un ensemble d&#8217;évènements</li>
<li>des personnes participant aux évènements, et ayant entre eux des relations d&#8217;amitiés</li>
</ul>
<p>L&#8217;application doit afficher pour chaque évènement auquel l&#8217;utilisateur participe, la liste de ses amis participant à ce même évènement.</p>
<p>L&#8217;approche naïve en <acronym title="Structured Query Language">SQL</acronym>, c&#8217;est une requête composée de deux jointures. Là où ça se corse, c&#8217;est quand la volumétrie et le nombre d&#8217;accès concurrents augmentent…</p>
<p>Julien nous a donc passé en revue un certain nombre de solution (à choisir en fonction du contexte et de ses contraintes : <a href="http://fr.wikipedia.org/wiki/Transaction_informatique">ACID</a> ou non) :</p>
<ul>
<li>Un serveur <acronym title="Structured Query Language">SQL</acronym> traditionnel simple (<a href="http://www.oracle.com/">Oracle</a>)</li>
<li>Un cluster de bases <acronym title="Structured Query Language">SQL</acronym> (master-slave, façon <a href="http://www.mysql.fr/">MySQL</a>)</li>
<li>du <a href="http://www.oracle.com/fr/products/database/options/rac/">Oracle RAC</a> (monnayant quelques bras)</li>
<li>une couche <a href="http://fr.wikipedia.org/wiki/Mapping_objet-relationnel">ORM</a> (<a href="http://www.hibernate.org/">Hibernate</a> par exemple), utilisant les bénéfices des caches de premier et second niveau (<a href="http://ehcache.org/">Ehcache</a>, etc.)</li>
<li>les solutions de cache distribués, qu&#8217;il soient gratuits (<a href="http://memcached.org/">Memcached</a>) ou propriétaires (<a href="http://www.terracotta.org/">Terracotta</a>, <a href="http://www.vmware.com/products/vfabric-gemfire/overview.html">GemFire</a>, etc.)</li>
<li>une solution NoSQL, avec la présentation de Cassandra (qui fait d&#8217;ailleurs partie de <a href="http://blog.ippon.fr/2011/06/15/netty-et-cassandra-en-finale-du-challenge-usi-2011/">la solution</a> avec laquelle Julien et son équipe sont parvenus en finale du <a href="http://sourceforge.net/p/usi2011/home/Challenge%20USI%202011/">challenge</a> de l&#8217;<a href="http://www.universite-du-si.com/">Université du SI</a>.</li>
</ul>
<h3>Epilogue</h3>
<p>Cette journée s&#8217;est terminée par une mise en pratique fort sympathique de la keynote du matin, en communauté :</p>
<div id="attachment_884" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.courtine.org/wp-content/uploads/2011/06/BreizhCamp_bar.jpg"><img class="size-medium wp-image-884" title="Quatrième (voire cinquième) mi-temps" src="http://blog.courtine.org/wp-content/uploads/2011/06/BreizhCamp_bar-300x225.jpg" alt="Quatrième (voire cinquième) mi-temps" width="300" height="225" /></a><p class="wp-caption-text">Quatrième (voire cinquième) mi-temps</p></div>
<p>Prochain grand rendez-vous le 16 septembre pour le <a href="https://sites.google.com/site/jugsummercamp/"><acronym title="Java User Group">JUG</acronym> Summer Camp</a> : et il reste des places !
<div class="tweetmeme_button" style="float: left; margin-left: 10px; margin-right: 20px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F06%2F23%2Fretour-sur-le-breizhcamp%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F06%2F23%2Fretour-sur-le-breizhcamp%2F&amp;style=normal&amp;service=bit.ly&amp;service_api=bcourtine%3AR_adaa69f468b94402bc961e78ad01d140&amp;hashtags=Cloud+Computing,Communaut%C3%A9,Java-JEE,NoSQL,Veille+Technologique&amp;b=2" height="61" width="50" /><br />
			</a>
		</div> <p><a href="http://blog.courtine.org/?flattrss_redirect&amp;id=877&amp;md5=b22afbf5403a7824c9ba93920a50f941" title="Flattr" target="_blank"><img src="http://blog.courtine.org/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.courtine.org/2011/06/23/retour-sur-le-breizhcamp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=bcourtine&amp;popout=1&amp;url=http%3A%2F%2Fblog.courtine.org%2F2011%2F06%2F23%2Fretour-sur-le-breizhcamp%2F&amp;language=fr_FR&amp;category=text&amp;title=Retour+sur+le+BreizhCamp&amp;description=Vendredi+dernier%2C+j%26%238217%3Bai+eu+la+chance+de+pouvoir+participer+au+premier+BreizhCamp%2C+organis%C3%A9+entre+autres+par+Nicolas+de+Loof.+Cette+journ%C3%A9e%2C+agr%C3%A9ment%C3%A9e+d%26%238217%3Bun+temps+%26laquo%3B%26nbsp%3Bbreton%26nbsp%3B%26raquo%3B%2C+f%C3%BBt+tr%C3%A8s+enrichissante%2C+tant+par...&amp;tags=Cloud+Computing%2CCommunaut%C3%A9%2CJava-JEE%2CNoSQL%2CVeille+Technologique%2Cblog" type="text/html" />
	</item>
		<item>
		<title>99 Scala problems : les 22 premiers</title>
		<link>http://blog.courtine.org/2011/06/09/99-scala-problems-les-22-premiers/</link>
		<comments>http://blog.courtine.org/2011/06/09/99-scala-problems-les-22-premiers/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 21:29:50 +0000</pubDate>
		<dc:creator>Benoît Courtine</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Java-JEE]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://blog.courtine.org/?p=863</guid>
		<description><![CDATA[Après quelques articles et tutoriels, ainsi que sur les interactions avec Java, j&#8217;ai commencé mon apprentissage du Scala par les 99 Scala problems. Avant de me lancer dans la résolution des problèmes en question, et en application des bonnes pratiques du TDD, j&#8217;ai écrit les signatures des méthodes, et les tests associés à ces 22 problèmes. Si&#8230;]]></description>
			<content:encoded><![CDATA[<p>Après quelques articles et tutoriels, ainsi que <a href="http://blog.courtine.org/2011/05/24/premiers-pas-en-scala/">quelques tests</a> sur les interactions avec <a href="http://www.java.com/fr/">Java</a>, j&#8217;ai commencé mon apprentissage du <a href="http://www.scala-lang.org/">Scala</a> par les <a href="http://aperiodic.net/phil/scala/s-99/">99 Scala problems</a>.</p>
<p>Avant de me lancer dans la résolution des problèmes en question, et en application des bonnes pratiques du <a href="http://fr.wikipedia.org/wiki/Test_Driven_Development">TDD</a>, j&#8217;ai écrit les signatures des méthodes, et les tests associés à ces 22 problèmes. Si vous voulez vous lancer, je vous épargne cette première étape : vous pouvez télécharger directement <a href="http://blog.courtine.org/wp-content/uploads/2011/06/99_scala_pbs.tar.gz">ce squelette</a>.</p>
<p>Vous pourrez vérifier que les 22 tests échouent. Ces tests sont cependant rudimentaires, et les faire passer au vert ne garantira pas que vous avez la bonne solution (même si c&#8217;est encourageant).</p>
<p>D&#8217;autres personnes se sont lancées avant moi dans la résolution de ces problèmes. Comme il est toujours intéressant de comparer les différentes approches, en voici quelques unes (en plus des solutions du site original) :</p>
<ul>
<li><a href="http://99problemsinscala.wordpress.com/">http://99problemsinscala.wordpress.com/</a></li>
<li><a href="http://gabrielsw.blogspot.com/2009/04/my-take-on-99-problems-in-scala-first.html">http://gabrielsw.blogspot.com/2009/04/my-take-on-99-problems-in-scala-first.html</a></li>
</ul>
<p><span id="more-863"></span></p>
<p>Voici maintenant mes propositions pour chacun de ces problèmes, que vous pourrez tester, critiquer, optimiser. Par rapport à celles proposées sur le site officiel, elles sont sans doute moins optimisées, et plus complexes. Mais découvrant le langage, je n&#8217;ai pas eu le réflexe d&#8217;utiliser les méthodes natives de manipulation des listes avancées (<em>flatMap</em>, <em>takeWhile</em>, <em>dropWhile</em>, etc.), qui permettent souvent de s&#8217;en sortir d&#8217;une jolie manière.<br />
<strong>P01 : trouver le dernier élément d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> last<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> E <span style="color: #000080;">=</span>
    ls <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> Nil <span style="color: #000080;">=&gt;</span> <span style="color: #0000ff; font-weight: bold;">throw</span> <span style="color: #0000ff; font-weight: bold;">new</span> NoSuchElementException
        <span style="color: #0000ff; font-weight: bold;">case</span> head <span style="color: #000080;">::</span> Nil <span style="color: #000080;">=&gt;</span> head
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #000080;">_</span> <span style="color: #000080;">::</span> tail <span style="color: #000080;">=&gt;</span> last<span style="color: #F78811;">&#40;</span>tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P02 : trouver l&#8217;avant-dernier élément d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> penultimate<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> E <span style="color: #000080;">=</span>
    ls <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> head <span style="color: #000080;">::</span> lastElement <span style="color: #000080;">::</span> Nil <span style="color: #000080;">=&gt;</span> head
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #000080;">_</span> <span style="color: #000080;">::</span> tail <span style="color: #000080;">=&gt;</span> penultimate<span style="color: #F78811;">&#40;</span>tail<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> Nil <span style="color: #000080;">=&gt;</span> <span style="color: #0000ff; font-weight: bold;">throw</span> <span style="color: #0000ff; font-weight: bold;">new</span> NoSuchElementException
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P03 : trouver un élément donné d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> nth<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span> Int, ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> E <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span>n, ls<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> <span style="color: #0000ff; font-weight: bold;">throw</span> <span style="color: #0000ff; font-weight: bold;">new</span> NoSuchElementException
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">0</span>, head <span style="color: #000080;">::</span> <span style="color: #000080;">_</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> head
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>m, <span style="color: #000080;">_</span> <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> nth<span style="color: #F78811;">&#40;</span>m - <span style="color: #F78811;">1</span>, tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P04 : trouver la taille d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> length<span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>Any<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Int <span style="color: #000080;">=</span>
    ls <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> Nil <span style="color: #000080;">=&gt;</span> <span style="color: #F78811;">0</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #000080;">_</span> <span style="color: #000080;">::</span> tail <span style="color: #000080;">=&gt;</span> <span style="color: #F78811;">1</span> + length<span style="color: #F78811;">&#40;</span>tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P05 : inverser une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> reverse<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    reverseRec<span style="color: #F78811;">&#40;</span>ls, Nil<span style="color: #F78811;">&#41;</span>
&nbsp;
<span style="color: #0000ff; font-weight: bold;">private</span> <span style="color: #0000ff; font-weight: bold;">def</span> reverseRec<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>input<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span>, result<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span>input, result<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>Nil, res<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> res
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>head <span style="color: #000080;">::</span> tail, res<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> reverseRec<span style="color: #F78811;">&#40;</span>tail, head <span style="color: #000080;">::</span> res<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P06 : la liste est-elle un palindrome ?</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> isPalindrome<span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>Any<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Boolean <span style="color: #000080;">=</span>
    <span style="color: #008000; font-style: italic;">// En Scala, '==' correspond à la méthode Java 'equals()'.</span>
    <span style="color: #F78811;">&#40;</span>ls <span style="color: #000080;">==</span> reverse<span style="color: #F78811;">&#40;</span>ls<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span></pre></td></tr></table></div>

<p><strong>P07 : &laquo;&nbsp;aplanir&nbsp;&raquo; une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> flatten<span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>Any<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>Any<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    ls <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> Nil <span style="color: #000080;">=&gt;</span> Nil
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>head<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span><span style="color: #000080;">_</span><span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">::</span> tail <span style="color: #000080;">=&gt;</span> flatten<span style="color: #F78811;">&#40;</span>head<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">:::</span> flatten<span style="color: #F78811;">&#40;</span>tail<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> head <span style="color: #000080;">::</span> tail <span style="color: #000080;">=&gt;</span> head <span style="color: #000080;">::</span> flatten<span style="color: #F78811;">&#40;</span>tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P08 éliminer les doublons successifs d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> compress<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    ls <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> Nil <span style="color: #000080;">=&gt;</span> Nil
        <span style="color: #0000ff; font-weight: bold;">case</span> h1 <span style="color: #000080;">::</span> h2 <span style="color: #000080;">::</span> tail <span style="color: #0000ff; font-weight: bold;">if</span> <span style="color: #F78811;">&#40;</span>h1 <span style="color: #000080;">==</span> h2<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> compress<span style="color: #F78811;">&#40;</span>h2 <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> h1 <span style="color: #000080;">::</span> tail <span style="color: #000080;">=&gt;</span> h1 <span style="color: #000080;">::</span> compress<span style="color: #F78811;">&#40;</span>tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P09 : &laquo;&nbsp;compacter&nbsp;&raquo; une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> pack<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    packRec<span style="color: #F78811;">&#40;</span>Nil, Nil, ls<span style="color: #F78811;">&#41;</span>
&nbsp;
<span style="color: #0000ff; font-weight: bold;">private</span> <span style="color: #0000ff; font-weight: bold;">def</span> packRec<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>accu<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span>, result<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#93;</span>, ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span>accu, result, ls<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>Nil, res, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> res
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>acc, res, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> res <span style="color: #000080;">:::</span> List<span style="color: #F78811;">&#40;</span>acc<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>Nil, res, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> packRec<span style="color: #F78811;">&#40;</span>List<span style="color: #F78811;">&#40;</span>head<span style="color: #F78811;">&#41;</span>, res, tail<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>accHead <span style="color: #000080;">::</span> accTail, res, lsHead <span style="color: #000080;">::</span> lsTail<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">if</span> <span style="color: #F78811;">&#40;</span>accHead <span style="color: #000080;">==</span> lsHead<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> packRec<span style="color: #F78811;">&#40;</span>lsHead <span style="color: #000080;">::</span> accHead <span style="color: #000080;">::</span> accTail, res, lsTail<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>accHead <span style="color: #000080;">::</span> accTail, res, lsHead <span style="color: #000080;">::</span> lsTail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> packRec<span style="color: #F78811;">&#40;</span>List<span style="color: #F78811;">&#40;</span>lsHead<span style="color: #F78811;">&#41;</span>, res <span style="color: #000080;">:::</span> List<span style="color: #F78811;">&#40;</span>accHead <span style="color: #000080;">::</span> accTail<span style="color: #F78811;">&#41;</span>, lsTail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P10 : &laquo;&nbsp;encodage&nbsp;&raquo; d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> encode<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span><span style="color: #F78811;">&#40;</span>Int, E<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span>
    pack<span style="color: #F78811;">&#40;</span>ls<span style="color: #F78811;">&#41;</span> map <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#40;</span>l<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> <span style="color: #F78811;">&#40;</span>length<span style="color: #F78811;">&#40;</span>l<span style="color: #F78811;">&#41;</span>, l.<span style="color: #000000;">head</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>
<span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P11 : encodage modifié d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> encodeModified<span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>Any<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>Any<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    pack<span style="color: #F78811;">&#40;</span>ls<span style="color: #F78811;">&#41;</span> map <span style="color: #F78811;">&#40;</span>
            <span style="color: #F78811;">&#40;</span>l<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span><span style="color: #000080;">_</span><span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> length<span style="color: #F78811;">&#40;</span>l<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
                <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">1</span> <span style="color: #000080;">=&gt;</span> l.<span style="color: #000000;">head</span>
                <span style="color: #0000ff; font-weight: bold;">case</span> n <span style="color: #000080;">=&gt;</span> <span style="color: #F78811;">&#40;</span>n, l.<span style="color: #000000;">head</span><span style="color: #F78811;">&#41;</span>
            <span style="color: #F78811;">&#125;</span>
    <span style="color: #F78811;">&#41;</span></pre></td></tr></table></div>

<p><strong>P12 : &laquo;&nbsp;décodage&nbsp;&raquo; d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> decode<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span><span style="color: #F78811;">&#40;</span>Int, E<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    ls <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> Nil <span style="color: #000080;">=&gt;</span> Nil
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>n, elem<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">::</span> tail <span style="color: #000080;">=&gt;</span> decodeRec<span style="color: #F78811;">&#40;</span>n, elem, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">:::</span> decode<span style="color: #F78811;">&#40;</span>tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span>
&nbsp;
<span style="color: #0000ff; font-weight: bold;">private</span> <span style="color: #0000ff; font-weight: bold;">def</span> decodeRec<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span> Int, elem<span style="color: #000080;">:</span> E, result<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    n <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">0</span> <span style="color: #000080;">=&gt;</span> result
        <span style="color: #0000ff; font-weight: bold;">case</span> m <span style="color: #000080;">=&gt;</span> decodeRec<span style="color: #F78811;">&#40;</span>m - <span style="color: #F78811;">1</span>, elem, elem <span style="color: #000080;">::</span> result<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P13 : encodage direct d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> encodeDirect<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span><span style="color: #F78811;">&#40;</span>Int, E<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    ls <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> Nil <span style="color: #000080;">=&gt;</span> List<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> head <span style="color: #000080;">::</span> tail <span style="color: #000080;">=&gt;</span> encodeDirectRec<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">1</span>, head, List<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span>, tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span>
&nbsp;
<span style="color: #0000ff; font-weight: bold;">private</span> <span style="color: #0000ff; font-weight: bold;">def</span> encodeDirectRec<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>nb<span style="color: #000080;">:</span> Int, elem<span style="color: #000080;">:</span> E, result<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span><span style="color: #F78811;">&#40;</span>Int, E<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#93;</span>, ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span><span style="color: #F78811;">&#40;</span>Int, E<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span>nb, elem, result, ls<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">0</span>, <span style="color: #000080;">_</span>, res, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> res
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>n, el, res, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> res <span style="color: #000080;">:::</span> List<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#40;</span>n, el<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">0</span>, <span style="color: #000080;">_</span>, res, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> encodeDirectRec<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">1</span>, head, res, tail<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>n, el, res, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">if</span> <span style="color: #F78811;">&#40;</span>el <span style="color: #000080;">==</span> head<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> encodeDirectRec<span style="color: #F78811;">&#40;</span>n+<span style="color: #F78811;">1</span>, el, res, tail<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>n, el, res, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> encodeDirectRec<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">1</span>, head, res <span style="color: #000080;">:::</span> List<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#40;</span>n, el<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>, tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P14 : dupliquer chaque élément d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> duplicate<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    ls <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> Nil <span style="color: #000080;">=&gt;</span> Nil
        <span style="color: #0000ff; font-weight: bold;">case</span> head <span style="color: #000080;">::</span> tail <span style="color: #000080;">=&gt;</span> head <span style="color: #000080;">::</span> head <span style="color: #000080;">::</span> duplicate<span style="color: #F78811;">&#40;</span>tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P15 : dupliquer N fois chaque élément d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> duplicateN<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span> Int, ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    duplicateNRec<span style="color: #F78811;">&#40;</span>n, n, ls<span style="color: #F78811;">&#41;</span>
&nbsp;
<span style="color: #0000ff; font-weight: bold;">private</span> <span style="color: #0000ff; font-weight: bold;">def</span> duplicateNRec<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span> Int, compt<span style="color: #000080;">:</span> Int, ls<span style="color: #000080;">:</span>List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span>compt, ls<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> Nil
        <span style="color: #008000; font-style: italic;">// Passage à l'élément suivant</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">0</span>, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> duplicateNRec<span style="color: #F78811;">&#40;</span>n, n, tail<span style="color: #F78811;">&#41;</span>
        <span style="color: #008000; font-style: italic;">// Boucle sur l'élément 'head' tant qu'il doit être dupliqué</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>cpt, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> head <span style="color: #000080;">::</span> duplicateNRec<span style="color: #F78811;">&#40;</span>n, cpt-<span style="color: #F78811;">1</span>, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span>
&nbsp;
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P16 : supprimer un élément tous les N d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> drop<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span> Int, ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    dropRec<span style="color: #F78811;">&#40;</span>n, <span style="color: #F78811;">1</span>, ls<span style="color: #F78811;">&#41;</span>
&nbsp;
<span style="color: #0000ff; font-weight: bold;">private</span> <span style="color: #0000ff; font-weight: bold;">def</span> dropRec<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span> Int, compt<span style="color: #000080;">:</span> Int, ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span>compt, ls<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> Nil
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>cpt, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">if</span> <span style="color: #F78811;">&#40;</span>cpt <span style="color: #000080;">==</span> n<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> dropRec<span style="color: #F78811;">&#40;</span>n, <span style="color: #F78811;">1</span>, tail<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>cpt, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> head <span style="color: #000080;">::</span> dropRec<span style="color: #F78811;">&#40;</span>n, cpt+<span style="color: #F78811;">1</span>, tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P17 : diviser une liste en deux sous-listes</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> split<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span> Int, ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> <span style="color: #F78811;">&#40;</span>List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span>, List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span>
    splitRec<span style="color: #F78811;">&#40;</span>n, Nil, ls<span style="color: #F78811;">&#41;</span>
&nbsp;
<span style="color: #0000ff; font-weight: bold;">private</span> <span style="color: #0000ff; font-weight: bold;">def</span> splitRec<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span> Int, left<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span>, right<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> <span style="color: #F78811;">&#40;</span>List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span>, List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span>n, right<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">0</span>, <span style="color: #000080;">_</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> <span style="color: #F78811;">&#40;</span>left, right<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> <span style="color: #0000ff; font-weight: bold;">throw</span> <span style="color: #0000ff; font-weight: bold;">new</span> NoSuchElementException
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>nb, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> splitRec<span style="color: #F78811;">&#40;</span>nb-<span style="color: #F78811;">1</span>, left <span style="color: #000080;">:::</span> List<span style="color: #F78811;">&#40;</span>head<span style="color: #F78811;">&#41;</span>, tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P18 : extraire les éléments M à N d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> slice<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>start<span style="color: #000080;">:</span> Int, end<span style="color: #000080;">:</span> Int, ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span>start, end, ls<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">0</span>, <span style="color: #F78811;">0</span>, <span style="color: #000080;">_</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> Nil
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>, <span style="color: #000080;">_</span>, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> <span style="color: #0000ff; font-weight: bold;">throw</span> <span style="color: #0000ff; font-weight: bold;">new</span> NoSuchElementException
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">0</span>, n, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> head <span style="color: #000080;">::</span> slice<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">0</span>, n-<span style="color: #F78811;">1</span>, tail<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>m, n, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> slice<span style="color: #F78811;">&#40;</span>m-<span style="color: #F78811;">1</span>, n-<span style="color: #F78811;">1</span>, tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P19 : permuter les positions des éléments d&#8217;une liste à gauche</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> rotate<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span> Int, ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span>n, ls<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> Nil
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">0</span>, lst<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> lst
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">if</span> <span style="color: #F78811;">&#40;</span>n <span style="color: #000080;">&gt;</span> <span style="color: #F78811;">0</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> rotate<span style="color: #F78811;">&#40;</span>n-<span style="color: #F78811;">1</span>, tail <span style="color: #000080;">:::</span> List<span style="color: #F78811;">&#40;</span>head<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>, <span style="color: #000080;">_</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> rotate<span style="color: #F78811;">&#40;</span>length<span style="color: #F78811;">&#40;</span>ls<span style="color: #F78811;">&#41;</span> + n, ls<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P20 : supprimer un élément d&#8217;une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> removeAt<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span> Int, ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> <span style="color: #F78811;">&#40;</span>List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span>, E<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span>
    removeAtRec<span style="color: #F78811;">&#40;</span>n, Nil, ls<span style="color: #F78811;">&#41;</span>
&nbsp;
<span style="color: #0000ff; font-weight: bold;">private</span> <span style="color: #0000ff; font-weight: bold;">def</span> removeAtRec<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>n<span style="color: #000080;">:</span> Int, start<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span>, end<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> <span style="color: #F78811;">&#40;</span>List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span>, E<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span>n, end<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> <span style="color: #0000ff; font-weight: bold;">throw</span> <span style="color: #0000ff; font-weight: bold;">new</span> NoSuchElementException
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">0</span>, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> <span style="color: #F78811;">&#40;</span>start <span style="color: #000080;">:::</span> tail, head<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>m, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> removeAtRec<span style="color: #F78811;">&#40;</span>m-<span style="color: #F78811;">1</span>, start <span style="color: #000080;">:::</span> List<span style="color: #F78811;">&#40;</span>head<span style="color: #F78811;">&#41;</span>, tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P21 : insérer un élément dans une liste</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> insertAt<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>elem<span style="color: #000080;">:</span> E, pos<span style="color: #000080;">:</span> Int, ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>E<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span>pos, ls<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">0</span>, lst<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> elem <span style="color: #000080;">::</span> lst
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>, Nil<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> <span style="color: #0000ff; font-weight: bold;">throw</span> <span style="color: #0000ff; font-weight: bold;">new</span> NoSuchElementException
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>, head <span style="color: #000080;">::</span> tail<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> head <span style="color: #000080;">::</span> insertAt<span style="color: #F78811;">&#40;</span>elem, pos-<span style="color: #F78811;">1</span>, tail<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p><strong>P22 : créer une liste contenant tous les entiers d&#8217;un intervalle donné</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> range<span style="color: #F78811;">&#40;</span>start<span style="color: #000080;">:</span> Int, end<span style="color: #000080;">:</span> Int<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>Int<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span>start, end<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>s, e<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">if</span> <span style="color: #F78811;">&#40;</span>e <span style="color: #000080;">&lt;</span> s<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> Nil
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span>s, e<span style="color: #F78811;">&#41;</span> <span style="color: #0000ff; font-weight: bold;">if</span> <span style="color: #F78811;">&#40;</span>s <span style="color: #000080;">==</span> e<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> List<span style="color: #F78811;">&#40;</span>s<span style="color: #F78811;">&#41;</span>
        <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>, <span style="color: #000080;">_</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> start <span style="color: #000080;">::</span> range<span style="color: #F78811;">&#40;</span>start+<span style="color: #F78811;">1</span>, end<span style="color: #F78811;">&#41;</span>
    <span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<div class="tweetmeme_button" style="float: left; margin-left: 10px; margin-right: 20px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F06%2F09%2F99-scala-problems-les-22-premiers%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F06%2F09%2F99-scala-problems-les-22-premiers%2F&amp;style=normal&amp;service=bit.ly&amp;service_api=bcourtine%3AR_adaa69f468b94402bc961e78ad01d140&amp;hashtags=Java-JEE,Scala,TDD&amp;b=2" height="61" width="50" /><br />
			</a>
		</div> <p><a href="http://blog.courtine.org/?flattrss_redirect&amp;id=863&amp;md5=284af1df2c2f4d113c69d861ce1116b1" title="Flattr" target="_blank"><img src="http://blog.courtine.org/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.courtine.org/2011/06/09/99-scala-problems-les-22-premiers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=bcourtine&amp;popout=1&amp;url=http%3A%2F%2Fblog.courtine.org%2F2011%2F06%2F09%2F99-scala-problems-les-22-premiers%2F&amp;language=fr_FR&amp;category=text&amp;title=99+Scala+problems+%3A+les+22+premiers&amp;description=Apr%C3%A8s+quelques+articles+et+tutoriels%2C+ainsi+que+sur+les%C2%A0interactions%C2%A0avec+Java%2C+j%26%238217%3Bai+commenc%C3%A9+mon+apprentissage+du+Scala+par+les+99+Scala+problems.+Avant+de+me+lancer+dans+la+r%C3%A9solution+des+probl%C3%A8mes...&amp;tags=Java-JEE%2CScala%2CTDD%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Mettre en place un workflow git</title>
		<link>http://blog.courtine.org/2011/06/02/mettre-en-place-un-workflow-git/</link>
		<comments>http://blog.courtine.org/2011/06/02/mettre-en-place-un-workflow-git/#comments</comments>
		<pubDate>Thu, 02 Jun 2011 16:27:42 +0000</pubDate>
		<dc:creator>Benoît Courtine</dc:creator>
				<category><![CDATA[Systèmes d'information]]></category>
		<category><![CDATA[DVCS]]></category>
		<category><![CDATA[Gestionnaire de configuration]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[SI]]></category>
		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://blog.courtine.org/?p=834</guid>
		<description><![CDATA[Si vous avez été à une ou deux présentations de git, vous avez sans doute déjà vu ce diagramme (ou un équivalent). Après avoir un peu pratiqué git, ce genre de workflow devient naturel, et est particulièrement appréciable : les fonctionnalités ont chacune leur branche dédiée : la lecture de son historique n&#8217;est donc pas&#8230;]]></description>
			<content:encoded><![CDATA[<p>Si vous avez été à une ou deux présentations de <a href="http://git-scm.com/">git</a>, vous avez sans doute déjà vu <a href="http://nvie.com/posts/a-successful-git-branching-model/">ce diagramme</a> (ou un équivalent).</p>
<p>Après avoir un peu pratiqué git, ce genre de workflow devient naturel, et est particulièrement appréciable :</p>
<ul>
<li>les fonctionnalités ont chacune leur branche dédiée : la lecture de son historique n&#8217;est donc pas gêné par le reste des développements</li>
<li>les livraisons peuvent être préparées sans empêcher les personnes qui travaillent sur les futures fonctionnalités de partager leur travail</li>
<li>etc.</li>
</ul>
<p>Voila pour la théorie : sur le papier, ça laisse absolument rêveur ! Mais dans la pratique, tout ne fonctionne pas aussi bien, surtout au début. Et c&#8217;est là que commence mon retour d&#8217;expérience sur la mise en place de ce workflow.</p>
<p><span id="more-834"></span></p>
<h3>Git est un outil complexe</h3>
<p>Lorsque l&#8217;on met git en place avec une équipe qui avait l&#8217;habitude de travailler avec <a href="http://subversion.tigris.org/"><acronym title="Subversion">SVN</acronym></a>, on ne peut pas s&#8217;attendre à ce qu&#8217;un tel workflow soit mis en place du jour au lendemain : il faut d&#8217;abord commencer par apprendre à l&#8217;équipe les bases de l&#8217;utilisation de git. Car si c&#8217;est un outil extrêmement puissant, il ne faut pas perdre de vue qu&#8217;il est aussi objectivement beaucoup plus complexe à utiliser. Il n&#8217;y a qu&#8217;à vérifier sur ce petit <a href="http://www.ndpsoftware.com/git-cheatsheet.html">pense-bête</a> des commandes pour s&#8217;en rendre compte :</p>
<ul>
<li>On passe d&#8217;une communication entre un workspace et dépôt à un système de quatre &laquo;&nbsp;zones&nbsp;&raquo; (et encore, je ne parle même pas du <em>stash</em>) : workspace, index, dépôt local, dépôt distant.</li>
<li>L&#8217;équivalent d&#8217;un commit <acronym title="Subversion">SVN</acronym>, c&#8217;est commit + push. L&#8217;équivalent d&#8217;un checkout <acronym title="Subversion">SVN</acronym>, c&#8217;est fetch + checkout (ou pull). etc. Bref, plus de commandes à apprendre !</li>
</ul>
<p>Il y a donc nécessairement un temps d&#8217;adaptation. L&#8217;idéal serait évidemment de pouvoir arrêter le développement le temps de véritablement former l&#8217;équipe à git, sur quelques jours à temps plein. Dans la pratique, ce n&#8217;est souvent pas possible, et on se retrouve à devoir apprendre petit à petit sur le tas.</p>
<p>C&#8217;est à ce stade que les formations ne sont vraiment pas un luxe. Personnellement, ce sont les formations sur une journée complète de <a href="http://twitter.com/porteneuve">Christophe Porteneuve</a> qui m&#8217;ont permis de véritablement apprendre à maîtriser git. Pour ceux que cela intéresse, la <a href="http://www.git-attitude.fr/">prochaine formation</a>, c&#8217;est samedi en huit à Paris. Et 100€ pour une journée de formation, déjeuner compris, c&#8217;est donné vu tout ce qu&#8217;on y apprend. Note : pour ceux qui se posent la question, je ne touche strictement rien pour les publicités que je lui fait. J&#8217;encourage ces ateliers parce que je les trouve excellents ! Et vu le prix des formations par rapport au temps qu&#8217;il y passe, je ne le soupçonne pas de faire ça pour l&#8217;argent non plus…</p>
<h3>Les habitudes <acronym title="Subversion">SVN</acronym>…</h3>
<p>Tous les manuels le disent : il ne faut pas penser comme en <acronym title="Subversion">SVN</acronym>, et ne surtout pas se dire &laquo;&nbsp;quel est l&#8217;équivalent de cette commande <acronym title="Subversion">SVN</acronym> en git ?&nbsp;&raquo;. C&#8217;est bien beau de le dire, mais dans la pratique, faute d&#8217;avoir le temps de commencer par une formation complète, ça commence souvent comme ça quand même !</p>
<p>On se retrouve donc avec deux habitudes que l&#8217;on reproduit :</p>
<ul>
<li><strong>la trunkite</strong> : dans <acronym title="Subversion">SVN</acronym>, la gestion des branches est tellement catastrophique que souvent, on ne les utilise même pas. Quand on arrive dans git, on n&#8217;a donc pas le réflexe de créer des branches, et on développe dans master, qui devient le &laquo;&nbsp;git trunk&nbsp;&raquo;.</li>
<li><strong>la pushite</strong> : avec <acronym title="Subversion">SVN</acronym>, les commits intermédiaires d&#8217;une fonctionnalité sont généralement interdits car ils cassent le build. On développe donc toute la fonctionnalité, avec d&#8217;effectuer un unique gros commit, que l&#8217;on le partage immédiatement à l&#8217;équipe par un push.</li>
<li><strong>la pullite</strong> : il s&#8217;agit de la peur de ne pas être à jour par rapport à ce que font les camarades, et donc d&#8217;effectuer très régulièrement des pull, pour remettre à jour sa branche.</li>
</ul>
<p>On utilise donc git comme si c&#8217;était un <acronym title="Subversion">SVN</acronym>. Et à plusieurs, il arrive souvent que les push soient refusés pour cause d&#8217;absence de mise à jour préalable. Qu&#8217;à cela ne tienne : &laquo;&nbsp;git pull + git push&nbsp;&raquo; résout le problème ! A ceci près que git conserve ces fusions dans son arbre. Quand il y a un merge, ça va… mais quand plusieurs développeurs commencent à faire la même chose en parallèle, on a vite un arbre qui ressemble à ça :</p>
<div id="attachment_840" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.courtine.org/wp-content/uploads/2011/06/git_svn_workflow.png"><img class="size-medium wp-image-840" title="Workflow Subversion utilisé dans Git" src="http://blog.courtine.org/wp-content/uploads/2011/06/git_svn_workflow-300x114.png" alt="Workflow Subversion utilisé dans Git" width="300" height="114" /></a><p class="wp-caption-text">Workflow Subversion utilisé dans Git</p></div>
<p>Le problème, c&#8217;est que dans ce workflow, les micro-merges de chacun ne correspondent pas à de véritables fusions fonctionnelles. On se retrouve donc avec un graph dont la compréhension nécessite parfois quelques aspirines. Paradoxalement, on se retrouve dans une situation où la gestion de configuration est plus difficile à lire que l&#8217;équivalent <acronym title="Subversion">SVN</acronym>, ce qui est l&#8217;inverse du but recherché.</p>
<h3>… dont on se soigne !</h3>
<p>Heureusement, après quelques temps et un peu de formation, la maîtrise des commandes progresse, ainsi que la compréhension des avantages de git et la méthode de travail. En particulier, voilà quelques réflexes qu&#8217;on acquiert :</p>
<h4>Commiter régulièrement</h4>
<p>C&#8217;est un des premiers réflexes à acquérir. Les commit étant locaux, le commit d&#8217;un &laquo;&nbsp;morceau de fonctionnalité&nbsp;&raquo; ne gènera pas le reste de l&#8217;équipe et ne cassera pas le build tant qu&#8217;il ne sera pas partagé. Ca permet d&#8217;avoir plus de commits par fonctionnalité, avec de nombreux avantages :</p>
<ul>
<li>un suivi plus fin du développement, et une meilleure compréhension pour le reste de l&#8217;équipe de l&#8217;enchaînement des étapes de développement</li>
<li>une identification plus facile du commit ayant entrainé une régression quand il y en a (recherche qui peut être automatisée avec le surpuissant <a href="http://blog.javabien.net/2010/03/23/git-bisect-might-save-your-day/">git bisect</a>)</li>
</ul>
<p>Cette évolution de la méthode de développement va évidemment de pair avec l&#8217;arrêt de la <em>pushite</em>, puisqu&#8217;on risquerait là de partager une évolution incomplète cassant le build, et de se faire taper dessus par le {reste de l&#8217;équipe/chef de projet/scrum master} (rayer les mentions inutiles).</p>
<h4>Créer des branches</h4>
<h4><em> </em><span style="font-size: 13px; font-weight: normal;">Avant tout début de développement (fonctionnalité, refactoring, etc.), le réflexe à avoir est de créer une branche dédiée, avant même de commencer à réfléchir à ce que l&#8217;on va coder.</span></h4>
<p>Petite astuce : avec quelques commandes git, si on a oublié de créer une branche, on peut le faire à postériori. Supposons que j&#8217;ai fait 3 commits dans <em>master</em>, que j&#8217;aurais du faire dans une branche dédiée <em>feature</em> :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> branch feature <span style="color: #666666; font-style: italic;"># Création de la branche manquante</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> reset HEAD~<span style="color: #000000;">3</span> <span style="color: #666666; font-style: italic;"># La branche master revient là où elle devrait être, ni vu ni connu…</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> checkout feature <span style="color: #666666; font-style: italic;"># Retour sur la branche et poursuite des développements…</span></pre></td></tr></table></div>

<p>Une fois cette habitude prise, la <em>pullite </em>n&#8217;est plus un problème : rien n&#8217;empêche de mettre à jour <em>master</em> (aussi souvent qu&#8217;on le souhaite), en <em>fast-forward</em>, tout en continuant ses développements dans la branche <em>feature</em>.</p>
<p>On ne fusionne sa branche de développement dans <em>master</em> que lorsque l&#8217;évolution est terminée :</p>
<div id="attachment_842" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.courtine.org/wp-content/uploads/2011/06/git_feature_workflow.png"><img class="size-medium wp-image-842" title="Git workflow" src="http://blog.courtine.org/wp-content/uploads/2011/06/git_feature_workflow-300x56.png" alt="Git workflow" width="300" height="56" /></a><p class="wp-caption-text">Git workflow</p></div>
<h3>Résolution des conflits</h3>
<p>Le workflow précédent est déjà nettement plus lisible dans l&#8217;historique git. Cependant, il présente un inconvénient : si l&#8217;évolution est complexe, on travaille &laquo;&nbsp;en aveugle&nbsp;&raquo; par rapport au reste des développements jusqu&#8217;à la fusion finale. Si différentes évolutions impactent les mêmes classes, la fusion finale peut être difficile.</p>
<p>D&#8217;où l&#8217;idée de résoudre les conflits par avance. Pour cela, il y a un moyen simple : réaliser régulièrement des fusions de la branche <em>master</em> vers sa branche de développement :</p>
<div id="attachment_844" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.courtine.org/wp-content/uploads/2011/06/git_feature_merge_workflow.png"><img class="size-medium wp-image-844" title="Git workflow avec fusions intermédiaires" src="http://blog.courtine.org/wp-content/uploads/2011/06/git_feature_merge_workflow-300x50.png" alt="Git workflow avec fusions intermédiaires" width="300" height="50" /></a><p class="wp-caption-text">Git workflow avec fusions intermédiaires</p></div>
<p>Cela permet de résoudre les conflits au fur et à mesure qu&#8217;ils apparaissent, et ainsi de ne pas avoir à tout résoudre d&#8217;un seul coup à la fin.</p>
<h3>En route vers <a href="http://www.kernel.org/pub/software/scm/git/docs/git-rerere.html">git ReReRe</a></h3>
<p>Ce chapitre est naturellement dédié à <a href="http://blog.loof.fr/">Nicolas</a>, suite à une discussion que nous avons eu à la <a href="http://www.whatsnextparis.com/">What&#8217;s Next</a> la semaine dernière (juste avant qu&#8217;il ne s&#8217;enfuie pour mettre à jour une <a href="http://www.slideshare.net/ndeloof/jenkins-user-meetup-paris">présentation</a>…).</p>
<p>Certaines fusions de <em>master</em> vers la branche de développement sont justifiées, quand par exemple, il faut intégrer des correctifs qui impactent les développements en cours. Mais si ces fusions n&#8217;ont pour but que de résoudre par avance les conflits, elles sont un peu artificielles et &laquo;&nbsp;polluent&nbsp;&raquo; l&#8217;historique du projet.</p>
<h4>Mise en place</h4>
<p>Or, il existe un moyen d&#8217;avoir une résolution par avance, sans pour autant conserver ces fusions. Il s&#8217;agit de la fonctionnalité ReReRe de git (Reuse Recorded Resolution) : son principe est d&#8217;enregistrer par avance la résolution du conflit, afin que git l&#8217;utilise automatiquement lors de la fusion finale.</p>
<p>Pour activer cette fonctionnalité, il faut l&#8217;ajouter à la configuration de git (soit pour un projet, soit de manière globale). Ca ne coûte pas grand chose : c&#8217;est donc maintenant quelque chose qui fait partie de ma configuration <em>.gitconfig</em> de base (avec quelques alias et autres choses…). D&#8217;autant plus que cela se fait en une commande :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> config <span style="color: #660033;">--global</span> rerere.enabled <span style="color: #c20cb9; font-weight: bold;">true</span></pre></td></tr></table></div>

<h4>Utilisation</h4>
<p>Cette configuration en place, si on utilise la ligne de commandes, on remarque l&#8217;apparition de nouvelles lignes lors des fusions contenant des conflits à résoudre :</p>
<blockquote><p>Recorded preimage for &#8216;fichier_en_conflit&#8217;</p></blockquote>
<p>Et, une fois la résolution effectuée, au moment du commit :</p>
<blockquote><p>Recorded resolution for &#8216;fichier_en_conflit&#8217;</p></blockquote>
<p>Git a donc enregistré la manière dont on a géré le conflit, et sera capable de la rejouer manuellement. Vérifions cela immédiatement. Juste après ce commit, on exécute :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> reset <span style="color: #660033;">--hard</span> HEAD^ <span style="color: #666666; font-style: italic;"># Annulation de la fusion que l'on vient d'effectuer</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> merge branche_en_conflit</pre></td></tr></table></div>

<p>Git indique alors :</p>
<blockquote><p>Resolved &#8216;fichier_en_conflit&#8217; using previous resolution.</p></blockquote>
<p>Le commit n&#8217;est pas fait : mais si on regarde les différents fichiers en conflit, on s&#8217;aperçoit que la résolution précédente a été appliquée automatiquement. Après vérification de celle-ci, il suffit de valider à nouveau le commit.</p>
<h4>Pour le cas qui nous intéresse…</h4>
<p>Annuler une fusion pour la rejouer immédiatement après, l&#8217;intérêt est limité. Mais ces résolutions sont conservées dans le temps. Ainsi, on peut pré-enregistrer la résolution des conflits entre sa branche et master, annuler la fusion, et continuer à travailler.</p>
<p>La résolution qu&#8217;on a enregistrée ne sera appliquée qu&#8217;au moment de la fusion finale, quand la fonctionnalité sera entièrement développée.</p>
<p>Concrètement, voici la manière de procéder :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> merge master
<span style="color: #666666; font-style: italic;"># Résolution des conflits</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> add fichier_en_conflit
<span style="color: #c20cb9; font-weight: bold;">git</span> commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">'Pré-résolution des conflits avec master'</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> reset <span style="color: #660033;">--hard</span> HEAD^ <span style="color: #666666; font-style: italic;"># Annulation du commit, mais en conservant la résolution</span>
<span style="color: #666666; font-style: italic;"># Suite de l'évolution dans la branche feature…</span>
<span style="color: #666666; font-style: italic;"># Nouvelle pré-résolution de conflit si l'évolution est longue (il n'y a pas de limite).</span>
<span style="color: #666666; font-style: italic;"># Une fois l'évolution terminée, intégration dans la branche principale :</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> checkout master
<span style="color: #c20cb9; font-weight: bold;">git</span> merge feature <span style="color: #666666; font-style: italic;"># Utilisation des résolutions pré-enregistrées</span></pre></td></tr></table></div>

<h4>Informations supplémentaires</h4>
<p>Quelques informations complémentaires concernant &laquo;&nbsp;git rerere&nbsp;&raquo; :</p>
<ul>
<li>si on travaille à plusieurs sur la branche feature (en la partageant sur le dépôt central) : les enregistrements de résolution sont partagés entre les membres de l&#8217;équipe . Ainsi, même si j&#8217;annule le commit après le pré-enregistrement d&#8217;une résolution, les développeurs travaillant sur la même branche bénéficieront des résolutions automatiquement lorsqu&#8217;ils feront à leur tours des fusions avec la branche <em>master</em>.</li>
<li>les résolutions enregistrées s&#8217;appliquent automatiquement dès que le conflit est à nouveau rencontré, et pas seulement pour les fusions. Ainsi, si par la suite je décide de faire un <em>rebase</em> sur la branche master de mon évolution plutôt d&#8217;une fusion, les conflits pour lesquels une résolution est connue seront automatiquement gérés.</li>
<li>mise en garde pour les cas extrêmes de développements très longs : les pré-résolutions ne sont conservées qu&#8217;une durée limitée. Par défaut, cette durée est de 60 jours : c&#8217;est généralement suffisant, mais si ça ne l&#8217;était pas, il est bien sûr possible d&#8217;augmenter ce temps dans la configuration git.</li>
</ul>
<p>Vu la puissance de cette fonction, il est dommage qu&#8217;elle soit assez méconnue. On peut cependant comprendre pourquoi elle n&#8217;est pas activée par défaut : il est préférable de bien en comprendre l&#8217;intérêt et le mode de fonctionnement du <em>ReReRe</em> avant de l&#8217;utiliser. Il n&#8217;est en effet pas naturel au début de fusionner et de commiter… pour annuler ce commit immédiatement après !</p>
<p>Comme toutes les commandes git, celle-ci dispose de toute une batterie d&#8217;options dans lesquelles on peut se plonger pour aller encore plus loin, avec le <a href="http://www.kernel.org/pub/software/scm/git/docs/git-rerere.html">manuel officiel</a>.</p>
<h3>Conclusion</h3>
<p>Voici donc comment on peut monter petit à petit un workflow d&#8217;utilisation de git sur un projet qui utilisait préalablement <acronym title="Subversion">SVN</acronym>. Pour ceux qui se poseraient la question, ce n&#8217;est pas que de la théorie : cet article est le fruit <del>d&#8217;une discussion avec Nicolas à la What&#8217;s Next</del> d&#8217;un véritable retour d&#8217;expérience sur un projet où nous avons <a href="http://blog.courtine.org/2010/12/07/au-revoir-svn-bonjour-git/">&laquo;&nbsp;switché&nbsp;&raquo; de <acronym title="Subversion">SVN</acronym> à git</a> (en particulier sur les habitudes <acronym title="Subversion">SVN</acronym> qu&#8217;il n&#8217;est pas évident de perdre).
<div class="tweetmeme_button" style="float: left; margin-left: 10px; margin-right: 20px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F06%2F02%2Fmettre-en-place-un-workflow-git%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F06%2F02%2Fmettre-en-place-un-workflow-git%2F&amp;style=normal&amp;service=bit.ly&amp;service_api=bcourtine%3AR_adaa69f468b94402bc961e78ad01d140&amp;hashtags=DVCS,Gestionnaire+de+configuration,Git,SI,SVN&amp;b=2" height="61" width="50" /><br />
			</a>
		</div> <p><a href="http://blog.courtine.org/?flattrss_redirect&amp;id=834&amp;md5=469d681dab2b7c3e6390d3a062772bc0" title="Flattr" target="_blank"><img src="http://blog.courtine.org/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.courtine.org/2011/06/02/mettre-en-place-un-workflow-git/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=bcourtine&amp;popout=1&amp;url=http%3A%2F%2Fblog.courtine.org%2F2011%2F06%2F02%2Fmettre-en-place-un-workflow-git%2F&amp;language=fr_FR&amp;category=text&amp;title=Mettre+en+place+un+workflow+git&amp;description=Si+vous+avez+%C3%A9t%C3%A9+%C3%A0+une+ou+deux+pr%C3%A9sentations+de+git%2C+vous+avez+sans+doute+d%C3%A9j%C3%A0+vu+ce+diagramme+%28ou+un+%C3%A9quivalent%29.+Apr%C3%A8s+avoir+un+peu+pratiqu%C3%A9+git%2C+ce+genre...&amp;tags=DVCS%2CGestionnaire+de+configuration%2CGit%2CSI%2CSVN%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Deuxième journée de What&#8217;s Next</title>
		<link>http://blog.courtine.org/2011/05/27/deuxieme-journee-de-whats-next/</link>
		<comments>http://blog.courtine.org/2011/05/27/deuxieme-journee-de-whats-next/#comments</comments>
		<pubDate>Fri, 27 May 2011 08:41:27 +0000</pubDate>
		<dc:creator>Benoît Courtine</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Intégration Continue]]></category>
		<category><![CDATA[Java-JEE]]></category>
		<category><![CDATA[Veille Technologique]]></category>

		<guid isPermaLink="false">http://blog.courtine.org/?p=785</guid>
		<description><![CDATA[Aujourd&#8217;hui, j&#8217;ai réussi à obtenir une connexion WIFI (reste à savoir pour combien de temps&#8230;). Je vais donc tenter de résumer cette deuxième journée de conférences en direct. La journée commence de manière très conviviale, autour d&#8217;un café avec Nicolas de Loof, qui nous quittera précipitamment pour aller tester git rerere et mettre à jour&#8230;]]></description>
			<content:encoded><![CDATA[<p>Aujourd&#8217;hui, j&#8217;ai réussi à obtenir une connexion WIFI (reste à savoir pour combien de temps&#8230;). Je vais donc tenter de résumer cette deuxième journée de conférences en direct.</p>
<p>La journée commence de manière très conviviale, autour d&#8217;un café avec <a href="http://blog.loof.fr/">Nicolas de Loof</a>, qui nous quittera précipitamment pour aller tester <a href="http://www.kernel.org/pub/software/scm/git/docs/git-rerere.html">git rerere</a> et mettre à jour sa présentation de ce soir. J&#8217;en profite pour faire la publicité des ateliers <a href="http://www.git-attitude.fr/">git attitude</a> qui m&#8217;ont appris l&#8217;existence et l&#8217;utilisation de cette commande !</p>
<h3>Keynote de Neal Gafter</h3>
<p><a href="http://gafter.blogspot.com/">Neal Gafter</a> est une des figures emblématiques du langage <a href="http://www.java.com/fr/">Java</a>, ayant contribué à son commencement. Il commence par nous présente un historique complet du langage, et des évènements survenus lors de son développement (problème des <a href="http://www.jcp.org/en/resources/tdk">TCK</a> et du projet <a href="http://harmony.apache.org/">Harmony</a>, etc.). Au passage, quelques tests tirés de son livre <a href="http://www.javapuzzlers.com/">Java Puzzlers</a> (sur lesquels je me suis fait avoir : j&#8217;ai encore quelques révisions à faire&#8230;).</p>
<p>Nous passons maintenant à une partie qui m&#8217;intéresse : le cloud (encore !), mais à la sauce <a href="http://www.microsoft.com/fr-fr/">Microsoft</a> :  <a href="http://www.microsoft.com/windowsazure/">Azure</a>. La plate-forme de cloud tourne en environnement <a href="http://www.microsoft.com/france/windows/">Windows</a>, mais se veut ouverte à tous les langages de développement.</p>
<p>Avec la plate-forme Azure, on ne s&#8217;occupe pas des machines virtuelles : la plate-forme le gère pour nous, et fournit les VMs clés-en-main, en appliquant automatiquement les patchs de sécurité, etc. Le but est de permettre aux développeurs de se concentrer sur les applications. De même, la plupart des briques techniques sont gérées automatiquement : le load-balancing, l&#8217;ajout d&#8217;une base de données, etc.</p>
<p>Sur ces points, la description de cette plate-forme me rappelle fortement ce que j&#8217;ai pu voir de <a href="http://cloudfoundry.com/">Cloud Foundry</a>.</p>
<p>Apparemment, Azure est Java Ready : <a href="http://www.windowsazure4j.org/"><acronym title="Software Development Kit">SDK</acronym> Java</a>, support de JDBC4 (et donc des frameworks de persistence comme <a href="http://www.hibernate.org/">Hibernate</a>). Il y a également un <a href="http://wastarterkit4java.codeplex.com/">Starter Kit</a> permettant de configurer un projet Java sur le cloud.</p>
<h3><a href="http://www.rabbitmq.com/">RabbitMQ</a> par Rob Harrop</h3>
<p>Pas de WIFI pendant cette présentation, j&#8217;écris le compte-rendu à postériori. Rob était absolument impressionnant (je le soupçonne d&#8217;être en fait <a href="http://www.chucknorrisfacts.fr/">Chuck Norris</a> déguisé) : démonstration live sans aucun &laquo;&nbsp;effet démo&nbsp;&raquo; sur 4 langages différents (Java, <a href="http://www.erlang.org/">Erlang</a>, <a href="http://www.ruby-lang.org/fr/">Ruby</a>, <a href="http://www.python.org/">Python</a>) pour montrer l&#8217;inter-opérabilité de la plate-forme. Ca donne vraiment envie de l&#8217;essayer !</p>
<p>A suivi une phase de questions-réponses assez pointues sur la scalabilité, la résistance à la panne, les différences d&#8217;approche par rapport à d&#8217;autres technologies de messagerie, etc.</p>
<h3>Pause déjeuner</h3>
<p>Tirage au sort de l&#8217;<a href="http://www.apple.com/fr/ipad/">iPad 2</a> : encore perdu… Je ne perds pas espoir d&#8217;en gagner un prochainement.</p>
<p>Comme hier, au <a href="http://www.mcdonalds.fr/">Mc Donald&#8217;s</a> d&#8217;en face, mais sans passer par la case sandwichs.</p>
<h3>Le découplage de services par <a href="http://omniti.com/is/theo-schlossnagle">Theo Schlossnagle</a></h3>
<p>Un contributeur à presque 20 projets OpenSource, ça force le respect…</p>
<p>Début de conférence sur les chapeaux de roue : on met les pieds dans le plat avec les raisons du choix d&#8217;une architecture <a href="http://nosql-database.org/">NoSQL</a> ou <a href="http://fr.wikipedia.org/wiki/Cloud_computing">Cloud</a>.</p>
<p>Très bonne démonstration du fait qu&#8217;on n&#8217;a pas besoin de milliers de machines pour scaler, mais de repenser son modèle dans la majorité des cas.</p>
<p>Le découplage d&#8217;une application en systèmes élémentaires indépendants donne de la flexibilité, mais est une opération très complexe. Elle nécessite des systèmes de files (<a href="http://activemq.apache.org/">ActiveMQ</a>, RabbitMQ, etc.).</p>
<p>Pour bien concevoir un système, on doit faire la part des choses entre ce que l&#8217;on veut (un résultat instantané), et ce que l&#8217;on peut obtenir (calcul trop long pour permettre un résultat instantané). Dans ce cas, il faut découpler ce calcul dans un système asynchrone.</p>
<p>Conseils pour parvenir à ses fins :</p>
<ul>
<li>Programmation défensive (timeouts, points de vérification, etc.)</li>
<li>Mise en place de monitoring (vitesse de traitement, taille des files d&#8217;attente, nombre de connexions concurrentes, etc.)</li>
</ul>
<blockquote><p>Si une application doit tomber en erreur, il faut qu&#8217;elle tombe en erreur rapidement (timeouts, etc.) !</p></blockquote>
<p>Résumé final : excellente conférence pleine de très bons conseils d&#8217;architecture !</p>
<h3>Tirage au sort des gagnants de places VIP pour Rolland Garros</h3>
<p>Félicitations Alexandre !</p>
<h3>Architecturer l&#8217;expérience utilisateur, par <a href="http://codemoiunmouton.wordpress.com/">Michaël Chaize</a></h3>
<p>Conférence en français (ça mérite d&#8217;être souligné).</p>
<blockquote><p>L&#8217;architecture est impactée par l&#8217;expérience utilisateur qu&#8217;on veut donner à ses clients</p></blockquote>
<p><a href="http://www.adobe.com/ca_fr/products/flex/">Flex</a> est devenu Open Source en 2007, et peut être codé en ActionScript 3 ou en MXML. Il génère ensuite un fichier <a href="http://www.adobe.com/fr/products/flashplayer/">Flash</a>. Flex est utilisé à 90% pour des applications internes [Mode mauvaise langue]par honte de les exposer au public[/Mode mauvaise langue].</p>
<p>Depuis 2007, la fondation <a href="http://www.openscreenproject.org/">OpenScreen</a> a permis de travailler avec les acteurs du marché mobile pour optimiser le player Flash sur les terminaux, à l&#8217;exception d&#8217;un acteur du marché qui a refusé. On se demande bien <a href="http://www.apple.com/fr/">lequel</a>…</p>
<p>Flex 4.5 semble effectivement assez adapté au développement mobile :</p>
<ul>
<li>prise en compte des différentes résolutions d&#8217;écran</li>
<li>développement unique pour <a href="http://www.android.com/">Android</a> 2.2 et 2.3, <a href="http://fr.blackberry.com/playbook-tablet/">Blackberry Playbook</a>, et les tablettes Apple (moyennant une conversion de code)</li>
</ul>
<p>Présentation intéressante, et qui donne envie. Mais malheureusement, je n&#8217;ai pas vraiment le temps en ce moment de faire du développement mobile (trop d&#8217;autres choses dans ma todo-list d&#8217;études).</p>
<h3>Conférence <a href="http://akka.io/">Akka</a> par <a href="http://jonasboner.com/">Jonas Bonér</a> (CTO de <a href="http://typesafe.com/">TypeSafe</a>)</h3>
<p>Il est difficile de construire des systèmes gérant correctement la concurrence et la scalabilité. Akka (et Scala) a été créé pour tenter de proposer des solutions à cette problématique.</p>
<p>Les trois briques principales de Akka :</p>
<ul>
<li>Tolérance à la panne (supervision)</li>
<li>Scalabilité (système des Actors et clustering)</li>
<li>Concurrence (Actors, STM, Agents, Dataflow)</li>
</ul>
<p>Plus tout un ensemble de modules add-on (JPA, etc.)</p>
<p>Qu&#8217;est ce qu&#8217;un <strong>acteur</strong> ? un acteur ressemble à un objet : c&#8217;est un <strong>état</strong>, et un <strong>comportement</strong>. Un acteur est indépendant, isolé, et ne partage pas son état : il n&#8217;y a donc pas de mécanisme de lock à implémenter pour gérer la concurrence. Les acteurs communiquent par un système de <strong>messages</strong>. Les acteurs sont indépendants des threads (à ceci près qu&#8217;un acteur est MonoThread) : la seule limitation du nombre d&#8217;acteurs est la mémoire.</p>
<p>L&#8217;envoi d&#8217;un message à un acteur n&#8217;attend aucun retour. Le traitement du message est asynchrone. On peut cependant attendre un résultat futur (associé à un timeout) :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;">actor <span style="color: #000080;">!</span> message
&nbsp;
<span style="color: #0000ff; font-weight: bold;">val</span> future <span style="color: #000080;">=</span> actor <span style="color: #000080;">!!!</span> message
future.<span style="color: #000000;">await</span>
<span style="color: #0000ff; font-weight: bold;">val</span> result <span style="color: #000080;">=</span> future.<span style="color: #000000;">result</span></pre></td></tr></table></div>

<p>Le comportement des acteurs est complètement déterministe.</p>
<p>Travailler avec des acteurs distribués sur plusieurs machines est presque transparent pour le code. Le runtime fournit un mécanisme de clustering (gérant le failover) pour les acteurs, avec plusieurs stratégies de choix du serveur d&#8217;exécution (CPU utilisé, mémoire utilisée, etc.).</p>
<h3><a href="http://www.elasticsearch.org/">Elastic Search</a>, par <a href="http://www.kimchy.org/">Shay Banon</a></h3>
<p>Présentation très originale, qui s&#8217;est déroulée sans aucun slide, mais juste avec une console, et l&#8217;outil <a href="http://curl.haxx.se/">cURL</a>, qui servait à attaquer l&#8217;<acronym title="Application Programming Interface">API</acronym> REST d&#8217;Elastic Search. Pour résumer, Elastic Search est un outil construit autour de <a href="http://lucene.apache.org/">Lucene</a> avec les grandes fonctionnalités suivantes :</p>
<ul>
<li>Fonctionnement en cluster (avec une gestion très simple de l&#8217;ajout d&#8217;un serveur au cluster)</li>
<li><acronym title="Application Programming Interface">API</acronym> d&#8217;accès entièrement construite en REST, avec des données <a href="http://json.org/">JSON</a></li>
</ul>
<p>L&#8217;ensemble de la présentation consistait à nous montrer des fonctionnalités de plus en plus complexes :</p>
<ul>
<li>utilisation d&#8217;un noeud, puis d&#8217;un cluster de noeuds</li>
<li>création d&#8217;index simples, puis complexes (en imposant un format de mapping)</li>
<li>recherches simples, puis complexes (filtrage, etc.)</li>
</ul>
<p>Je n&#8217;ai encore jamais eu l&#8217;occasion de travailler sur une problématique d&#8217;indexation de documents (à l&#8217;exception d&#8217;une mise en place d&#8217;une GED <a href="http://www.alfresco.com/fr/">Alfresco</a>, mais où l&#8217;indexation est déjà gérée). Mais si ça devait arriver, l&#8217;<acronym title="Application Programming Interface">API</acronym> d&#8217;Elastic Search en fait un produit qui a l&#8217;air particulièrement intéressant.</p>
<h3>L&#8217;avenir de l&#8217;intégration continue par <a href="http://www.twitter.com/kohsukekawa">Kohsuke Kawaguchi</a></h3>
<p>La présentation commence par un bilan : la puissance des machines de développement augmente de manière exponentielle. Or, les compétences des développeurs ne suivent pas cette même évolution. Par rapport à la puissance des machines, le développeur est donc une denrée précieuse : il faut donc veiller à ce que l&#8217;outillage exploite eu mieux cette puissance machine pour permettre aux développeurs de gagner du temps.</p>
<p>Pour cela, plusieurs pistes :</p>
<ul>
<li>utiliser au mieux les gestionnaires de configuration distribués (<a href="http://git-scm.com/">git</a> par exemple)</li>
<li>faire exécuter les tests sur le serveur d&#8217;intégration continue au lieu de les exécuter sur les machines des développeurs</li>
<li>etc.</li>
</ul>
<h3>Epilogue</h3>
<p>Voilà deux journées très intéressantes, sans aucun bémol majeur : c&#8217;est donc une grande réussite pour <a href="http://www.zenika.com/">Zenika</a> (dont je remercie toute l&#8217;équipe au passage), qui nous a d&#8217;ors et déjà invités à revenir l&#8217;année prochaine.</p>
<p>La soirée s&#8217;est achevée pour moi par plus d&#8217;une heure de discussions techniques passionnées sur les quais du métro avec <a href="http://www.viadeo.com/fr/profile/alexandre.depellegrin">Alexandre</a> (rencontré hier par l&#8217;intermédiaire d&#8217;<a href="http://twitter.com/antoine_sd">Antoine</a>).</p>
<p>Félicitation à <a href="http://blog.loof.fr/">Nicolas</a> qui a le courage de rempiler pour la soirée Jenkins… J&#8217;aurai une pensée émue pour sa présentation de ce soir (et j&#8217;en suis quitte pour un prochain article sur git, sauf si <a href="http://twitter.com/sdouche">Sébastien</a> me devance).</p>
<p><strong>[Mise à jour : quelques autres compte-rendus]</strong></p>
<ul>
<li><a href="http://hypedrivendev.wordpress.com/2011/05/28/whats-next/">http://hypedrivendev.wordpress.com/2011/05/28/whats-next/</a></li>
<li><a href="http://blog.loof.fr/2011/05/merci-zenika.html">http://blog.loof.fr/2011/05/merci-zenika.html</a></li>
<li><a href="http://www.lemondeinformatique.fr/actualites/lire-what-s-next-le-monde-java-pense-a-l-avenir-sans-oracle-33817.html">http://www.lemondeinformatique.fr/actualites/lire-what-s-next-le-monde-java-pense-a-l-avenir-sans-oracle-33817.html</a></li>
<li><a href="http://www.touilleur-express.fr/2011/05/31/whats-next-2eme-journee-neal-gafters-keynote/">http://www.touilleur-express.fr/2011/05/31/whats-next-2eme-journee-neal-gafters-keynote/</a></li>
<li><a href="http://pro.01net.com/editorial/533707/what-s-next-les-retrouvailles-de-la-communaute-java/">http://pro.01net.com/editorial/533707/what-s-next-les-retrouvailles-de-la-communaute-java/</a></li>
</ul>
<p><strong>[Et ça continue…]</strong></p>
<ul>
<li>Chez <a href="http://www.xebia.fr/">Xebia</a>, <a href="http://blog.xebia.fr/2011/06/03/whats-next-paris-2011/">ici</a> et <a href="http://blog.xebia.fr/2011/06/06/whats-next-la-keynote-dadrian-colyer/">là</a></li>
<li>Chez <a href="http://www.valtech.fr/">Valtech</a>, <a href="http://blog.valtech.fr/wordpress/2011/06/06/whats-next-paris-jour-1/">ici</a> et <a href="http://blog.valtech.fr/wordpress/2011/06/06/whats-next-paris-jour-2/">là</a></li>
</ul>
<div class="tweetmeme_button" style="float: left; margin-left: 10px; margin-right: 20px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F05%2F27%2Fdeuxieme-journee-de-whats-next%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F05%2F27%2Fdeuxieme-journee-de-whats-next%2F&amp;style=normal&amp;service=bit.ly&amp;service_api=bcourtine%3AR_adaa69f468b94402bc961e78ad01d140&amp;hashtags=Int%C3%A9gration+Continue,Java-JEE,Veille+Technologique&amp;b=2" height="61" width="50" /><br />
			</a>
		</div> <p><a href="http://blog.courtine.org/?flattrss_redirect&amp;id=785&amp;md5=115491ef63038610fcb1649ef23b36fa" title="Flattr" target="_blank"><img src="http://blog.courtine.org/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.courtine.org/2011/05/27/deuxieme-journee-de-whats-next/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=bcourtine&amp;popout=1&amp;url=http%3A%2F%2Fblog.courtine.org%2F2011%2F05%2F27%2Fdeuxieme-journee-de-whats-next%2F&amp;language=fr_FR&amp;category=text&amp;title=Deuxi%C3%A8me+journ%C3%A9e+de+What%26%238217%3Bs+Next&amp;description=Aujourd%26%238217%3Bhui%2C+j%26%238217%3Bai+r%C3%A9ussi+%C3%A0+obtenir+une+connexion+WIFI+%28reste+%C3%A0+savoir+pour+combien+de+temps%26%238230%3B%29.+Je+vais+donc+tenter+de+r%C3%A9sumer+cette+deuxi%C3%A8me+journ%C3%A9e+de+conf%C3%A9rences+en+direct.+La+journ%C3%A9e...&amp;tags=Int%C3%A9gration+Continue%2CJava-JEE%2CVeille+Technologique%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Première journée à la What&#8217;s Next</title>
		<link>http://blog.courtine.org/2011/05/26/premiere-journee-a-la-whats-next/</link>
		<comments>http://blog.courtine.org/2011/05/26/premiere-journee-a-la-whats-next/#comments</comments>
		<pubDate>Thu, 26 May 2011 21:38:42 +0000</pubDate>
		<dc:creator>Benoît Courtine</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Java-JEE]]></category>
		<category><![CDATA[Veille Technologique]]></category>
		<category><![CDATA[What's Next]]></category>

		<guid isPermaLink="false">http://blog.courtine.org/?p=777</guid>
		<description><![CDATA[Je vais certainement manquer de temps pour résumer l&#8217;ensemble de cette journée&#8230; d&#8217;autant plus qu&#8217;on repart dès demain pour une deuxième journée de conférences toute aussi intéressante que la première. Une logistique perfectible Commençons par le sujet qui fâche&#8230; la logistique ! A la décharge de Zenika, c&#8217;est la première édition de la What&#8217;s Next.&#8230;]]></description>
			<content:encoded><![CDATA[<p>Je vais certainement manquer de temps pour résumer l&#8217;ensemble de cette journée&#8230; d&#8217;autant plus qu&#8217;on repart dès demain pour une deuxième journée de conférences toute aussi intéressante que la première.</p>
<h3>Une logistique perfectible</h3>
<p>Commençons par le sujet qui fâche&#8230; la logistique ! A la décharge de <a href="http://www.zenika.com/">Zenika</a>, c&#8217;est la première édition de la <a href="http://www.whatsnextparis.com/">What&#8217;s Next</a>. Et gérer la logistique pour une conférence de plus de 600 participants, ce n&#8217;est pas une mince affaire. Voici donc quelques points perfectibles :</p>
<ul>
<li>Le <a href="http://www.legrandrex.com/">Grand Rex</a> n&#8217;a visiblement pas l&#8217;habitude de recevoir en même temps 500 geeks, tous équipés de leur {smartphone/tablette/ ordinateur portable} (rayer les mentions inutiles). Les 3 réseaux WIFI disponibles ont rapidement été saturés, et n&#8217;attribuaient plus d&#8217;adresse <acronym title="Internet Protocol">IP</acronym>. Heureusement qu&#8217;il restait la 3G d&#8217;urgence pour couvrir l&#8217;évènement via <a href="http://twitter.com/">Twitter</a> (le hashtag officiel <a href="http://twitter.com/#!/search/wsnparis">wsnparis</a> ayant bien servi).</li>
<li>Un seul point de ravitaillement en café pour les mêmes 500 geeks, c&#8217;est l&#8217;embouteillage assuré à chaque pause (encore qu&#8217;il faille relativiser : la distribution restait suffisamment fluide, et que j&#8217;ai toujours pu avoir mon café).</li>
<li>Le déjeuner a convaincu une bonne partie des participants de se retrouver au <a href="http://www.mcdonaldsfrance.fr/">Mc Donald&#8217;s</a> d&#8217;en face. Cependant, vu le rapport entre le prix d&#8217;entrée et la qualité des conférenciers présents, je ne regrette pas le déjeuner un peu léger. J&#8217;aime autant que la conférence reste à prix abordable, quitte à devoir sacrifier sur la nourriture.</li>
</ul>
<p>Le choix du Grand Rex a pourtant un certains nombres d&#8217;avantages indéniables :</p>
<ul>
<li>bien placé, au centre de Paris</li>
<li>des sièges bien plus confortables que dans la majorité des salles de conférences</li>
</ul>
<h3>Une ambiance géniale et des rencontres très sympatiques</h3>
<p>Comme d&#8217;habitude, la journée a été très riche en rencontres. Outre les personnes déjà croisées au <a href="http://www.parisjug.org/">Paris <acronym title="Java User Group">JUG</acronym></a> (ou autres évènements), j&#8217;ai pu faire la connaissance aujourd&#8217;hui de <a href="http://twitter.com/dgageot">David Gageot</a>, <a href="http://twitter.com/ndeloof">Nicolas de Loof</a>, <a href="http://twitter.com/aheritier">Arnaud Héritier</a>, <a href="http://twitter.com/FlorianBoulay">Florian Boulay</a>, ainsi qu&#8217;un bon nombre d&#8217;autres personnes&#8230;</p>
<p>L&#8217;ambiance générale de l&#8217;évènement était très agréable : très détendue, très geek (sur l&#8217;ensemble des participants, on n&#8217;a pu dénombrer que quelques cravates). Sur ce sujet, la palme revient d&#8217;ailleurs certainement à <a href="http://www.ekabanov.net/">Jevgeni Kabanov</a>.</p>
<p>Enfin, la fin de journée sur une discussion autour d&#8217;une bière était une super-idée pour permettre un debriefing et des débats passionnés dans une bonne ambiance, même si j&#8217;ai dû m&#8217;absenter assez rapidement, étant <a href="http://blog.courtine.org/2011/03/16/te-deum/">attendu</a>.</p>
<h3>De très bonnes conférences</h3>
<p>Les conférences étaient très bonnes. Parmi celles-ci, j&#8217;ai particulièrement apprécié :</p>
<ul>
<li>La keynote d&#8217;<a href="http://www.springone2gx.com/conference/speaker/adrian_colyer">Adrian Colyer</a>, où il était question surtout question de cloud, de cloud&#8230; et de cloud ! Cette conférence m&#8217;a donné envie de me repencher sur <a href="http://cloudfoundry.com/">Cloud Foundry</a>, après quelques <a href="http://blog.courtine.org/2011/05/05/playframework-et-cloudfoundry-reloaded/">premiers tests</a>. Au passage, on notera l&#8217;apparition d&#8217;un nouveau buzzword qui devrait faire fureur dans les prochaines : le <strong>microcloud</strong> (j&#8217;aurai peut-être l&#8217;occasion de revenir sur ce concept dans un prochain article).</li>
<li>La présentation du projet <a href="http://www.eclipse.org/orion/">Eclipse Orion</a>, par Boris Bokowski. Elle ne m&#8217;a pas convaincu d&#8217;abandonner <a href="http://www.jetbrains.com/idea/">IntelliJ IDEA</a>, mais la démonstration des possibilités d&#8217;édition était impressionnante : on ne se croirait pas dans une application web ! Parmi mes appréhension, je me pose en particulier la question suivante : l&#8217;<acronym title="Integrated Development Environment">IDE</acronym> web est-il résistant à la perte de la connexion réseau et permet-il de travailler offline ?</li>
<li>La présentation de <a href="http://clojure.org/">Clojure</a> par Howard Lewis Ship était intéressante : elle rappelait bien les différents paradigmes de la programmation fonctionnelle. Cependant, le langage lui-même ne m&#8217;a pas du tout convaincu : les exemples de code étaient particulièrement difficiles à relire, et me rappelaient la syntaxe sur-parenthésée du <a href="http://fr.wikipedia.org/wiki/Lisp">LISP</a>. Sur les langages fonctionnels, je vais donc certainement continuer de faire l&#8217;impasse sur Clojure, et poursuivre ma découverte de <a href="http://www.scala-lang.org/">Scala</a>.</li>
<li>La présentation de Jevgeni Kabanov sur la gestion de la mémoire en Java était passionnante. En particulier, la modélisation du CPU et de la gestion mémoire par du code <a href="http://www.java.com/fr/">Java</a> était impressionnante ! En résumé, un excellent cours de culture générale sur la gestion de la mémoire en Java. Pour revoir cette conférence (éventuellement au ralenti), c&#8217;est dans l&#8217;ordre <a href="http://www.youtube.com/watch?v=-KlYKIXBdHw">ici</a>, <a href="http://www.youtube.com/watch?v=lE5djOLKTjg">ici</a>, et <a href="http://www.youtube.com/watch?v=it9I5bIzktE">ici</a>.</li>
<li>Enfin, la présentation des <a href="http://dev.w3.org/html5/websockets/">Web Sockets</a> parBrad Drysdale m&#8217;a là encore donné envie d&#8217;étudier cette <acronym title="Application Programming Interface">API</acronym> de plus près. Par chance, je me souviens avoir lu rapidement <a href="http://coffeebean.loicdescotte.com/2011/05/websocket-et-play-framework.html">un article</a> parlant des Web Sockets et de <a href="http://www.playframework.org/">Play Framework</a>.</li>
</ul>
<p>Après cette conférence, je sens que je vais avoir un programme d&#8217;étude chargé ces prochains week-ends&#8230; Vivement demain pour la suite !</p>
<p><strong>[Mise à jour]</strong> Pour un résumé beaucoup plus détaillé de cette première journée, conférence par conférence (et avec des photos), <a href="http://www.touilleur-express.fr/2011/05/27/whats-next-compte-rendu-de-la-premiere-journee/">foncez chez Nicolas.</a>
<div class="tweetmeme_button" style="float: left; margin-left: 10px; margin-right: 20px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F05%2F26%2Fpremiere-journee-a-la-whats-next%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F05%2F26%2Fpremiere-journee-a-la-whats-next%2F&amp;style=normal&amp;service=bit.ly&amp;service_api=bcourtine%3AR_adaa69f468b94402bc961e78ad01d140&amp;hashtags=Java-JEE,Veille+Technologique,What%27s+Next&amp;b=2" height="61" width="50" /><br />
			</a>
		</div> <p><a href="http://blog.courtine.org/?flattrss_redirect&amp;id=777&amp;md5=6119f5f6d707f62d1abddd0902019b56" title="Flattr" target="_blank"><img src="http://blog.courtine.org/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.courtine.org/2011/05/26/premiere-journee-a-la-whats-next/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=bcourtine&amp;popout=1&amp;url=http%3A%2F%2Fblog.courtine.org%2F2011%2F05%2F26%2Fpremiere-journee-a-la-whats-next%2F&amp;language=fr_FR&amp;category=text&amp;title=Premi%C3%A8re+journ%C3%A9e+%C3%A0+la+What%26%238217%3Bs+Next&amp;description=Je+vais+certainement+manquer+de+temps+pour+r%C3%A9sumer+l%26%238217%3Bensemble+de+cette+journ%C3%A9e%26%238230%3B+d%26%238217%3Bautant+plus+qu%26%238217%3Bon+repart+d%C3%A8s+demain+pour+une+deuxi%C3%A8me+journ%C3%A9e+de+conf%C3%A9rences+toute+aussi+int%C3%A9ressante+que+la+premi%C3%A8re....&amp;tags=Java-JEE%2CVeille+Technologique%2CWhat%27s+Next%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Premiers pas en Scala</title>
		<link>http://blog.courtine.org/2011/05/24/premiers-pas-en-scala/</link>
		<comments>http://blog.courtine.org/2011/05/24/premiers-pas-en-scala/#comments</comments>
		<pubDate>Tue, 24 May 2011 20:54:08 +0000</pubDate>
		<dc:creator>Benoît Courtine</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Java-JEE]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://blog.courtine.org/?p=767</guid>
		<description><![CDATA[Cela fait maintenant pas mal de temps que j&#8217;entends parler de Scala, mais je n&#8217;avais jamais pris le temps m&#8217;y attarder. Il y a maintenant deux semaines, l&#8217;annonce du lancement de Typesafe (on pourra lire l&#8217;article de Nicolas pour plus d&#8217;informations) m&#8217;a donné envie de regarder de plus près ce langage. En attendant mon prochain&#8230;]]></description>
			<content:encoded><![CDATA[<p>Cela fait maintenant pas mal de temps que j&#8217;entends parler de <a href="http://www.scala-lang.org/">Scala</a>, mais je n&#8217;avais jamais pris le temps m&#8217;y attarder. Il y a maintenant deux semaines, l&#8217;annonce du lancement de <a href="http://typesafe.com/">Typesafe</a> (on pourra lire <a href="http://www.touilleur-express.fr/2011/05/12/typesafe-une-solution-dentreprise-en-scala/">l&#8217;article de Nicolas</a> pour plus d&#8217;informations) m&#8217;a donné envie de regarder de plus près ce langage.</p>
<p>En attendant mon prochain passage par <a href="http://www.fnac.com/">la FNAC</a> pour trouver un bon livre sur la question, j&#8217;ai été glaner quelques informations pour débuter :</p>
<ul>
<li>La <a href="http://www.touilleur-express.fr/category/scala/">liste des billets</a> de Nicolas sur la question</li>
<li>Les <a href="http://aperiodic.net/phil/scala/s-99/">99 Scala Problems</a>, que je suis en train de faire petit à petit</li>
<li>Les différents <a href="http://www.scala-lang.org/node/1305">liens de documentation</a> du site officiel (il y a de quoi faire&#8230;)</li>
</ul>
<p>J&#8217;ai eu la chance d&#8217;avoir des cours de <a href="http://caml.inria.fr/caml-light/">Caml Light</a> en <a href="http://www.janson-de-sailly.fr/">prépa</a> et de <a href="http://www.cliki.net/index">Lisp</a> en <a href="http://www.ec-nantes.fr/">école d&#8217;ingénieurs</a> : la programmation fonctionnelle ne m&#8217;est donc pas inconnue, ce qui m&#8217;a grandement facilité l&#8217;entrée en matière (même si j&#8217;ai rapidement dû me mettre à niveau avec les <em>Case Class</em> et autres concepts que je n&#8217;avais encore jamais rencontré).</p>
<p>Les cours de prépa que j&#8217;ai pu avoir sur la question étaient excellents. Même s&#8217;ils concernent le langage Caml, ils fournissent des exemples originaux dans lesquels la programmation fonctionnelle permet de s&#8217;en sortir bien plus facilement qu&#8217;en programmation procédurale. Je propose donc aux curieux d&#8217;aller les consulter sur <a href="http://www.normalesup.org/~simonet/teaching/index.fr.html">le site de notre enseignant</a>.<br />
<span id="more-767"></span></p>
<h3>Problématique</h3>
<p>Après ces premiers pas dans le langage à suivre des tutoriels, j&#8217;ai trouvé quelques cas d&#8217;utilisation dans mes projets sur lesquels le Scala serait mieux adapté que le <a href="http://www.java.com/fr/">Java</a>. Il est bien évidemment hors de question de réécrire toute l&#8217;application en Scala. Je me suis donc demandé s&#8217;il était possible de faire cohabiter facilement dans une même application du code Java et Scala.</p>
<p>Je vais donc partir d&#8217;un projet Java standard, et tenter d&#8217;y ajouter du Scala petit à petit. Voici donc la structure de mon projet :</p>
<ul>
<li><strong>src/main/java</strong> : code source Java</li>
<li><strong>src/main/scala</strong> : code source Scala</li>
</ul>
<h3>Choix de l&#8217;<acronym title="Integrated Development Environment">IDE</acronym></h3>
<p>Typesafe préconise l&#8217;utilisation de <a href="http://www.scala-ide.org/">Scala-<acronym title="Integrated Development Environment">IDE</acronym></a>, basé sur <a href="http://www.eclipse.org/">Eclipse</a>. J&#8217;avoue ne même pas l&#8217;avoir essayé : je n&#8217;ai donc pas de point de comparaison. Je me suis directement tourné vers le <a href="http://plugins.intellij.net/plugin/?id=1347">plugin Scala</a> d&#8217;<a href="http://www.jetbrains.com/idea/">IntelliJ IDEA</a>, et il me convient parfaitement :</p>
<ul>
<li>coloration syntaxique</li>
<li>autocomplétion (y compris lorsque le paramètre est une fonction)</li>
<li>détection des erreurs de compilation à la volée</li>
<li>possibilité d&#8217;utiliser du Scala et du Java dans un même projet, avec des appels croisés</li>
<li>etc.</li>
</ul>
<p>Bref&#8230; je retrouve dans le plugin Scala tous les petits plus que j&#8217;apprécie dans IntelliJ par rapport à Eclipse !</p>
<h3>Appeler du code Scala depuis du Java</h3>
<p>Après quelques tests, il semble qu&#8217;appeler du code Java depuis Scala ne pose apparemment aucun problème. Mais dans le cas qui m&#8217;intéresse d&#8217;une application Java pré-existante, c&#8217;est plus l&#8217;inverse dont je vais avoir besoin.</p>
<p>Prenons donc un code utilitaire en Scala :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">object</span> ListUtils <span style="color: #F78811;">&#123;</span>
    <span style="color: #0000ff; font-weight: bold;">def</span> length<span style="color: #F78811;">&#91;</span>A<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>A<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Int <span style="color: #000080;">=</span>
        ls <span style="color: #0000ff; font-weight: bold;">match</span> <span style="color: #F78811;">&#123;</span>
            <span style="color: #0000ff; font-weight: bold;">case</span> Nil <span style="color: #000080;">=&gt;</span> <span style="color: #F78811;">0</span>
            <span style="color: #0000ff; font-weight: bold;">case</span> <span style="color: #000080;">_</span> <span style="color: #000080;">::</span> tail <span style="color: #000080;">=&gt;</span> <span style="color: #F78811;">1</span> + length<span style="color: #F78811;">&#40;</span>tail<span style="color: #F78811;">&#41;</span>
        <span style="color: #F78811;">&#125;</span>
<span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p>Premier test simpliste en Java :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    java.<span style="color: #006633;">util</span>.<span style="color: #006633;">List</span><span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span> listeTest <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> java.<span style="color: #006633;">util</span>.<span style="color: #006633;">ArrayList</span><span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    listeTest.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;un&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    listeTest.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;deux&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Taille : &quot;</span> <span style="color: #339933;">+</span> ListUtils.<span style="color: #006633;">length</span><span style="color: #009900;">&#40;</span>listeTest<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>On tente de compiler, et les premiers soucis ne se font pas attendre :</p>
<blockquote><p>&lt;A&gt;length(scala.collection.immutable.List&lt;A&gt;) in org.courtine.scala.ListUtils cannot be applied to &lt;java.lang.String&gt;(java.util.List&lt;java.lang.String&gt;)</p></blockquote>
<p>L&#8217;erreur a le mérite d&#8217;être explicite. Il ne nous reste donc qu&#8217;à convertir notre <em>java.util.List</em> en <em>scala.collection.immutable.List</em>. Je n&#8217;ai pas encore réussi à faire cette conversion côté Java. En revanche, c&#8217;est une conversion assez simple côté Scala. Il suffit donc de créer dans notre classe utilitaire Scala une méthode supplémentaire :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">def</span> length<span style="color: #F78811;">&#91;</span>A<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>ls<span style="color: #000080;">:</span> java.<span style="color: #000000;">util</span>.<span style="color: #000000;">List</span><span style="color: #F78811;">&#91;</span>A<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Int <span style="color: #000080;">=</span> length<span style="color: #F78811;">&#40;</span>ls.<span style="color: #000000;">toArray</span>.<span style="color: #000000;">toList</span><span style="color: #F78811;">&#41;</span></pre></td></tr></table></div>

<p>On recompile et on exécute l&#8217;ensemble : ça marche !</p>
<p>Après ce test utilitaire, un autre test concluant : une classe métier Scala peut être instanciée et utilisée directement dans le code Java, sans aménagement particulier (du moins une classe simple : je n&#8217;ai pas encore essayé de mettre en défaut cette compatibilité avec des cas tordus).</p>
<h3>Automatiser le build</h3>
<p>Ces premiers tests étant concluants, passons à l&#8217;étape du build : l&#8217;exécution des tests se passe bien dans IntelliJ, mais une fois sorti de l&#8217;<acronym title="Integrated Development Environment">IDE</acronym>, peut-on assurer un build automatisé (tests, intégration continue, etc.).</p>
<p>Pour les projets sur lesquels je travaille, le build est assuré par <a href="http://maven.apache.org/">Maven</a>. Après une recherche rapide, on découvre qu&#8217;il existe un <a href="http://scala-tools.org/mvnsites/maven-scala-plugin/">plugin Scala pour Maven</a>. Voici donc le fichier pom de mon projet :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;project</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://maven.apache.org/POM/4.0.0&quot;</span> <span style="color: #000066;">xmlns:xsi</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span>         <span style="color: #000066;">xsi:schemaLocation</span>=<span style="color: #ff0000;">&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;modelVersion<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>4.0.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/modelVersion<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.courtine<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>scala-java-test<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;packaging<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>jar<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/packaging<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>scala-java-test<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;repositories<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;repository<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>scala-tools.org<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Scala-tools Maven2 Repository<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://scala-tools.org/repo-releases<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/repository<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/repositories<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pluginRepositories<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pluginRepository<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>scala-tools.org<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Scala-tools Maven2 Repository<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://scala-tools.org/repo-releases<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/pluginRepository<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/pluginRepositories<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;build<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plugins<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.scala-tools<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>maven-scala-plugin<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;executions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>compile<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>compile<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>compile<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>test-compile<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>testCompile<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>test-compile<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>process-resources<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/phase<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>compile<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goal<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/goals<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/execution<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/executions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>maven-compiler-plugin<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;source<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.6<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/source<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.6<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plugin<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plugins<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/build<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependencies<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.scala-lang<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>scala-library<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>2.9.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>junit<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>junit<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>4.8.2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;scope<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>test<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/scope<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependencies<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/project<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p lang="xml">Ce fichier automatise convenablement le packaging de l&#8217;application par Maven.</p>
<h3 lang="xml">Et maintenant</h3>
<p>D&#8217;après ces premiers tests, il semble donc qu&#8217;on puisse créer une application mélangeant du code Scala et Java, avec un coût d&#8217;entrée faible (du point de vue des adaptations à effectuer : j&#8217;exclue ici le coût d&#8217;apprentissage du langage Scala lui-même, qui est loin d&#8217;être négligeable).</p>
<p>La prochaine étape sera d&#8217;essayer de vérifier si un tel mélange de codes n&#8217;est pas préjudiciable aux performances.</p>
<p>L&#8217;étape suivante sera certainement la plus compliquée : convaincre un client des avantages d&#8217;un tel mélange (code plus expressif sur les parties métier du projet), pour pouvoir le mettre en oeuvre sur un véritable projet.
<div class="tweetmeme_button" style="float: left; margin-left: 10px; margin-right: 20px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F05%2F24%2Fpremiers-pas-en-scala%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.courtine.org%2F2011%2F05%2F24%2Fpremiers-pas-en-scala%2F&amp;style=normal&amp;service=bit.ly&amp;service_api=bcourtine%3AR_adaa69f468b94402bc961e78ad01d140&amp;hashtags=Java-JEE,Maven,Scala&amp;b=2" height="61" width="50" /><br />
			</a>
		</div> <p><a href="http://blog.courtine.org/?flattrss_redirect&amp;id=767&amp;md5=be2c9319528d9cbfc3804f5ea0d1f6d2" title="Flattr" target="_blank"><img src="http://blog.courtine.org/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.courtine.org/2011/05/24/premiers-pas-en-scala/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=bcourtine&amp;popout=1&amp;url=http%3A%2F%2Fblog.courtine.org%2F2011%2F05%2F24%2Fpremiers-pas-en-scala%2F&amp;language=fr_FR&amp;category=text&amp;title=Premiers+pas+en+Scala&amp;description=Cela+fait+maintenant+pas+mal+de+temps+que+j%26%238217%3Bentends+parler+de+Scala%2C+mais+je+n%26%238217%3Bavais+jamais+pris+le+temps+m%26%238217%3By+attarder.+Il+y+a+maintenant+deux+semaines%2C+l%26%238217%3Bannonce+du+lancement...&amp;tags=Java-JEE%2CMaven%2CScala%2Cblog" type="text/html" />
	</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
