<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3929106467046424972</id><updated>2011-10-17T10:29:26.957+02:00</updated><category term='C#'/><category term='xml'/><category term='google app engine'/><category term='transaction'/><category term='jsf'/><category term='agile'/><category term='maven hibernate'/><category term='WCF'/><category term='ejb'/><category term='news'/><category term='jpa'/><category term='REST'/><category term='spring'/><category term='jaxp'/><category term='GAE'/><category term='eclipse'/><category term='jee'/><category term='javascript i18n'/><category term='myfaces'/><category term='.NET'/><title type='text'>new Blog("jclagache");</title><subtitle type='html'>A propos de Web, Enterprise Java &amp;amp; .NET Applications et autres sujets ennuyeux ...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-2378015264274122940</id><published>2011-05-20T11:43:00.014+02:00</published><updated>2011-05-23T09:34:36.549+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>Client WCF et HTTP Basic Authentification</title><content type='html'>WCF propose 2 protocoles pour cela : &lt;a href="http://msdn.microsoft.com/fr-fr/library/system.servicemodel.basichttpbinding.aspx" target="_blank"&gt;BasicHttpBinding&lt;/a&gt; et &lt;a href="http://msdn.microsoft.com/fr-fr/library/system.servicemodel.wshttpbinding.aspx" target="_blank"&gt;WSHttpBinding&lt;/a&gt; avec des caractéristiques différentes. Parmi celles-ci, la version SOAP des messages échangés doit être de version SOAP 1.1 pour&amp;nbsp; &lt;a href="http://msdn.microsoft.com/fr-fr/library/system.servicemodel.basichttpbinding.aspx" target="_blank"&gt;BasicHttpBinding&lt;/a&gt; et SOAP 1.2 pour &lt;a href="http://msdn.microsoft.com/fr-fr/library/system.servicemodel.wshttpbinding.aspx" target="_blank"&gt;WSHttpBinding&lt;/a&gt;.&lt;br /&gt;En partant du principe, que le web service cible est implémenté en SOAP 1.2, la seule solution devient &lt;a href="http://msdn.microsoft.com/fr-fr/library/system.servicemodel.wshttpbinding.aspx" target="_blank"&gt;WSHttpBinding&lt;/a&gt;. Sauf que … &lt;a href="http://msdn.microsoft.com/fr-fr/library/system.servicemodel.wshttpbinding.aspx" target="_blank"&gt;WSHttpBinding&lt;/a&gt; impose soit une sécurité sur le transport (SSL) ou sur le message (certificat X.509). Il n’existe donc aucune solution dans WCF pour utiliser un service web basé sur HTTP Basic Auth sans protection (très mauvaise pratique, je l’accorde …).&lt;br /&gt;La seule solution est donc un &lt;a href="http://msdn.microsoft.com/en-us/library/aa347793.aspx" target="_blank"&gt;CustomBinding&lt;/a&gt; surchargeant &lt;a href="http://msdn.microsoft.com/fr-fr/library/system.servicemodel.basichttpbinding.aspx" target="_blank"&gt;BasicHttpBinding&lt;/a&gt; en lui imposant comme version de message SOAP 1.2.&lt;br /&gt;&lt;pre class="csharp:nogutter:nocontrols" name="code"&gt;public class MyBasicHttpBinding : BasicHttpBinding&lt;br /&gt;    {&lt;br /&gt;        public override BindingElementCollection CreateBindingElements()&lt;br /&gt;        {&lt;br /&gt;            Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;&lt;br /&gt;            Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;&lt;br /&gt;            BindingElementCollection bc = base.CreateBindingElements();&lt;br /&gt;            bc.Remove(bc.Find&amp;lt;textmessageencodingbindingelement&amp;gt;());&lt;br /&gt;            //Transport binding element must be the last&lt;br /&gt;            bc.Insert(0, new TextMessageEncodingBindingElement { MessageVersion = MessageVersion.Soap12 });&lt;br /&gt;            return bc;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pour le client : &lt;br /&gt;&lt;pre class="csharp:nogutter:nocontrols" name="code"&gt;var client = new MyWebserviceClient(new MyBasicHttpBinding(), new EndpointAddress("http://localhost:8090/MyWebservice"));&lt;br /&gt;client.ClientCredentials.UserName.UserName = "my_user";&lt;br /&gt;client.ClientCredentials.UserName.Password = "my_key";&lt;br /&gt;client.doSomething();&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-2378015264274122940?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/2378015264274122940/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=2378015264274122940' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/2378015264274122940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/2378015264274122940'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2011/05/client-wcf-et-http-basic.html' title='Client WCF et HTTP Basic Authentification'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-9186866982766638855</id><published>2011-04-05T14:46:00.001+02:00</published><updated>2011-04-05T14:49:25.979+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='jee'/><title type='text'>Spring comme provider JPA au sein d’un conteneur EE5</title><content type='html'>Notamment dans &lt;a href="http://www.jboss.org/jbossas/" target="_blank"&gt;JBoss 5&lt;/a&gt;, cela pose un problème. En effet, le conteneur va scanner l’ensemble des librairies pour trouver le ou les fichiers de définitions des “persistence units” (&lt;i&gt;&lt;b&gt;META-INF/persistence.xml&lt;/b&gt;&lt;/i&gt;). Or, lorsque l’on souhaite que ce soit &lt;a href="http://www.springsource.org/" target="_blank"&gt;Spring&lt;/a&gt; qui gère la création de l’”&lt;i&gt;&lt;b&gt;&lt;a href="http://download.oracle.com/javaee/5/api/javax/persistence/EntityManagerFactory.html" target="_blank"&gt;EntityManagerFactory&lt;/a&gt;&lt;/b&gt;&lt;/i&gt;”, ce fichier de définition peut être très succinct : &lt;br /&gt;&lt;pre class="xml:nogutter:nocontrols" name="code"&gt;&amp;lt;persistence xmlns=&amp;amp;&amp;lt;persistence xmlns="http://java.sun.com/xml/ns/persistence" &lt;br /&gt;    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" &lt;br /&gt;    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence &lt;br /&gt;    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" &lt;br /&gt;    version="2.0"&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;persistence-unit name="myPersistenceUnit"&amp;gt;&lt;br /&gt;  &amp;lt;class&amp;gt;model.MyEntityClass&amp;lt;/class&amp;gt;  &lt;br /&gt; &amp;lt;/persistence-unit&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;lt;/persistence&amp;gt;&lt;br /&gt;&lt;/pre&gt;Cette description ne permettra pas au conteneur EE5 de démarrer cette “persistence unit” en l’absence de source de données.&lt;br /&gt;Par exemple, sous &lt;a href="http://www.jboss.org/jbossas/" target="_blank"&gt;JBoss 5&lt;/a&gt; le serveur indiquera qu’une spécification n’est pas respectée :&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Specification violation [EJB3 JPA 6.2.1.2] - You have not defined a non-jta-data-source for a RESOURCE_LOCAL enabled persistence context named: myPersistenceUni&lt;/b&gt;t&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;La solution consiste a renommer le fichier &lt;a href="http://download.oracle.com/docs/cd/B31017_01/web.1013/b28221/cfgdepds005.htm" target="_blank"&gt;persistence.xml&lt;/a&gt; de telle sorte qu’il ne soit pas pris en compte par le serveur (exemple : jpa-persistence.xml).&lt;br /&gt;Mais cela ne suffit pas : le conteneur va aussi scanner toutes les classes à la recherche de l’annotation&amp;nbsp; &lt;b&gt;&lt;i&gt;&lt;a href="http://download.oracle.com/javaee/5/api/javax/persistence/PersistenceContext.html" target="_blank"&gt;@PersistenceContext&lt;/a&gt;&lt;/i&gt;&lt;/b&gt; et sera incapable de charger la “persistence-unit” correspondante.&lt;br /&gt;Là, l’attribut&lt;b&gt;&lt;i&gt; &lt;a href="http://java.sun.com/developer/technicalArticles/JavaEE/JavaEE6Overview_Part2.html" target="_blank"&gt;metadata-complete&lt;/a&gt;&lt;/i&gt;&lt;/b&gt; de l’élément web-app du fichier de configuration web.xml permet de préciser au conteneur de ne pas prendre en compte les annotations Java EE parce qu'elles sont gérées pas un autre mécanisme (&lt;a href="http://www.springsource.org/" target="_blank"&gt;Spring&lt;/a&gt; en l’occurrence dans notre cas).&lt;br /&gt;&lt;pre class="xml:nogutter:nocontrols" name="code"&gt;&amp;lt;web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5" metadata-complete="true"&amp;gt;&lt;br /&gt;&amp;lt;/web-app&amp;gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-9186866982766638855?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/9186866982766638855/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=9186866982766638855' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/9186866982766638855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/9186866982766638855'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2011/04/spring-comme-provider-jpa-au-sein-dun.html' title='Spring comme provider JPA au sein d’un conteneur EE5'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-8212068920238566879</id><published>2010-10-28T14:28:00.004+02:00</published><updated>2010-11-03T14:01:11.679+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>L’ Agile Tour 2010 - Rouen</title><content type='html'>&lt;img align="right" src="http://lh6.ggpht.com/_xDQQ-Ux8s_A/TMqNsECrBwI/AAAAAAAAAgQ/9B-cv1YdgjE/s512/agilii_logo.jpg" style="display: inline; float: right; margin: 5px;" /&gt;Grâce au soutient du &lt;a href="http://www.normandyjug.org/" target="_blank"&gt;Normandy JUG&lt;/a&gt;, L’&lt;a href="http://www.agiletour.org/" target="_blank"&gt;Agile Tour 2010&lt;/a&gt; faisait une étape à Rouen ce 27 octobre dans les locaux du &lt;a href="http://www.cesi-entreprises.fr/centre/centre.asp?centre=_level0.mont_st_aignan_btn" target="_blank"&gt;cesi&lt;/a&gt; à Mont Saint Aignan. C’était pour moi l’occasion de clarifier tous ces termes qui inondent la littérature sur la gestion de projet et l’agilité : “backlog”, “sprint”, “burdown chart”, etc … &lt;br /&gt;Je vais pas mentir, j’ai rater la keynote de 13h30 … et je penses que cela a été préjudiciable pour la suite. En effet, j’ai eu l’impression de rentrer tout de suite dans le vif du sujet sans réel vue globale de haut niveau, sans comparaison avec d’autres modèles de gestion de projet ou plutôt LE modèle de gestion de projet qui a trôné pendant des années : le cycle en V.&lt;br /&gt;&lt;h2&gt;L’adoption de l’agilité par les usages – Xavier Warzee&lt;/h2&gt;Je me suis trompé de salle … mais c’est trop tard, le speakeur commence. Les logos “Microsoft” et “MSN” sur le rétro projecteur me font penser que je vais avoir droit à une présentation commerciale de &lt;a href="http://www.microsoft.com/visualstudio/en-us/products/2010-editions/ultimate" target="_blank"&gt;Visual Studio Team System&lt;/a&gt;. Et bien non, &lt;a href="http://www.jroller.com/xwarzee/" target="_blank"&gt;Xavier Warzee&lt;/a&gt; présente et explique ce qui fait le succès d’un taskboard : l’interactivité par le touché. Il est scientifiquement prouvé que la collaboration est plus efficace par l’approche tactile (touch). Ainsi, un tableau avec des post-it est un moyen très efficace d’organiser ses backlogs et tasks avec un public qui n’est plus que spectateur mais aussi acteur et appréhende cet exercice comme un jeu. Il faut cependant dématérialiser cette pratique pour d’une part conserver un historique des changements et éviter une double saisie vers le SI.&lt;br /&gt;Xavier Warzee nous présente alors les solutions Microsoft face à cette demande : &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://urbanturtle.com/" target="_blank"&gt;Urban Turtle&lt;/a&gt; : l’outil de &lt;a href="http://pyxis-tech.com/fr/accueil" target="_blank"&gt;Pyxis&lt;/a&gt; qui s’interface avec &lt;a href="http://msdn.microsoft.com/en-us/vstudio/ff637362.aspx" target="_blank"&gt;TFS&lt;/a&gt; pour le planning board et la gestion de product backlog est aussi disponible sur une tablette à écran tactile sous Windows 7.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://labs.access-it.net/en-US/Projects/TFS/TeamTable" target="_blank"&gt;Team Table&lt;/a&gt; et TFS 2010 : Microsoft Surface et &lt;a href="http://msdn.microsoft.com/en-us/vstudio/ff637362.aspx" target="_blank"&gt;TFS&lt;/a&gt; collaborent pour fournir un plan interactif tactile de post-it virtuels pour les daily meeting.&lt;/li&gt;&lt;/ul&gt;Les fabricants planchent sur des versions en 3D, où les utilisateurs manipulent ces métaphores (post-it) dans l’espace. Bon, si je peux comprendre l’intérêt de ces tableaux virtuels pour la collaboration, je doute qu’une infrastructure à la “Minority Report” soit indispensable … &lt;br /&gt;&lt;h2&gt;Intégration continue – Dimitri Vaeli&lt;/h2&gt;Le programme annonçait “Une approche imagée sur l’éligibilité et la contractualisation Agile par Laurent Morisseau”. Il a certainement été précisé lors de la keynote que Laurent Morisseau n’était pas là et que sa présentation était remplacée … C’est &lt;a href="http://twitter.com/dbaeli" target="_blank"&gt;Dimitri Vaeli&lt;/a&gt;, d’&lt;a href="http://www.exoplatform.com/" target="_blank"&gt;eXo Platform&lt;/a&gt;, qui reprend une version actualisée et étoffée semble t’il d’une précédente présentation sur le sujet lors du &lt;a href="https://docs.google.com/present/view?id=dfkhzdx4_33csmvbpct" target="_blank"&gt;Normandy JUG du 16/09/2009&lt;/a&gt;. Au menu, une des composantes de l’agilité : l’intégration continue (même si le concept existait bien avant la création de la méthode agile). L’intégration continue consiste à vérifier de manière systématique (au commit et(ou) à intervalle régulier) la non régression du logiciel. Cela passe par une automatisation complète de la phase de build (compilation, tests unitaires, analyse qualité, tests de déploiement, d’intégration, génération de la documentation, packaging et publication). Même si le concept m’est plutôt familier, j’ai pu noter quelques nom d’outils que je ne connaissais pas comme &lt;a href="http://www.greenpeppersoftware.com/" target="_blank"&gt;GreenPepper&lt;/a&gt; de … &lt;a href="http://pyxis-tech.com/fr/accueil" target="_blank"&gt;Pyxis&lt;/a&gt;. Mais là on n’est plus du tout en collaboration avec TFS mais plutôt avec les outils d’&lt;a href="http://www.atlassian.com/" target="_blank"&gt;Atlassian&lt;/a&gt;. Déjà convaincu de la qualité et efficacité des autres outils (&lt;a href="http://www.atlassian.com/software/jira/" target="_blank"&gt;JIRA&lt;/a&gt;, &lt;a href="http://www.atlassian.com/software/confluence/" target="_blank"&gt;Confluence&lt;/a&gt;, …) de cet éditeur, je ne peux qu’approfondir l’utilisation de &lt;a href="http://www.greenpeppersoftware.com/" target="_blank"&gt;GreenPepper&lt;/a&gt;. D’ailleurs, il est fort probable que l’ALM d’eXo Platform soit géré par ces outils … L’une des difficultés dans l’intégration continue sont les tests ou plutôt comment distinguer les tests unitaires, des tests d’intégration. Pour moi les frontières entre ces tests sont souvent floues et poreuses. &lt;a href="http://twitter.com/dbaeli" target="_blank"&gt;Dimitri Vaeli&lt;/a&gt; ne m’a pas éclairé davantage, c’est en effet un exercice difficile aussi d’après lui. Nous sommes tout de même arrivé à la conclusion suivante :  &lt;br /&gt;&lt;ul&gt;&lt;li&gt;dans les test unitaires, on teste une classe unitairement. On “Mock” les objets en relation avec la classe à tester pour se concentrer uniquement sur les algorithmes qui la compose.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;dans les tests d’intégration, ces relations doivent être implémentées. Ces tests doivent être répartis suivant le degré de qualité que l’on veut vérifier. Ainsi, ces tests d’intégration peuvent à la fois prendre la forme de tests &lt;a href="http://www.junit.org/" target="_blank"&gt;JUnit&lt;/a&gt; (ou &lt;a href="http://testng.org/" target="_blank"&gt;TestNG&lt;/a&gt;) mais aussi de tests &lt;a href="http://seleniumhq.org/" target="_blank"&gt;Selenium&lt;/a&gt; (ou &lt;a href="http://abbot.sourceforge.ne/" target="_blank"&gt;Abbot&lt;/a&gt;) pour une couverture encore plus élargie.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Optimiser le retour sur investissement de votre produit avec une bonne priorisation de votre backlog – Céline Stauder&lt;/h2&gt;Je suis pour l’instant un peu déçu : même si j’ai apprécié les 2 premières présentations, je n’ai toujours pas clarifier la vision que je me faisait de l’agilité. Je n’ai certainement pas choisis les présentations adéquates pour ce genre de questionnement.  &lt;a href="http://fr.linkedin.com/pub/c%C3%A9line-stauder/a/b99/915" target="_blank"&gt;Céline Stauder&lt;/a&gt; de &lt;a href="http://www.clt-services.com/" target="_blank"&gt;CLT Services&lt;/a&gt; propose une vision orientée service produits de la méthode et dès les premiers slides de sa présentation, je sens que c’est ce point de vue qui va m’éclairer. Tout d’abord quelques définitions :  &lt;br /&gt;&lt;ul&gt;&lt;li&gt;product backlog : ensemble de user stories priorisées&lt;br /&gt;&lt;/li&gt;&lt;li&gt;product owner : le “maitre” du projet&lt;br /&gt;&lt;/li&gt;&lt;li&gt;user story (US) : fonctionnalité vue par l’utilisateur. Par exemple, en tant que rôle X dans le produit je veux pouvoir faire ça.&lt;/li&gt;&lt;/ul&gt;&lt;img align="left" src="http://lh4.ggpht.com/_xDQQ-Ux8s_A/TMqIC9yGhLI/AAAAAAAAAgA/x5nK__BaWoE/s512/normal_User_Stories_-_60_minutes_small.jpg" style="display: inline; float: left; margin: 5px;" /&gt;  Céline Stauder détaille ensuite les méthodes de priorisation des US. C’est cette priorisation par “backlog en map” qui va donner le roadmap. Les US les plus pertinentes seront en effet dans la première release.  La méthode présentée est la priorisation relative de &lt;a href="http://blog.mountaingoatsoftware.com/" target="_blank"&gt;Mike Cohn&lt;/a&gt;. L’idée est de prendre une US de référence et de comparer les autres US par rapport à celle-ci.     On arrive ensuite à une classification des US dans le backlog :  &lt;img src="http://lh4.ggpht.com/_xDQQ-Ux8s_A/TMqIC28Gc-I/AAAAAAAAAgE/xE5ewtRrczo/s512/iceberg_list_2.png" style="margin: 5px;" /&gt; &lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;Suivant ce que j’attendais de cette après-midi, je penses qu’assister à d’autres sessions m’aurait été plus profitable, notamment l’&lt;b&gt;Introduction à Scrum par Guillaume Lours&lt;/b&gt; et l’atelier de &lt;b&gt;Planning Poker de Youen Chéné&lt;/b&gt;. Cependant, les 3 présentations auxquelles j’ai pu assisté m’ont toutes semblées intéressantes et toutes animées par des personnes passionnées. Ce type d’évènement est fait par des agilistes, &lt;strike&gt;pour des agilistes&lt;/strike&gt; pour tout public même si quelques notions de base sur la méthode sont préférables pour profiter des différents speakeurs. En tout cas, une belle initiative du &lt;a href="http://twitter.com/NormandyAgile" target="_blank"&gt;Normandy Agile Group&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-8212068920238566879?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/8212068920238566879/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=8212068920238566879' title='4 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/8212068920238566879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/8212068920238566879'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2010/10/l-agile-tour-2010-rouen.html' title='L’ Agile Tour 2010 - Rouen'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_xDQQ-Ux8s_A/TMqNsECrBwI/AAAAAAAAAgQ/9B-cv1YdgjE/s72-c/agilii_logo.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-2224267367127684788</id><published>2009-12-10T17:46:00.003+01:00</published><updated>2009-12-11T11:10:30.273+01:00</updated><title type='text'>Intégration de l’API Zoho Report dans Spring</title><content type='html'>&lt;a href="http://reports.zoho.com/" target="_blank"&gt;Zoho Report&lt;/a&gt; permet de réaliser facilement en ligne des rapports et graphiques efficaces. &lt;br /&gt;Une &lt;a href="http://zohoreportsapi.wiki.zoho.com/Zoho-Reports-API.html" target="_blank"&gt;API REST&lt;/a&gt; est disponible pour soumettre ou récupérer des données dans ou depuis Zoho Report. Ce format n’est pas le plus adapté pour manipuler un nombre important de données organisées au sein d’une base de données. &lt;a href="http://zohoreportsapi.wiki.zoho.com/Zoho-Reports-CloudSQL.html" target="_blank"&gt;Zoho CloudSQL&lt;/a&gt; permet d’effectuer ces manipulations par requête SQL. Un &lt;a href="http://zohoreportsapi.wiki.zoho.com/JDBC-Driver.html" target="_blank"&gt;driver JDBC&lt;/a&gt; vient compléter le tout pour offrir une véritable connectivité à cette base de donnée “on the cloud”.&lt;br /&gt;Cependant, &lt;a href="http://zohoreportsapi.wiki.zoho.com/Zoho-Reports-CloudSQL.html" target="_blank"&gt;CloudSQL&lt;/a&gt; et donc le &lt;a href="http://zohoreportsapi.wiki.zoho.com/JDBC-Driver.html" target="_blank"&gt;driver JDBC&lt;/a&gt; ne permettent, pour l’instant, que de la récupération de données (SELECT).&lt;br /&gt;Pour utiliser complètement les possibilités de &lt;a href="http://reports.zoho.com/" target="_blank"&gt;Zoho Report&lt;/a&gt;, le mieux est donc d’utiliser les librairies clientes disponibles (Java, Python et Google App Engine).&lt;br /&gt;Pour Java, pour utiliser la librairie, il faut : &lt;br /&gt;&lt;ul&gt;&lt;li&gt;télécharger la librairie sur &lt;a href="http://zohoreportsapi.wiki.zoho.com/Java-Client-Library.html" target="_blank"&gt;cette page&lt;/a&gt; &lt;/li&gt;&lt;li&gt;avoir un compte Zoho (LOGINNAME,PASSWORD) &lt;/li&gt;&lt;li&gt;demander une &lt;a href="http://writer.zoho.com/apikey.htm" target="_blank"&gt;clé API&lt;/a&gt; (APIKEY) &lt;/li&gt;&lt;li&gt;une base de donnée crée (DATABASENAME) avec au mois une table (TABLENAME) &lt;/li&gt;&lt;/ul&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;ReportClient rc = new ReportClient(APIKEY);&lt;br /&gt;rc.login(LOGINNAME,PASSWORD);&lt;br /&gt;String uri = getURI(LOGINNAME,DATABASENAME,TABLENAME);&lt;br /&gt;rc.addRow(uri, new HashMap(), null);&lt;/pre&gt;Le but ici est d’utiliser &lt;a href="http://www.springsource.org/" target="_blank"&gt;Spring&lt;/a&gt; pour simplifier la gestion du client et de ses constantes de configuration (APIKEY, LOGINNAME, PASSWORD et DATABASENAME) :&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;ZohoReportClientWrapper rc = (ZohoReportClientWrapper) ctx.getBean("zohoClient");&lt;br /&gt;rc.login();&lt;br /&gt;rc.addRow("sampleTable", new HashMap());&lt;/pre&gt;Avec comme fichier de configuration Spring : &lt;br /&gt;&lt;pre class="xml:nogutter:nocontrols" name="code"&gt;&lt;bean class="ZohoConfig" id="zohoConfig"&gt;&lt;br /&gt;&amp;lt;bean id="zohoConfig" class="ZohoConfig"&amp;gt;&lt;br /&gt;&amp;lt;property name="apiKey" value="yourAPIKey"/&amp;gt;&lt;br /&gt;&amp;lt;property name="databaseName" value="yourDBName"/&amp;gt;&lt;br /&gt;&amp;lt;property name="loginName" value="yourZohoLogin"/&amp;gt;&lt;br /&gt;&amp;lt;property name="password" value="yourZohoPasswd"/&amp;gt; &lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="zohoClient" class="ZohoReportClientWrapper" init-method="init"&amp;gt;&lt;br /&gt;&amp;lt;property name="config" ref="zohoConfig"/&amp;gt; &lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/bean&gt;&lt;/pre&gt;Pour cela, j’ai crée un projet Google : &lt;a href="http://code.google.com/p/spring-zohoreport/"&gt;spring-zohoreport&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-2224267367127684788?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/2224267367127684788/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=2224267367127684788' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/2224267367127684788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/2224267367127684788'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2009/12/integration-de-lapi-zoho-report-dans.html' title='Intégration de l’API Zoho Report dans Spring'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-8251190798394469562</id><published>2009-10-21T17:02:00.005+02:00</published><updated>2010-10-15T23:02:42.015+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='google app engine'/><title type='text'>Google App Engine (GAE) : création d'un environnement de développement</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://code.google.com/intl/fr/appengine/images/appengine_lowres.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://code.google.com/intl/fr/appengine/images/appengine_lowres.gif" /&gt;&lt;/a&gt;&lt;/div&gt;Installation et configuration pas à pas d'un environnement de développement java pour Google App Engine.&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;Installation du SDK Java&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Google App Engine supporte Java 5 et Java 6. Cependant, l'application tournera sous Java 6 dans App Engine. Il est donc naturellement préférable que l'environnement de développement soit configuré en Java 6.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Tips : localisation des SDKs sur le disque&lt;br /&gt;Créer un dossier "SDKs" sur votre disque dur. Par exemple, sous Windows, je l'ai créer sous C:\SDKs.&lt;br /&gt;Créer une variable d'environnement pour ce dossier (SDKS_HOME).&lt;br /&gt;C'est dans ce répertoire SDKS_HOME que vous pourrez installer les différentes versions de SDK.&lt;br /&gt;Par exemple sous Windows, pour créer des variables d'environnement il faut soit aller dans Panneau de Configuration -&amp;gt; Système ou clique droit sur le bureau dans Poste De Travail -&amp;gt; Propriétés. &lt;br /&gt;Cliquer alors sur l'onglet Avancé puis sur le bouton Variables d'environnement.&lt;br /&gt;Entrer les variables suivantes dans Variables Systèmes :&lt;br /&gt;SDKS_HOME = C:\SDKs&lt;br /&gt;JAVA_HOME = %SDKS_HOME%\jdk1.6.0_16&lt;br /&gt;Rajouter %JAVA_HOME%\bin à la variable PATH&lt;br /&gt;Tout ceci permet de "switcher" rapidement de version de Java,&lt;br /&gt;simplement en modifiant la variable JAVA_HOME.&lt;/blockquote&gt;&lt;br /&gt;Télécharger et installer le &lt;a href="http://java.sun.com/javase/downloads/index.jsp"&gt;Java SE Development Kit (JDK)&lt;/a&gt;. Pour vérifier l'installation, vérifier le numéro de version retourné par ces lignes de commande.&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;java -version&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;javac -version&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;Installation d'Eclipse et du Plugin Google&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Un plugin Google pour Eclipse est disponible. Celui-ci est disponible pour les versions  Eclipse 3.3 (Europa), Eclipse 3.4 (Ganymede) and Eclipse 3.5 (Galileo). Le dernière version Eclipse à l'écriture de ce post est la version 3.5 (Galileo).&lt;br /&gt;&lt;a href="http://www.eclipse.org/downloads/"&gt;Télécharger et installer Eclipse 3.5 (Galileo)&lt;/a&gt; Il est préférable de choisir le package Eclipse IDE for Java EE Developers pour profiter aussi  du plugin &lt;a href="http://www.eclipse.org/webtools/"&gt;Web Tools Platform (WTP)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Lancer Eclipse pour installer le Plugin Google par le Software Update d'Eclipse.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Selectionner &lt;b&gt;Help &lt;/b&gt;-&amp;gt; &lt;b&gt;Install New Software&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Dans la zone de texte &lt;b&gt;Work with&lt;/b&gt; taper &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;http://dl.google.com/eclipse/plugin/3.5&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Cliquer sur le bouton &lt;b&gt;Add &lt;/b&gt;puis sur &lt;b&gt;OK &lt;/b&gt;dans la zone de dialogue.&lt;/li&gt;&lt;li&gt;Cocher les composants "&lt;b&gt;Google Plugin for Eclipse 3.5&lt;/b&gt;" et "&lt;b&gt;Google App Engine Java SDK&lt;/b&gt;"("Google Web Toolkit SDK" pourra être installer plus tard si nécessaire).&lt;/li&gt;&lt;li&gt;Une fois l'installation terminée Eclipse doit être redémarré.&lt;/li&gt;&lt;/ol&gt;Voilà, il faut maintenant se lancer en &lt;a href="http://code.google.com/intl/fr/appengine/docs/java/gettingstarted/creating.html"&gt;créant son premier projet&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-8251190798394469562?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/8251190798394469562/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=8251190798394469562' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/8251190798394469562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/8251190798394469562'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2009/10/google-app-engine-gae-creation-dun.html' title='Google App Engine (GAE) : création d&apos;un environnement de développement'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-5514913077914615153</id><published>2009-05-27T15:25:00.009+02:00</published><updated>2009-05-27T15:54:03.337+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><title type='text'>Traitement asynchrone avec une api REST</title><content type='html'>Une des critiques faite sur REST est le fait de son attachement au protocole HTTP. Ce protocole est "déconnecté" : il est impossible de reprendre une connexion précédente. Cela pose un problème dans le cadre de longs traitements asynchrones et de notifications.&lt;br /&gt;&lt;br /&gt;Une possibilité pour palier à cette faiblesse est de considérer elle aussi cette transaction comme une ressource. Cette ressource est retournée immédiatement au client suite au premier appel. Ensuite, le client pourra récupérer l'état de cette transaction. Par exemple, supposons que nous souhaitons lancer un batch "batch1" de manière asynchrone :&lt;br /&gt;&lt;pre class="xml:nocontrols" name="code"&gt;&lt;br /&gt;GET /batchs/batch1  HTTP/1.1&lt;br /&gt;Host: xyz.com&lt;br /&gt;Content-Type: application/xml; charset=utf-8&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="xml:nocontrols" name="code"&gt;&lt;br /&gt;HTTP/1.1 200 OK&lt;br /&gt;Content-Type: application/xml; charset=utf-8&lt;br /&gt;Location: /transactions/1234&lt;br /&gt;&lt;ref&gt;http://xyz.com/transactions/1234&lt;/ref&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;La réponse est immédiatement renvoyée et contient l'URI de la transaction utilisée. Le client peut consulter cette ressource pour connaitre le status de son traitement en cours.&lt;br /&gt;&lt;pre class="xml:nocontrols" name="code"&gt;&lt;br /&gt;GET /transactions/1234 HTTP/1.1&lt;br /&gt;Host: xyz.com&lt;br /&gt;Content-Type: application/xml; charset=utf-8&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="xml:nocontrols" name="code"&gt;&lt;br /&gt;HTTP/1.1 200 OK&lt;br /&gt;Content-Type: application/xml; charset=utf-8&lt;br /&gt;Content-Length: nnn&lt;br /&gt;&lt;transaction&gt;&lt;br /&gt; &lt;type&gt;batch1&lt;/type&gt;&lt;br /&gt; &lt;status&gt;In Progress&lt;/status&gt;&lt;br /&gt;&lt;/transaction&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-5514913077914615153?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/5514913077914615153/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=5514913077914615153' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/5514913077914615153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/5514913077914615153'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2009/05/traitement-asynchrone-avec-une-api-rest.html' title='Traitement asynchrone avec une api REST'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-4081791457735106587</id><published>2009-02-06T17:42:00.010+01:00</published><updated>2010-10-18T12:26:59.486+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript i18n'/><title type='text'>Internationalisation (i18n) en Javascript</title><content type='html'>&lt;a href="http://www.blogger.com/post-edit.g?blogID=3929106467046424972&amp;amp;postID=4081791457735106587" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" src="http://www.desmm.com/wp-content/uploads/javascript.jpg" style="float: left; height: 194px; margin: 0pt 10px 10px 0pt; width: 230px;" /&gt;&lt;/a&gt;&lt;br /&gt;Difficile de gérer le multilinguisme (i18n) en Javascript ! Et pourtant, on est souvent tenté de rapidement écrire dans son code des messages destinés à l'utilisateur. La gestion a posteriori de plusieurs langues devient alors un casse tête. Mieux vaut anticipé et externaliser ses libellés.&lt;br /&gt;&lt;pre class="javascript:nogutter:nocontrols" name="code"&gt;var labels_fr =  {&lt;br /&gt;'hello' : 'Bonjour {0}, tu as {1} ans',&lt;br /&gt;'quit' : 'Quitter ?'&lt;br /&gt;}&lt;br /&gt;var labels_en =  {&lt;br /&gt;'hello' : 'Hello {0}, you are {1}',&lt;br /&gt;'quit' : 'Quit ?'&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;La classe ci-dessous permet d'obtenir simplement le libellé souhaité en fonction de la langue :&lt;br /&gt;&lt;pre class="javascript:nogutter:nocontrols" name="code"&gt;var i18n = new I18n();&lt;br /&gt;i18n.load(labels_fr);&lt;br /&gt;i18n.translate('hello','JC', '33');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Plus propre, non ?&lt;br /&gt;La classe en question &lt;b&gt;(UPDATE 18/10/2010 : prise en compte de plusieurs patterns)&lt;/b&gt; :&lt;br /&gt;&lt;pre class="javascript:nogutter:nocontrols" name="code"&gt;/**&lt;br /&gt;* I18n est une classe permettant d'obtenir un libellé&lt;br /&gt;* caractérisé par une clé dans une map contenant un&lt;br /&gt;* ensemble de libellés traduits dans la langue choisie&lt;br /&gt;* @constructor&lt;br /&gt;*/&lt;br /&gt;var I18n = function(){}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Charge la map de clés/libellés&lt;br /&gt;* @param {Object}  translations Les clés/libellés traduits&lt;br /&gt;* @constructor&lt;br /&gt;*/&lt;br /&gt;I18n.prototype.load = function(translations) {&lt;br /&gt;this._translations = translations;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Remplace les nombres entre accolades ({0}) par les&lt;br /&gt;* chaînes de caractères passées en paramètre&lt;br /&gt;* exemple  : _format('Hello {0} ! ', 'guy') =&amp;gt; Hello guy !&lt;br /&gt;* @param {String}  format La chaîne de caractère à formater&lt;br /&gt;*/&lt;br /&gt;I18n.prototype._format = function(format) {&lt;br /&gt;var args = arguments[1];&lt;br /&gt;return format.replace(/\{(\d+)\}/g, function(m, i){&lt;br /&gt;return args[i];&lt;br /&gt;});&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;*  Retrouve le libellé correspondant à la clé passée en paramètre&lt;br /&gt;* et le formate en fonction des paramètres supplémentaires&lt;br /&gt;* exemple  : translate('hello', 'guy') =&amp;gt; Hello guy !&lt;br /&gt;* @param {String}  key La clé à traduire&lt;br /&gt;*/&lt;br /&gt;I18n.prototype.translate = function(key) {&lt;br /&gt;if (typeof(this._translations)!='undefined' &amp;amp;&amp;amp; this._translations[key]) {&lt;br /&gt;return this._format(this._translations[key],Array.prototype.slice.call(arguments,1));&lt;br /&gt;}&lt;br /&gt;return key;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-4081791457735106587?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/4081791457735106587/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=4081791457735106587' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/4081791457735106587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/4081791457735106587'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2009/02/internationalisation-en-javascript.html' title='Internationalisation (i18n) en Javascript'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-7848806466864286319</id><published>2008-10-02T15:20:00.006+02:00</published><updated>2008-10-02T16:02:14.057+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='myfaces'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'>JSF (MyFaces) et TimeZone</title><content type='html'>Les spécifications JSF font que le fuseau horaire (timezone) par défaut d'une conversion Date -&gt; String est le GMT.&lt;br /&gt;Celui du serveur n'est pas pris en compte.&lt;br /&gt;Pour &lt;a href="http://myfaces.apache.org/"&gt;MyFaces&lt;/a&gt;, ces spécifications sont respectées depuis les versions supérieures à 1.1.0&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;package javax.faces.convert;&lt;br /&gt;...&lt;br /&gt;public class DateTimeConverter implements Converter, StateHolder {&lt;br /&gt;...&lt;br /&gt;  private static final TimeZone TIMEZONE_DEFAULT = TimeZone.getTimeZone("GMT");&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ainsi, il faudrait préciser le fuseau horaire dans toutes les pages affichant des dates si on souhaite en utiliser un autre.&lt;br /&gt;&lt;pre class="xml:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;&amp;lt;h:outputText value=&amp;quot;#{bean.date}&amp;quot;&amp;gt;&lt;br /&gt; &amp;lt;f:convertDateTime timeZone=&amp;quot;Europe/Paris&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/h:outputText&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Fastidieux!&lt;br /&gt;Le plus simple est d'écrire son propre &lt;span style="font-style:italic;"&gt;DateTimeConverter &lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;import java.util.TimeZone;&lt;br /&gt;import javax.faces.convert.DateTimeConverter;&lt;br /&gt;public class MyDateTimeConverter extends DateTimeConverter {&lt;br /&gt;  public MyDateTimeConverter() {&lt;br /&gt;    super();&lt;br /&gt;    setTimeZone(TimeZone.getDefault());&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;et de faire en sorte qu'il devienne le converter par défaut : &lt;br /&gt;&lt;pre class="xml:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;&amp;lt;converter&amp;gt;&lt;br /&gt;&amp;lt;converter-for-class&amp;gt;java.util.Date&amp;lt;/converter-for-class&amp;gt;&lt;br /&gt;&amp;lt;converter-class&amp;gt;MyDateTimeConverter&amp;lt;/converter-class&amp;gt;&lt;br /&gt;&amp;lt;/converter&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-7848806466864286319?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/7848806466864286319/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=7848806466864286319' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/7848806466864286319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/7848806466864286319'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2008/10/jsf-myfaces-et-timezone.html' title='JSF (MyFaces) et TimeZone'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-8510677171247243819</id><published>2008-06-03T16:36:00.015+02:00</published><updated>2008-08-25T15:09:26.529+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maven hibernate'/><title type='text'>Utilisation avancée du plugin Maven Hibernate 3</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mojo.codehaus.org/"&gt;&lt;img style="margin: 0pt 5px 5px 0pt; float: left; cursor: pointer; width: 199px;" src="http://mojo.codehaus.org/images/mojo_logo.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Le &lt;a href="http://mojo.codehaus.org/maven-hibernate3/hibernate3-maven-plugin/"&gt;plugin Maven Hibernate 3&lt;/a&gt; permet d'intégrer facilement &lt;a href="http://www.hibernate.org/"&gt;Hibernate 3&lt;/a&gt; au sein d'un projet géré par &lt;a href="http://maven.apache.org/"&gt;maven&lt;/a&gt;. Ce plugin est régulièrement maintenu et sa communauté réactive mais on peu cependant déplorer une documentation succincte.&lt;br /&gt;On y trouve en effet des exemples que pour des cas simples d'utilisation.&lt;br /&gt;Par exemple, on y trouve comment générer un schéma pour une base de donnée avec un seul fichier de configuration mais comment faire pour générer des schémas pour plusieurs bases de données, chacune possédant son propre fichier de configuration .hbm.&lt;br /&gt;Pour cela, il faut appeler plusieurs fois hbm2ddl :&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&lt;plugin&gt;&lt;br /&gt; &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;&lt;br /&gt; &lt;artifactId&gt;hibernate3-maven-plugin&lt;/artifactId&gt;&lt;br /&gt; &lt;version&gt;2.2-SNAPSHOT&lt;/version&gt;&lt;br /&gt; &lt;executions&gt;&lt;br /&gt;  &lt;execution&gt;&lt;br /&gt;   &lt;id&gt;generate-database-1&lt;/id&gt;&lt;br /&gt;   &lt;phase&gt;process-test-resources&lt;/phase&gt;&lt;br /&gt;   &lt;goals&gt;&lt;br /&gt;    &lt;goal&gt;hbm2ddl&lt;/goal&gt;&lt;br /&gt;   &lt;/goals&gt;&lt;br /&gt;   &lt;configuration&gt;&lt;br /&gt;    &lt;componentProperties&gt;&lt;br /&gt;     &lt;configurationfile&gt;target/classes/hibernate1.cfg.xml&lt;/configurationfile&gt;&lt;br /&gt;     &lt;propertyfile&gt;target/classes/jdbc1.properties&lt;/propertyfile&gt;&lt;br /&gt;    &lt;/componentProperties&gt;&lt;br /&gt;   &lt;/configuration&gt;&lt;br /&gt;  &lt;/execution&gt;&lt;br /&gt;  &lt;execution&gt;&lt;br /&gt;   &lt;id&gt;generate-database-2&lt;/id&gt;&lt;br /&gt;   &lt;phase&gt;process-test-resources&lt;/phase&gt;&lt;br /&gt;   &lt;goals&gt;&lt;br /&gt;    &lt;goal&gt;hbm2ddl&lt;/goal&gt;&lt;br /&gt;   &lt;/goals&gt;&lt;br /&gt;   &lt;configuration&gt;&lt;br /&gt;    &lt;componentProperties&gt;&lt;br /&gt;     &lt;configurationfile&gt;target/classes/hibernate2.cfg.xml&lt;/configurationfile&gt;&lt;br /&gt;     &lt;propertyfile&gt;target/classes/jdbc2.properties&lt;/propertyfile&gt;&lt;br /&gt;    &lt;/componentProperties&gt;&lt;br /&gt;   &lt;/configuration&gt;&lt;br /&gt;  &lt;/execution&gt;&lt;br /&gt; &lt;/executions&gt;&lt;br /&gt; &lt;dependencies&gt;&lt;br /&gt;  &lt;dependency&gt;&lt;br /&gt;   &lt;groupId&gt;${jdbc1.groupId}&lt;/groupId&gt;&lt;br /&gt;   &lt;artifactId&gt;${jdbc1.artifactId}&lt;/artifactId&gt;&lt;br /&gt;   &lt;version&gt;${jdbc1.version}&lt;/version&gt;&lt;br /&gt;  &lt;/dependency&gt;&lt;br /&gt;  &lt;dependency&gt;&lt;br /&gt;   &lt;groupId&gt;${jdbc2.groupId}&lt;/groupId&gt;&lt;br /&gt;   &lt;artifactId&gt;${jdbc2.artifactId}&lt;/artifactId&gt;&lt;br /&gt;   &lt;version&gt;${jdbc2.version}&lt;/version&gt;&lt;br /&gt;  &lt;/dependency&gt;&lt;br /&gt; &lt;/dependencies&gt;&lt;br /&gt;&lt;/plugin&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Cette logique reste vraie avec les autres "goals".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-8510677171247243819?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/8510677171247243819/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=8510677171247243819' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/8510677171247243819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/8510677171247243819'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2008/06/utilisation-avance-du-plugin-maven.html' title='Utilisation avancée du plugin Maven Hibernate 3'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-7364111266250318014</id><published>2008-03-27T15:15:00.008+01:00</published><updated>2008-12-15T14:14:47.718+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='jaxp'/><title type='text'>Problème de validation XML avec JAXP</title><content type='html'>L'api &lt;a href="https://jaxp.dev.java.net/"&gt;JAXP&lt;/a&gt; permet l'analyse et la transformation de documents XML. Une implémentation de JAXP est disponible dans &lt;a href="http://java.sun.com/j2se/1.5.0/index.jsp"&gt;JAVASE 5.0&lt;/a&gt; mais il est aussi possible d'utiliser l'implémentation fournie par &lt;a href="http://xerces.apache.org/xerces2-j/"&gt;Apache Xerces&lt;/a&gt;.&lt;br /&gt;Pour analyser le fichier data.xml avec un parser SAX :&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;SAXParserFactory spfactory = SAXParserFactory.newInstance();&lt;br /&gt;spfactory.setNamespaceAware(true);&lt;br /&gt;SAXParser saxparser = spfactory.newSAXParser();&lt;br /&gt;saxparser.parse(new File("data.xml"));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Et avec un parser DOM :&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();&lt;br /&gt;dbfactory.setNamespaceAware(true);&lt;br /&gt;DocumentBuilder domparser = dbfactory.newDocumentBuilder();&lt;br /&gt;domparser.parse(new File("data.xml"));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;La fonctionnalité qui nous intéresse ici est la validation d'un document par rapport à un schéma.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();&lt;br /&gt;dbfactory.setNamespaceAware(true);&lt;br /&gt;dbfactory.setXIncludeAware(true);&lt;br /&gt;&lt;br /&gt;DocumentBuilder parser = dbfactory.newDocumentBuilder();&lt;br /&gt;Document doc = parser.parse(new File("data.xml"));&lt;br /&gt;&lt;br /&gt;DOMSource xmlsource = new DOMSource(doc);&lt;br /&gt;&lt;br /&gt;SchemaFactory wxsfactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);&lt;br /&gt;&lt;br /&gt;//load a W3C XML Schema&lt;br /&gt;Schema schema = wxsfactory.newSchema(new File("myschema.xsd"));&lt;br /&gt;&lt;br /&gt;// create a validator from the loaded schema&lt;br /&gt;Validator validator = schema.newValidator();&lt;br /&gt;&lt;br /&gt;//validate the XML instance&lt;br /&gt;validator.validate(xmlsource);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Si cet exemple fonctionne avec l'implémentation fournie avec &lt;a href="http://java.sun.com/j2se/1.5.0/index.jsp"&gt;JAVASE 5.0&lt;/a&gt;, une exception est toujours levée avec &lt;a href="http://xerces.apache.org/xerces2-j/"&gt;Xerces&lt;/a&gt; :&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;Exception in thread "main" org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'root'.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;En effet, l'implémentation &lt;a href="http://xerces.apache.org/xerces2-j/"&gt;Xerces&lt;/a&gt; de &lt;span style="font-style:italic;"&gt;Validator#validate&lt;/span&gt; ne semble pas supporter un objet de classe &lt;span style="font-style:italic;"&gt;DOMSource &lt;/span&gt;en paramètre.&lt;br /&gt;Pour contourner ce problème, il faut utiliser la fonctionnalité de transformation de JAXP et transformer notre document DOM(&lt;span style="font-style:italic;"&gt;DOMSource&lt;/span&gt;) en Stream(&lt;span style="font-style:italic;"&gt;StreamSource&lt;/span&gt;).&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;DOMSource xmlsource = new DOMSource(doc);&lt;br /&gt;StringWriter writer = new StringWriter();&lt;br /&gt;StreamResult result = new StreamResult(writer);&lt;br /&gt;TransformerFactory tf = TransformerFactory.newInstance();&lt;br /&gt;Transformer transformer = tf.newTransformer();&lt;br /&gt;transformer.transform(xmlsource , result);&lt;br /&gt;validator.validate(new StreamSource(new StringReader(result.toString())));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Pour aller plus loin : &lt;a href="http://issues.apache.org/jira/browse/XERCESJ-1163"&gt;http://issues.apache.org/jira/browse/XERCESJ-1163&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-7364111266250318014?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/7364111266250318014/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=7364111266250318014' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/7364111266250318014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/7364111266250318014'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2008/03/problme-de-validation-xml-avec-jaxp.html' title='Problème de validation XML avec JAXP'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-4250988700433450706</id><published>2008-02-05T11:01:00.001+01:00</published><updated>2008-02-20T13:26:00.260+01:00</updated><title type='text'>Sticky sessions</title><content type='html'>Dans un environnement multi-serveurs (cluster), le mécanisme de sticky session (affinité de session) assure qu'un client qui a ouvert une session sur un serveur sera toujours aiguillé vers ce même serveur durant sa session.&lt;br /&gt;Par opposition, la réplication de session permet de garder sa session quelque soit le serveur sur lequel l'utilisateur est aiguillé.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-4250988700433450706?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/4250988700433450706/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=4250988700433450706' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/4250988700433450706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/4250988700433450706'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2008/02/sticky-sessions.html' title='Sticky sessions'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-3208164167966544690</id><published>2008-01-17T13:32:00.000+01:00</published><updated>2008-01-20T18:36:00.752+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='news'/><title type='text'>Oracle rachète BEA</title><content type='html'>&lt;a href="http://money.cnn.com/2007/10/12/technology/oracle_bea/index.htm?cnn=yes"&gt;Ca se tramait depuis un certain temps&lt;/a&gt; mais c'est maintenant officiel :&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.prnewswire.com/cgi-bin/stories.pl?ACCT=109&amp;amp;STORY=/www/story/01-16-2008/0004737296&amp;amp;EDATE="&gt;Oracle to Acquire BEA Systems&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;L'un des 2 serveurs d'application &lt;a href="http://www.oracle.com/technology/tech/java/oc4j/index.html"&gt;OC4J &lt;/a&gt;ou &lt;a href="http://dev2dev.bea.com/wlserver/index.html"&gt;Weblogic Server&lt;/a&gt; devrait passer à la trappe.&lt;br /&gt;&lt;br /&gt;De même, on peut se demander comment va se positionner la nouvelle entité par rapport à  &lt;a href="http://www.bea.com/framework.jsp?CNT=index.htm&amp;amp;FP=/content/products/weblogic/workshop/"&gt;Workshop &lt;/a&gt;concurent direct de &lt;a href="http://www.blogger.com/www.oracle.com/technology/products/jdev/index.html"&gt;JDevelopper&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;En tout cas, ce rachat sucite de nombreuses réactions dont celles de &lt;a href="http://blog.springsource.com/main/2008/01/16/the-power-of-adoption-why-no-company-is-big-enough-to-deny-developers-what-they-want/"&gt;Rod Johnson&lt;/a&gt; et &lt;a href="http://www.gigaspacesblog.com/2008/01/18/an-open-letter-to-bea-weblogic-customers/"&gt;Gigaspace &lt;/a&gt;qui nous encouragent à s'affranchir de l'architecture j2ee dont les 2 seuls concurrents directs sont maintenant Oracle et IBM.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-3208164167966544690?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.prnewswire.com/cgi-bin/stories.pl?ACCT=109&amp;STORY=/www/story/01-16-2008/0004737296&amp;EDATE=' title='Oracle rachète BEA'/><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/3208164167966544690/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=3208164167966544690' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/3208164167966544690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/3208164167966544690'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2008/01/oracle-to-acquire-bea-systems.html' title='Oracle rachète BEA'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3929106467046424972.post-7276078591515477563</id><published>2008-01-15T12:45:00.000+01:00</published><updated>2008-02-08T16:32:39.135+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='transaction'/><title type='text'>Niveau d'isolement des transactions avec les EJB</title><content type='html'>C'est souvent trop tard qu'on commence à se pencher sérieusement sur certains concepts. Celui-ci est souvent occulté quand on développe un module EJB mais cet oubli peut conduire à des incompréhensions. L'abstraction de l'architecture J2EE peut alors se montrer trompeuse ...&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://java.sun.com/developer/EJTechTips/images/2005/tt0125_Figure2.gif"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 400px;" src="http://java.sun.com/developer/EJTechTips/images/2005/tt0125_Figure2.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;L'isolement des transactions (le "I" dans les propriétés ACID), représente un concept et des mécanismes permettant d'assurer l'intégrité d'une base de données pouvant être accedée et(ou) mise à jour par un ensemble de clients simultanément.&lt;br /&gt;&lt;br /&gt;En vue d'un déploiement au sein d'un conteneur d'EJB, la bonne pratique veut que ces transactions soient déclarées "déclarativement" dans les différents descripteurs de déploiement.&lt;br /&gt;Dans cette optique, le niveau d'isolement peut être défini pour l'EJB ou pour une méthode en particulier.&lt;br /&gt;Les différents niveaux d'isolement et leurs caractéristiques sont résumés ici.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TRANSACTION_SERIALIZABLE&lt;/b&gt;&lt;br /&gt;&lt;p&gt;La transaction obtient les privilèges exclusifs de lecture et d'écriture sur les données. Aucune autre transaction ne peut lire ou écrire les même données.  Les "&lt;a href="#dirtyreads"&gt;dirty reads&lt;/a&gt;", "&lt;a href="#nonrepeatablereads"&gt;nonrepeatable reads&lt;/a&gt;" et  "&lt;a href="#phantomreads"&gt;phantom reads&lt;/a&gt;" sont donc exclues. Ce niveau d'isolation est le plus restrictif.&lt;/p&gt;&lt;br /&gt;&lt;b&gt;TRANSACTION_REPEATABLE_READ&lt;/b&gt;&lt;p&gt;La transaction ne peut modifier les données en cours de lecture par une autre transaction.Les "&lt;a href="#dirtyreads"&gt;dirty reads&lt;/a&gt;" et "&lt;a href="#nonrepeatablereads"&gt;nonrepeatable reads&lt;/a&gt;" sont exclues. Les "&lt;a href="#phantomreads"&gt;phantom reads&lt;/a&gt;" peuvent subvenir. Les EJB ou méthodes utilisant ce niveau d'isolation ont les mêmes restrictions que le niveau TRANSACTION_READ_COMMITED et auront des données identiques pendant toute la transaction.&lt;/p&gt;&lt;b&gt;TRANSACTION_READ_COMMITTED&lt;/b&gt;&lt;p&gt;La transaction ne peut lire des données non commitées. Des données en cours de modification par une autre transaction ne peuvent pas être lues.  Les "&lt;a href="#dirtyreads"&gt;dirty reads&lt;/a&gt;" sont exclues mais les "&lt;a href="#nonrepeatablereads"&gt;nonrepeatable reads&lt;/a&gt;" et "&lt;a href="#phantomreads"&gt;phantom reads&lt;/a&gt;" peuvent subvenir.&lt;/p&gt;&lt;b&gt;TRANSACTION_READ_UNCOMMITTED&lt;/b&gt;&lt;p&gt;La transaction peut lire des données pas encore commitées par une autre transaction en cours.Les "&lt;a href="#dirtyreads"&gt;dirty reads&lt;/a&gt;", "&lt;a href="#nonrepeatablereads"&gt;nonrepeatable reads&lt;/a&gt;" et "&lt;a href="#phantomreads"&gt;phantom reads&lt;/a&gt;" peuvent subvenir.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;a style="font-weight: bold;" name="dirtyreads"&gt;dirty reads&lt;/a&gt;&lt;br /&gt;Séquence :&lt;br /&gt;– A écrit un tuple&lt;br /&gt;– B lit ce tuple&lt;br /&gt;– A fait un rollback (restaurant l'ancienne valeur)&lt;br /&gt;Conséquence :&lt;br /&gt;– B a effectué un dirty read&lt;br /&gt;– B possède une mauvaise valeur&lt;br /&gt;&lt;br /&gt;&lt;a style="font-weight: bold;" name="nonrepeatablereads"&gt;nonrepeatable reads&lt;/a&gt;&lt;br /&gt;Séquence :&lt;br /&gt;– B lit un tuple&lt;br /&gt;– A modifie ce tuple&lt;br /&gt;– A fait un commit, rendant le changement permanent&lt;br /&gt;Conséquence :&lt;br /&gt;– B a effectué un non repeatable read&lt;br /&gt;– B ne possède pas la bonne valeur du tuple&lt;br /&gt;Si B refait une lecture de ce tuple, il aura une autre valeur&lt;br /&gt;&lt;br /&gt;&lt;a style="font-weight: bold;" name="phantomreads"&gt;phantom reads&lt;/a&gt;&lt;br /&gt;Séquence :&lt;br /&gt;– A lit un ensemble de tuples&lt;br /&gt;– B écrit un tuple qui aurait dû se trouver dans l'ensemble de A si B avait été plus rapide&lt;br /&gt;Conséquence :&lt;br /&gt;– A ne possède pas toute l'information qu'il cherchait&lt;br /&gt;– Si A exécute la même requête à nouveau, les phantoms (nouveaux tuples) apparaissent&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3929106467046424972-7276078591515477563?l=jclagache.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jclagache.blogspot.com/feeds/7276078591515477563/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3929106467046424972&amp;postID=7276078591515477563' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/7276078591515477563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3929106467046424972/posts/default/7276078591515477563'/><link rel='alternate' type='text/html' href='http://jclagache.blogspot.com/2008/01/niveau-disolement-des-transactions-avec.html' title='Niveau d&apos;isolement des transactions avec les EJB'/><author><name>jclagache</name><uri>http://www.blogger.com/profile/08374829789329771682</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
