<?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>Javasioux &#187; Java</title>
	<atom:link href="http://www.javasioux.fr/blog/category/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.javasioux.fr/blog</link>
	<description>Par Jérôme Van Der Linden</description>
	<lastBuildDate>Mon, 21 Nov 2011 22:45:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Paris Jug 12/05/09</title>
		<link>http://www.javasioux.fr/blog/2009/05/13/paris-jug-120509/</link>
		<comments>http://www.javasioux.fr/blog/2009/05/13/paris-jug-120509/#comments</comments>
		<pubDate>Wed, 13 May 2009 08:28:50 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[hot deploy]]></category>
		<category><![CDATA[javarebel]]></category>
		<category><![CDATA[paris jug]]></category>
		<category><![CDATA[productivité]]></category>

		<guid isPermaLink="false">http://www.javasioux.fr/blog/?p=463</guid>
		<description><![CDATA[Hier soir, se déroulait comme tous les mois, le <a href="http://www.parisjug.org/xwiki/bin/view/Meeting/20090512" target="_blank">Paris JUG</a>. Au programme : cache distribué, grille de données, <a href="http://www.terracotta.org/web/display/orgsite/What+Is+Terracotta" target="_blank">Terracotta</a> en première partie et <a href="http://www.zeroturnaround.com/javarebel/" target="_blank">javarebel</a> en fin de session.]]></description>
			<content:encoded><![CDATA[<h1>Cache distribué, NAM et grilles</h1>
<p>Je ne vais pas m&#8217;étendre sur la première partie présentée par <a href="http://www.parisjug.org/xwiki/bin/view/Speaker/AlliaumeErwan" target="_blank">Erwan Alliaume</a> et <a href="http://www.parisjug.org/xwiki/bin/view/Speaker/LeclercCyrille" target="_blank">Cyrille Le Clerc</a> de Xebia ainsi que <a href="http://www.parisjug.org/xwiki/bin/view/Speaker/BeaJeanMichel" target="_blank">Jean-Michel Bea</a> de FastConnect, le touilleur a encore une fois fait <a href="http://www.touilleur-express.fr/2009/05/13/compte-rendu-de-la-soiree-datagrid-et-javarebel/" target="_blank">un bon résumé</a>. La session était dense mais très intéressante.</p>
<h1>Javarebel</h1>
<p>Je vais m&#8217;attarder un peu plus sur la deuxième partie (qui n&#8217;a duré qu&#8217;une demi heure) dont le sujet me correspond plus : la productivité des développements avec JavaRebel. C&#8217;est <a href="http://www.zeroturnaround.com/author/toomasr/" target="_blank">Toomas Römer</a> de ZeroTurnaround qui nous présente l&#8217;outil.</p>
<p>
La démo de l&#8217;outil est toujours aussi bluffante (dispo <a href="http://www.zeroturnaround.com/javarebel-demonstration-screencast/" target="_blank">ici</a> et <a href="http://www.zeroturnaround.com/javarebel-spring-integration-screencast/" target="_blank">là</a>), d&#8217;autant que pressé par le temps, Toomas l&#8217;a déroulé assez vite, ajoutant du punch à la démo :</p>
<ul>
<li>Modification d&#8217;une jsp => rafraichissement instantané de la page web</li>
<li>Modification d&#8217;un validator => rafraichissement instantané de la page web</li>
<li>Ajout de méthode, de paramètres => rafraichissement instantané de la page web</li>
<li>Ajout d&#8217;un bean spring et d&#8217;une jsp => rafraichissement instantané de la page web</li>
</ul>
<p>Aucun repackaging, aucun redéploiement, aucune perte de temps ! C&#8217;est l&#8217;objectif de Javarebel : éviter de devoir recompiler, retester, repackager et surtout redéployer l&#8217;application à chaque modification du code.</p>
<p>
La démo nous laisse à penser : &laquo;&nbsp;mais comment j&#8217;arrive à supporter mes builds Maven de plusieurs minutes ?&nbsp;&raquo; Probablement parce qu&#8217;on n&#8217;a pas goûté à ce plaisir&#8230;</p>
<p>
A la fin de la session, on a le droit à une question intéressante qui est de savoir s&#8217;il (Toomas ndlr) n&#8217;avait pas peur que les développeurs ne prennent plus le temps de réfléchir à leur code (modélisation, archi&#8230;) mais se contentent de coder / tester / coder&#8230; pour se rendre compte au bout de plusieurs heures que leur code n&#8217;est pas bon. Ce à quoi Toomas a répondu que l&#8217;outil était là pour éviter de perdre du temps au redéploiement (10 minutes par ci, 10 minutes par là) et ne devait pas changer la manière dont travaillent les développeurs. Et Antonio d&#8217;ajouter qu&#8217;on ne pourrait plus prendre autant de pauses cafés <img src='http://www.javasioux.fr/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  !</p>
<p>
A l&#8217;issue de la présentation, en discutant avec Erwan (qui avait <a href="http://blog.xebia.fr/2008/11/14/javarebel/" target="_blank">blogué sur le sujet</a>), il s&#8217;avère que l&#8217;outil n&#8217;est pas tout à fait aussi magique, tou au mions pas tout le temps. Notamment sur un gros projet, Javarebel rame et finit même par planter. Je présume qu&#8217;il doit bien s&#8217;appliquer sur des appli webs relativement simples.</p>
<p>
En tout cas je suis persuadé que la démo plus quelques chiffres pourraient convaincre quelques managers de l&#8217;intérêt de l&#8217;outil.<br />
Pensez donc : 10 développeurs qui redéploiement environ 10 fois par jours au prix de 5 minutes à chaque fois (maven + serveur d&#8217;app) : 500 minutes (8h), soit 1j.h perdu par jour ! Au regard du prix de la <a href="http://sales.zeroturnaround.com/" target="_blank">license</a> (150 $ pour une entreprise), ca donne à réfléchir !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javasioux.fr/blog/2009/05/13/paris-jug-120509/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Single Sign On avec Kerberos</title>
		<link>http://www.javasioux.fr/blog/2009/01/12/single-sign-on-avec-kerberos/</link>
		<comments>http://www.javasioux.fr/blog/2009/01/12/single-sign-on-avec-kerberos/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 13:14:52 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[active directory]]></category>
		<category><![CDATA[jaas]]></category>
		<category><![CDATA[kerberos]]></category>
		<category><![CDATA[securité]]></category>

		<guid isPermaLink="false">http://www.javasioux.fr/blog/?p=341</guid>
		<description><![CDATA[Comment mettre en place un mécanisme d'authentification java en single sign on (SSO) ? Dans ce petit article, je décris comment nous avons procédé sur un projet en utilisant JAAS, Kerberos et Active Directory. La configuration n'est pas forcément innée donc avis aux intéressés...]]></description>
			<content:encoded><![CDATA[<h1>Besoin</h1>
<p>Le besoin est simple : avoir une application java client lourd avec un système d&#8217;authentification <a href="http://fr.wikipedia.org/wiki/Single_sign_on" target="_blank">Single Sign On</a> basé sur Kerberos et Active Directory. On se base donc sur l&#8217;infrastructure Microsoft (AD, Windows qui utilise Kerberos pour l&#8217;authentification depuis la version 2000) et la sécurité java (JAAS).</p>
<h1>Présentation des intervenants</h1>
<h2>Kerberos</h2>
<table>
<tr>
<td><img src="http://web.mit.edu/Kerberos/images/dog-ring.jpg" alt="Kerberos"></td>
<td><a href="http://fr.wikipedia.org/wiki/Kerberos" target="_blank">Kerberos</a> vient du grec et signifie &laquo;&nbsp;Cerbère&nbsp;&raquo;, le chien à trois têtes gardien de la porte des enfers (mythologie grecque), joliment trouvé pour un protocole d&#8217;authentification ! Je ne rentrerai pas dans les détails du protocol, wikipedia le décrivant mieux que moi. Sachez simplement que le protocole est basé sur une notion de tickets et qu&#8217;une fois authentifié sur votre poste via l&#8217;AD, vous disposez d&#8217;un ticket que nous allons pouvoir réutiliser pour vous authentifier sur d&#8217;autres applications / serveurs&#8230;
</td>
</tr>
</table>
<p><center><img src="http://www.adopenstatic.com/images/resources/blog/Kerberos1.jpg" alt=""></center></p>
<h2>JAAS</h2>
<table>
<tr>
<td>Java Authentication and Authorization Service (<a href="http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html" target="_blank">JAAS</a> pour les intimes) est l&#8217;API sécurité de java. Elle fournit comme son nom l&#8217;indique des mécanismes d&#8217;authentification et d&#8217;habilitation. Nous allons nous concentrer sur la partie <a href="http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html#Authentication">authentification</a>. Je vous recommande vivement ce <a href="http://www.jaasbook.com/pdfs/jaas-in-action_chapter03-02.pdf">pdf</a> si vous souhaitez une description claire et complète sur l&#8217;authent (en tout <a href="http://www.jaasbook.com/">10 documents</a> expliquent en long en large et en travers l&#8217;API JAAS : très enrichissant).</td>
<td><img src="http://ditwww.epfl.ch/SIC/SA/SPIP/Publications/IMG/gif/duke-security.gif" height="130" alt="JAAS"></td>
</tr>
</table>
<h1>Mise en place</h1>
<h2>LoginContext, LoginModule, CallBackHandler&#8230;</h2>
<p>Si vous avez lu les documents que je citais ci-dessus, passez à la partie suivante. Sinon, voilà un petit résumé des classes dont nous allons avoir besoin :</p>
<p><img src="http://www.javaworld.com/javaworld/jw-09-2002/images/jw-0913-jaas1.gif" alt="Jaas classes"></p>
<ul>
<li><a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/login/LoginContext.html" target="_blank">LoginContext</a> : cette classe est la classe principale permettant d&#8217;authentifier un utilisateur (méthode login). Elle est indépendante du mécanisme d&#8217;authentification car elle s&#8217;appuie sur des LoginModule qui, eux, varient en fonction de la technologie sous-jacente.</li>
<li><a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/spi/LoginModule.html" target="_blank">LoginModule</a> : Il s&#8217;agit d&#8217;une interface que les différents mécanismes d&#8217;authentification (Ldap, Kerberos, &#8230;) doivent implémenter pour authentifier un utilisateur (méthode login également).</li>
<li><a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/callback/CallbackHandler.html" target="_blank">CallBackHandler</a> : Le CallbackHandler est une interface dont votre propre implémentation doit être passée au LoginModule utilisé. Il permet d&#8217;interagir avec l&#8217;application pour récupérer les crédentials de l&#8217;utilisateur (par exemple récupérer le login/password au travers d&#8217;une interface graphique ou d&#8217;un prompt&#8230;).</li>
</ul>
<p>Typiquement vous aurez : </p>
<pre lang="java" line="1">
LoginContext lc = new LoginContext("MyLoginModuleName", new MyCallbackHandler(...));
try {
   lc.login();
} catch (LoginException le) {
  // do what you want
}
</pre>
<p>Lorsque le LoginContext est instancié, il va récupérer le(s) LoginModule(s) (classe d&#8217;implémentation + paramètres) correspondant au nom &laquo;&nbsp;MyLoginModuleName&nbsp;&raquo; dans un fichier de configuration. Il l&#8217;initialise.<br />
Lorsque le login est fait, le context parcours tous les modules associés et effectue un login dans chacun d&#8217;eux. Si le module en a besoin, il fera appel au CallbackHandler associé pour récupérer les credentials et faire l&#8217;authentification. </p>
<p>Je vais entrer dans les détails dans la partie suivante.</p>
<h2>Dans le vif du sujet</h2>
<h3>Configuration de JAAS</h3>
<p>On commence par créer un fichier <em>jaas.conf</em> dont on référence le chemin avec la propriété <code>java.security.auth.login.config</code> (par exemple en lançant l’application avec <code>java -Djava.security.auth.login.config=path/to/config</code> ou <code>System.setProperty(java.security.auth.login.config, "path/to/config")</code>).</p>
<p>Voilà le contenu de ce fichier :</p>
<pre lang="xml">
KerberosSecurityAuthSSO {
  com.sun.security.auth.module.Krb5LoginModule required useTicketCache="true" debug="false";
};

KerberosSecurityAuth {
  com.sun.security.auth.module.Krb5LoginModule required useTicketCache="false" debug="false";
};
</pre>
<p><code>KerberosSecurityAuth[SSO]</code> étant les noms des modules que l’on utilisera lorsqu’on déclarera notre LoginContext.</p>
<p><code>Krb5LoginModule</code> étant l’implémentation choisie (dans notre cas Kerberos 5). Il est possible de mettre plusieurs implémentations pour un même module, par exemple en plus du Kerberos, on aurait pu mettre du Ldap (avec LdapLoginModule)</p>
<p>Suivent ensuite les options :</p>
<ul>
<li><code>required</code> permet de préciser que le module est requis pour l’authentification.</li>
<li><code>useTicketCache</code> permet de préciser qu’on souhaite réutiliser le TGT kerberos, donc lorsqu’on le set à true, on peut espérer avoir du SSO.</li>
<li><code>debug</code> permet comme son nom l’indique de fournir des traces de l’authentification.</li>
<li> … de nombreuses autres options sont dispo et documentées <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/spec/com/sun/security/auth/module/Krb5LoginModule.html" target="_blank">ici</a>.</li>
</ul>
<h3>Configuration de kerberos</h3>
<p>De même que jaas, on a besoin d’un fichier de <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jgss/tutorials/KerberosReq.html" target="_blank">configuration pour kerberos</a>. On créé donc un fichier <em>krb5.conf</em> dont on référence le chemin avec la propriété <code>java.security.krb5.conf</code>. Si cette propriété n’est pas mise, il ira dans java-home/lib/security puis dans divers répertoires du système s’il ne trouve pas.</p>
<p>Ce fichier contient :</p>
<pre lang="xml">[libdefaults] default_realm = MYDOMAIN.FR dns_fallback dns_lookup_kdc dns_lookup_realm [realms] MYDOMAIN.FR = { kdc = mydomain.fr }</pre>
<p>C’est donc là que vous référencez votre domaine AD (ou plusieurs) et le(s) kdc associé(s).</p>
<h3>Authentification SSO</h3>
<p>On va maintenant arrêter de jouer avec les fichiers de configuration et coder un peu.</p>
<pre lang="java" line="10">
// cas SSO : utilisation du module KerberosSecurityAuthSSO
LoginContext lc = new LoginContext(“KerberosSecurityAuthSSO”, new SiouxCallbackHandler());
// cas non SSO : utilisation du module KerberosSecurityAuth
// LoginContext lc = new LoginContext(“KerberosSecurityAuth”, new SiouxCallbackHandler());

try {
  // authentification
  lc.login();

  // recuperation du Subject
  Subject subject = lc.getSubject();

  // recuperation du Principal
  Iterator it = subject.getPrincipals().iterator();
  Principal pr = null;
  while (it.hasNext()) {
    pr = (Principal) it.next();
  }

  // on retourne le nom du principal (login@domaine)
  if (pr != null) {
    return pr.getName();
  }
  return null;

} catch (LoginException le) {
  // ...
}
</pre>
<p>Le CallbackHandler ne devrait pas être utilisé dans ce cas. Étant donné que l&#8217;on récupère le ticket Kerberos, le LoginModule n&#8217;en a pas besoin puisqu&#8217;il a déjà les credentials. </p>
<h3>Authentification non SSO</h3>
<p>Si par contre nous avions utilisé le module &laquo;&nbsp;KerberosSecurityAuth&nbsp;&raquo; (avec useTicketCache=false), le module va avoir besoin du SiouxCallbackHandler que voilà :</p>
<pre lang="java" line="5">
public class SiouxCallbackHandler implements CallbackHandler {

  public SiouxCallbackHandler (/* parametres... */) {
    /* init ... */
  }

  public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
    String username;
    String domain;
    String password;

    // Affichage d'une boite de dialogue ...
    SecurityLoginDialog loginDialog = new SecurityLoginDialog();
    loginDialog.pack();
    loginDialog.setVisible(true);

    // ... pour récupérer le user, domaine et password
    username = loginDialog.getUser();
    password = loginDialog.getPassword();
    domain = loginDialog.getDomain();

    // On met à jour les callbacks avec les infos récupérées (login@domain et password)
    for (int i = 0; i < callbacks.length; i++) {
      Callback cb = callbacks[i];
      if (cb instanceof NameCallback) {
        username = username.concat("@");
        username = username.concat(domain);
        ((NameCallback) cb).setName(username);
      } else if (cb instanceof PasswordCallback) {
        // password is a char[]
        ((PasswordCallback) cb).setPassword(password.toCharArray());
      } else {
        throw new UnsupportedCallbackException(cb, "Unrecognized Callback");
      }
    }
  }
}
</pre>
<p>Ainsi le Krb5LoginModule aura les credentials dont il a besoin pour effectuer l'authentification (Aucun mot de passe ne circule en clair sur le réseau, de par l'utilisation de Kerberos et non LDAP).</p>
<h1>Conclusion</h1>
<p>Il y a pas mal de documentation autour de ces sujets (cf. les divers liens de l'article) et moyen de faire beaucoup plus que ce que j'ai montré. Mon exemple est relativement simple et vous fournira les bases d'une application sécurisée avec Kerberos (SSO ou non).<br />
Un <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jgss/single-signon.html">document de sun</a> complète mon article avec l'utilisation de GSS-Api pour faire de la délégation de credentials et donc appeler des services avec son compte sans ré-authentification.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javasioux.fr/blog/2009/01/12/single-sign-on-avec-kerberos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Commons-logging VS SLF4J</title>
		<link>http://www.javasioux.fr/blog/2008/11/15/commons-logging-vs-slf4j/</link>
		<comments>http://www.javasioux.fr/blog/2008/11/15/commons-logging-vs-slf4j/#comments</comments>
		<pubDate>Sat, 15 Nov 2008 18:20:57 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[commons-logging]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[log4j]]></category>
		<category><![CDATA[logback]]></category>
		<category><![CDATA[slf4j]]></category>
		<category><![CDATA[websphere]]></category>

		<guid isPermaLink="false">http://www.javasioux.fr/blog/?p=191</guid>
		<description><![CDATA[Qui utilise (utilisait) toujours commons-logging dans son application croyant bien faire ? Et qui parmi ceux-là s'est déjà heurté aux classloaders un peu vicieux de certains serveurs d'applications, Websphere notamment ? A tous ceux-là, ce billet est pour vous...]]></description>
			<content:encoded><![CDATA[<h1>Commons-logging</h1>
<p><a href="http://commons.apache.org/logging/">Jakarta Commons-logging</a> (JCL) est une couche d&#8217;abstraction permettant d&#8217;utiliser n&#8217;importe quel mécanisme de log (<a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/logging/package-summary.html">java.util.logging</a>, <a href="http://logging.apache.org/log4j/1.2/index.html">log4j</a>) sans utiliser directement leur implémentation. Cela permet donc de changer de framework de log sans impacter toute l&#8217;application. Seulement, change-t-on vraiment de framework de log tous les quatre matins ? On utilise généralement log4j, qui est très complet et fait très bien ce qu&#8217;il a à faire et jamais on n&#8217;en change !</p>
<p><center></p>
<div class="post-info" style="width:90%;border-left:1px solid #bdccdc;border-right:1px solid #bdccdc;text-align:left">
<strong>Surconception</strong><br />
<img src="http://www.javasioux.fr/blog/wp-content/uploads/2008/11/note.gif" alt="" title="note" width="80" height="80" class="alignleft size-thumbnail wp-image-201" /></a>Petit aparté sur la surconception. On a souvent tendance à mettre en place des couches d&#8217;abstraction &laquo;&nbsp;au cas où&nbsp;&raquo;. JCL <em>au cas où</em> on changerait de framework de log, des interfaces à tout va <em>au cas où</em> on ajouterait une nouvelle implémentation, la séparation jar/war <em>au cas où</em> on ferait une nouvelle IHM&#8230;<br />
Ne pourrait-on pas se contenter du nécessaire et abstraire le jour où on en aura vraiment besoin ?<br />
Pour ceux qui ne connaissent pas le Test Driven Development (TDD), voilà les règles que la méthode énonce :</p>
<ul>
<li>On écrit le(s) test(s) qui vérifie(nt) la fonctionnalité (et qui échoue vu que la fonctionnalité n&#8217;est pas encore implémentée).</li>
<li>On écrit le code <strong><u>le plus simple possible</u></strong> qui fait passer le test. Pas de superflu, juste le nécessaire !</li>
<li>On itère sur les deux étapes précédentes pour ajouter d&#8217;autres fonctionnalités.</li>
<li>On refactor le code <strong><u>lorsque cela devient nécessaire</u></strong>. C&#8217;est à ce moment que l&#8217;on se pose la question des interfaces, des couches d&#8217;abstractions&#8230;</li>
</ul>
</div>
<p></center><br />
A quoi bon utiliser JCL alors ? Il y a des cas où vous ne pourrez y échapper, par exemple si vous développez non pas une application mais un framework ou une api qui sera utilisée par des applications. Effectivement, dans de tels cas, vous ne savez pas quel framework de log est utilisé et vous ne pouvez imposer log4j par exemple si le projet qui utilise votre framework/api fait du java.util.logging.</p>
<p><center><img src="http://www.javasioux.fr/blog/wp-content/uploads/2008/11/log4j.png" alt="" title="logging" width="550" height="157" class="alignnone size-full wp-image-207" /></center></p>
<p>L&#8217;utilisation de JCL m&#8217;a posé pas mal de problème sur WAS et aux vues des nombreuses plaintes à ce sujet, je ne pense pas être le seul. Effectivement, WAS embarque sa propre version de JCL et gère le chargement des classes (classloader) différemment des autres serveurs d&#8217;application, à savoir les classes de WAS avant celles de l&#8217;application (PARENT FIRST). <u>Résultat</u> : des &laquo;&nbsp;ClassCastException&nbsp;&raquo;, des &laquo;&nbsp;NoClassDefFoundError&nbsp;&raquo;, des &laquo;&nbsp;NoSuchMethodException&nbsp;&raquo;, &#8230;<br />
Un très bon <a href="http://www.qos.ch/logging/classloader.jsp">article</a>, même s&#8217;il est un peu ancien, décrit bien ce problème. Plusieurs solutions existent pour pallier à ça et notamment celles qui m&#8217;avaient servit à l&#8217;époque sur WAS 5.1. Je vous laisse lire ce <a href="http://mattfleming.com/files/active/0/ibm.pdf">document IBM</a> pour les détails.</p>
<p>Comme je le disais plus haut, la solution la plus simple est encore de ne pas l&#8217;utiliser quand on en n&#8217;a pas besoin. Dans le cas contraire, je vous conseille de regarder du côté de SLF4J.</p>
<h1>SLF4J</h1>
<p>Simple Logging Facade for Java (<a href="http://www.slf4j.org/">SL4J</a>) est comme son nom l&#8217;indique une couche d&#8217;abstraction simple, pour faire comme ce bon vieux JCL&#8230; mais sans les problèmes de classloader. Comment ?<br />
Tout simplement parce que contrairement à JCL qui charge dynamiquement à l&#8217;exécution l&#8217;implémentation (log4j, java.util), SLF4J le fait à la compilation et manuellement, en fonction de l&#8217;implémentation choisie (jar).</p>
<p><u>Exemple</u> : Vous fournissez une api quelconque dans laquelle vous loggez des informations. Pour ce faire, vous avez besoin du jar de SLF4J <strong>slf4j-api-x.x.x.jar</strong>, et des différents adapteurs des frameworks (log4j : slf4j-log4j12-x.x.x.jar, java.util : slf4j-jdk14-x.x.x.jar) que les projets vous utilisant manipulent :<br />
<center><a href="http://www.javasioux.fr/blog/wp-content/uploads/2008/11/slf4j.png"><img src="http://www.javasioux.fr/blog/wp-content/uploads/2008/11/slf4j.png" alt="" title="slf4j" width="600" height="488"" /></a></center></p>
<p>Simple d&#8217;utilisation :</p>
<p><center><a href="http://www.javasioux.fr/blog/wp-content/uploads/2008/11/siouxlogging.png"><img src="http://www.javasioux.fr/blog/wp-content/uploads/2008/11/siouxlogging.png" alt="" title="siouxlogging" width="600" height="143" class="aligncenter size-full wp-image-220" /></a></center><br />
(Vous aurez remarqué l&#8217;utilisation de {} pour jouer avec vos variables sans avoir à les concaténer à vos chaînes de caractères).</p>
<p>Plus de problème de classloading, vous fournissez tous les adapters disponibles (relativement légers : moins de 20 ko) et les projets utilisent leur framework de log préférés (log4j, java.util ou le plus récent <a href="http://logback.qos.ch/">logback</a> qui apporte nativement l&#8217;adapteur SLF4J).</p>
<h1>Conclusion</h1>
<p>Pas sûr que les problèmes de <a href="http://www.qos.ch/logging/classloader.jsp">classloading</a> soient encore d&#8217;actualité sur les versions récentes de WAS, il n&#8217;empêche que JCL est vieillissant et  quand on a degusté ces problèmes, on n&#8217;a plus envie de tenter le diable.<br />
Au delà de sa simplicité et de la disparition du problème de classpath, SLF4J apporte un peu de fraîcheur (cf. exemple ci-dessus), alors n&#8217;hésitez plus, simplifiez vous la vie !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javasioux.fr/blog/2008/11/15/commons-logging-vs-slf4j/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Livraison sur environnements multiples avec Maven &#8230; ou pas</title>
		<link>http://www.javasioux.fr/blog/2008/10/13/livraison-sur-environnements-multiples-avec-maven-ou-pas/</link>
		<comments>http://www.javasioux.fr/blog/2008/10/13/livraison-sur-environnements-multiples-avec-maven-ou-pas/#comments</comments>
		<pubDate>Mon, 13 Oct 2008 11:49:15 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[déploiement]]></category>
		<category><![CDATA[jee]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://www.javasioux.fr/blog/?p=15</guid>
		<description><![CDATA[Il s'agit d'un problème récurrent lorsque l'on développe une application JEE et pour lequel on n'est jamais vraiment au point : "comment gérer la configuration de mon application sur les différents environnements ?" Pourtant on dispose de tous les ingrédients pour y parvenir, et Maven n'est pas forcément le seul...]]></description>
			<content:encoded><![CDATA[<p><span style="color: #ffffff;">_</span></p>
<h2>Depuis la nuit des temps</h2>
<p>J&#8217;exagère un peu mais depuis qu&#8217;on développe des applications JEE, on doit gérer différents environnements :</p>
<ul>
<li>Le poste de travail du développeur</li>
<li>Le serveur d&#8217;assemblage</li>
<li>Le serveur de pré-prod</li>
<li>Le serveur de prod</li>
<li>&#8230; et parfois d&#8217;autres intermédiaires</li>
</ul>
<p>La plupart du temps, on maintenait plusieurs fichiers properties et au moment de générer le package, c&#8217;était la galère : on prenait le bon fichier (&laquo;&nbsp;<em>quel environnement je livre déjà ?</em>&laquo;&nbsp;), on le copiait dans le bon répertoire (&laquo;&nbsp;<em>euh, quel environnement j&#8217;ai dit ?</em>&laquo;&nbsp;). Avec Ant, on s&#8217;en sortait plus ou moins automatiquement mais au prix de nombreuses lignes d&#8217;XML!</p>
<h2>Maven est arrivé&#8230;</h2>
<p>&#8230; sans s&#8217;presser ! Et surtout sans rien révolutionner. Du moins dans les premiers temps car on refaisait avec Maven 1 (à coup de scripts jelly) ce qu&#8217;on faisait avant avec Ant. Mais l&#8217;arrivée des <strong>profiles</strong> a changé la donne !</p>
<h3>Profiles et ressources</h3>
<p>Je ne vais pas refaire le <a title="Maven Sonatype Book" href="http://www.sonatype.com/book/reference/profiles.html" target="_blank">chapitre 11 de l&#8217;excellent livre de sonatype</a> ni reprendre la <a title="Maven profiles" href="http://maven.apache.org/guides/introduction/introduction-to-profiles.html" target="_blank">doc Maven</a> à 0 mais pour résumer, il est possible d&#8217;avoir différent profils, qui comme leurs noms l&#8217;indiquent, permettent de définir plusieurs configurations et donc de gérer plusieurs environnements. Pour chaque profile, on peut définir des dépendances particulières, des plugins particuliers &#8230; mais surtout un build particulier et notamment les <strong>ressources</strong> (voir <a title="Maven profiles" href="http://maven.apache.org/pom.html#Profiles" target="_blank">ici</a> pour le détail du contenu de la balise profiles).</p>
<p>Le plus simple pour comprendre est encore de prendre un exemple :</p>
<table style="border-color: #000000; border-width: 1px; background-color: #c6c7c7;" border="1" width="500">
<tbody>
<tr>
<td>
<pre class="programlisting"><span style="font-size: medium;">&lt;<strong class="hl-tag"><span style="color: blue;">project</span></strong>&gt;
</span><span><span style="font-size: medium;">  [...]</span></span>
<span style="font-size: medium;">  &lt;<strong class="hl-tag"><span style="color: blue;">profiles</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">profile</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">id</span></strong>&gt;dev&lt;<strong class="hl-tag"><span style="color: blue;">/id</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">activation</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">activeByDefault</span></strong>&gt;true&lt;<strong class="hl-tag"><span style="color: blue;">/activeByDefault</span></strong>&gt;
      &lt;/<strong class="hl-tag"><span style="color: blue;">activation</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">build</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">resources</span></strong>&gt;
          &lt;<strong class="hl-tag"><span style="color: blue;">resource</span></strong>&gt;
            &lt;</span><span style="font-size: medium; color: #0000ff;"><strong>directory</strong></span><span style="font-size: medium;">&gt;${basedir}/src/main/resources_dev&lt;/</span><span style="font-size: medium; color: #0000ff;"><strong>directory</strong></span><span style="font-size: medium;">&gt;
          &lt;<strong class="hl-tag"><span style="color: blue;">resource</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">/resources</span></strong>&gt;
        [...]
      &lt;<strong class="hl-tag"><span style="color: blue;">/build</span></strong>&gt;
      [...]
    &lt;<strong class="hl-tag"><span style="color: blue;">/profile</span></strong>&gt;
</span><span style="font-size: medium;">    &lt;<strong class="hl-tag"><span style="color: blue;">profile</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">id</span></strong>&gt;prod&lt;<strong class="hl-tag"><span style="color: blue;">/id</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">build</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">resources</span></strong>&gt;
          &lt;<strong class="hl-tag"><span style="color: blue;">resource</span></strong>&gt;
            &lt;</span><span style="font-size: medium; color: #0000ff;"><strong>directory</strong></span><span style="font-size: medium;">&gt;${basedir}/src/main/resources_prod&lt;/</span><span style="font-size: medium; color: #0000ff;"><strong>directory</strong></span><span style="font-size: medium;">&gt;
          &lt;<strong class="hl-tag"><span style="color: blue;">resource</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">/resources</span></strong>&gt;
        [...]
      &lt;<strong class="hl-tag"><span style="color: blue;">/build</span></strong>&gt;
      [...]
    &lt;<strong class="hl-tag"><span style="color: blue;">/profile</span></strong>&gt;</span>
<span style="font-size: medium;">  &lt;<strong class="hl-tag"><span style="color: blue;">/profiles</span></strong>&gt;
&lt;<strong class="hl-tag"><span style="color: blue;">/project</span></strong>&gt;</span></pre>
</td>
</tr>
</tbody>
</table>
<pre class="programlisting" style="text-align: center;"><span style="font-size: medium;"><strong>pom.xml</strong>
</span></pre>
<p>Et on a donc une arborescence qui ressemble à ça :</p>
<table style="background-color: #d2d0d0; border-color: #000000; border-width: 1px;" border="1" width="500">
<tbody>
<tr>
<td>
<pre><span><span style="font-size: medium;">Javasioux
|
\- src
    |
    \- main
        |
        \- resources
        |    \- common.properties
        \- resources_dev
        |    \- specific.properties
        \- resources_prod
             \- specific.properties</span></span></pre>
</td>
</tr>
</tbody>
</table>
<p>Ainsi, sur votre poste de travail, vous n&#8217;aurez qu&#8217;à faire : <span style="font-size: medium; font-family: courier new,courier;">mvn package</span> pour que Maven sélectionne (par défaut : <span style="font-size: medium; font-family: courier new,courier;">activeByDefault</span>) le profile de dev et donc avoir en sortie les fichiers common.properties (qui provient par convention du répertoire src/main/resources) et specific.properties provenant du répertoire src/main/resources_dev.</p>
<p>Ensuite, lorsque vous devrez livrer votre application, vous devrez sélectionner le profile de prod et donc exécuter <span style="font-size: medium; font-family: courier new,courier;">mvn package <strong>-Pprod</strong></span>. En sortie, vous aurez toujours votre common.properties, mais par contre vous aurez le specific provenant de src/main/resources_prod.</p>
<p><span style="text-decoration: underline;">Avantage</span> : On peut sélectionner différents fichiers de configuration en fonction de l&#8217;environnement sur lequel on veut déployer.</p>
<p><span style="text-decoration: underline;">Inconvénients</span> :</p>
<ul>
<li>Lorsque vous aurez fait vos tests sur un environnement donné (préprod par exemple) avec votre fichier &laquo;&nbsp;specific&nbsp;&raquo; de préprod, vous devrez faire un nouveau package avec votre fichier &laquo;&nbsp;specific&nbsp;&raquo; de prod. Vous ne constatez pas un problème ? Effectivement, l&#8217;application testée et validée en préprod n&#8217;est pas la même que vous livrez en prod, et donc vous n&#8217;êtes pas sûr qu&#8217;elle fonctionnera !</li>
<li>Il faut maintenir plusieurs fichiers et ne pas oublier d&#8217;ajouter les variables dans chacun d&#8217;eux.</li>
<li>La configuration est faite en dur dans vos fichiers. Par conséquent vous devez connaître chacun des environnements. Hors, il est rare de connaître les paramètres de la base de donnée de production&#8230;</li>
</ul>
<h3>Profiles et filtres</h3>
<p>Il s&#8217;agit là encore d&#8217;une nouvelle possibilité bien pratique de Maven, <a title="Filter resource" href="http://www.sonatype.com/book/reference/resource-filtering.html">filtrer</a> les différentes propriétés de vos ressources. En clair, vous avez :</p>
<ul>
<li>Un fichier properties, un fichier xml, peu importe tant qu&#8217;il se situe dans un répertoire de ressources référencé dans le pom (src/main/resources par défaut).</li>
<li>Dans ce fichier de configuration quelconque, vous n&#8217;utilisez pas de valeurs en dur mais des variables du style <span style="font-size: medium; font-family: courier new,courier;">${mavariable}</span>.</li>
<li>Et dans le pom, vous définissez les différentes valeurs possibles pour ces variables en fonction des environnements.</li>
</ul>
<p>Exemple : je reprends l&#8217;exemple fourni par sonatype dans son livre, vous pouvez l&#8217;avoir en détail <a title="Filter resource" href="http://www.sonatype.com/book/reference/resource-filtering.html#d0e17124" target="_blank">ici</a>.</p>
<p>Vous avez un fichier spring qui définit une datasource, et comme je le disais des variables &#8230; variables :</p>
<table style="border-color: #000000; border-width: 1px; background-color: #cdcbcb;" border="1" width="500">
<tbody>
<tr>
<td>
<pre class="programlisting"><span style="font-size: medium;">&lt;<span class="hl-tag"><span style="color: blue;">beans</span></span> <span class="hl-attribute"><span style="color: blue;">xmlns</span></span>=<span class="hl-value"><span style="color: blue;">"http://www.springframework.org/schema/beans"</span></span>
       <span class="hl-attribute"><span style="color: blue;">xmlns:xsi</span></span>=<span class="hl-value"><span style="color: blue;">"http://www.w3.org/2001/XMLSchema-instance"</span></span>
       <span class="hl-attribute"><span style="color: blue;">xsi:schemaLocation</span></span>=<span class="hl-value"><span style="color: blue;">"http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"</span></span>&gt;

    &lt;<span class="hl-tag"><span style="color: blue;">bean</span></span> <span class="hl-attribute"><span style="color: blue;">id</span></span>=<span class="hl-value"><span style="color: blue;">"someDao"</span></span> <span class="hl-attribute"><span style="color: blue;">class</span></span>=<span class="hl-value"><span style="color: blue;">"com.example.SomeDao"</span></span>&gt;
        &lt;<span class="hl-tag"><span style="color: blue;">property</span></span> <span class="hl-attribute"><span style="color: blue;">name</span></span>=<span class="hl-value"><span style="color: blue;">"dataSource"</span></span> <span class="hl-attribute"><span style="color: blue;">ref</span></span>=<span class="hl-value"><span style="color: blue;">"dataSource"</span></span>/&gt;
    &lt;<span class="hl-tag"><span style="color: blue;">/</span></span><span class="hl-tag"><span style="color: blue;">bean</span></span>&gt;

    &lt;<span class="hl-tag"><span style="color: blue;">bean</span></span> <span class="hl-attribute"><span style="color: blue;">id</span></span>=<span class="hl-value"><span style="color: blue;">"dataSource"</span></span> <span class="hl-attribute"><span style="color: blue;">destroy-method</span></span>=<span class="hl-value"><span style="color: blue;">"close"</span></span>
             <span class="hl-attribute"><span style="color: blue;">class</span></span>=<span class="hl-value"><span style="color: blue;">"org.apache.commons.dbcp.BasicDataSource"</span></span>&gt;
        &lt;<span class="hl-tag"><span style="color: blue;">property</span></span> <span class="hl-attribute"><span style="color: blue;">name</span></span>=<span class="hl-value"><span style="color: blue;">"driverClassName"</span></span> <span class="hl-attribute"><span style="color: blue;">value</span></span>=<span class="hl-value"><span style="color: blue;">"<strong>${jdbc.driverClassName}</strong>"</span></span>/&gt;
        &lt;<span class="hl-tag"><span style="color: blue;">property</span></span> <span class="hl-attribute"><span style="color: blue;">name</span></span>=<span class="hl-value"><span style="color: blue;">"url"</span></span> <span class="hl-attribute"><span style="color: blue;">value</span></span>=<span class="hl-value"><span style="color: blue;">"<strong>${jdbc.url}</strong>"</span></span>/&gt;
        &lt;<span class="hl-tag"><span style="color: blue;">property</span></span> <span class="hl-attribute"><span style="color: blue;">name</span></span>=<span class="hl-value"><span style="color: blue;">"username"</span></span> <span class="hl-attribute"><span style="color: blue;">value</span></span>=<span class="hl-value"><span style="color: blue;">"<strong>${jdbc.username}</strong>"</span></span>/&gt;
        &lt;<span class="hl-tag"><span style="color: blue;">property</span></span> <span class="hl-attribute"><span style="color: blue;">name</span></span>=<span class="hl-value"><span style="color: blue;">"password"</span></span> <span class="hl-attribute"><span style="color: blue;">value</span></span>=<span class="hl-value"><span style="color: blue;">"<strong>${jdbc.password}</strong>"</span></span>/&gt;
    &lt;<span class="hl-tag"><span style="color: blue;">/</span></span><span class="hl-tag"><span style="color: blue;">bean</span></span>&gt;
&lt;<span class="hl-tag"><span style="color: blue;">/</span></span><span class="hl-tag"><span style="color: blue;">beans</span></span>&gt;</span></pre>
</td>
</tr>
</tbody>
</table>
<p>Pour faire simple, ce fichier se trouve dans le répertoire par défaut src/main/resources. Et donc associé à cela, vous avez évidemment le pom.xml magique :</p>
<table style="border-color: #000000; border-width: 1px; background-color: #ddd9dc;" border="1" width="500">
<tbody>
<tr>
<td>
<pre class="programlisting"><span style="font-size: medium;">&lt;<span class="hl-tag"><span style="color: blue;">project</span></span>&gt;
  [...]
  <span style="color: #339966;">&lt;!--
     On définit ici les valeurs par défaut des propriétés
     qui apparaîtront dans le fichier spring.
   --&gt;</span>
  &lt;<strong class="hl-tag"><span style="color: blue;">properties</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">jdbc.driverClassName</span></strong>&gt;com.mysql.jdbc.Driver&lt;<strong class="hl-tag"><span style="color: blue;">/jdbc.driverClassName</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">jdbc.url</span></strong>&gt;jdbc:mysql://localhost:3306/development_db&lt;<strong class="hl-tag"><span style="color: blue;">/jdbc.url</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">jdbc.username</span></strong>&gt;dev_user&lt;<strong class="hl-tag"><span style="color: blue;">/jdbc.username</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">jdbc.password</span></strong>&gt;s3cr3tw0rd&lt;<strong class="hl-tag"><span style="color: blue;">/jdbc.password</span></strong>&gt;
  &lt;<strong class="hl-tag"><span style="color: blue;">/properties</span></strong>&gt;
  </span><span><span style="font-size: medium;">[...]</span></span>
<span><span><span style="font-size: medium;"><span style="color: #339966;">  &lt;!--
    On est obligé de redéfinir la ressource car on active le filtrage.
    Cet élément est indispensable puisqu'il permet de dire à Maven
    que les ressources se trouvant dans ce répertoire doivent être
    filtrées, c'est à dire parsées pour remplacer les variables par
    des valeurs.
   --&gt;</span></span></span></span>
<span style="font-size: medium;">  &lt;<span class="hl-tag"><span style="color: blue;">build</span></span>&gt;
    &lt;<span class="hl-tag"><span style="color: blue;">resources</span></span>&gt;
      &lt;<span class="hl-tag"><span style="color: blue;">resource</span></span>&gt;src/main/resources&lt;<span class="hl-tag"><span style="color: blue;">/</span></span><span class="hl-tag"><span style="color: blue;">resource</span></span>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">filtering</span></strong>&gt;<strong>true</strong>&lt;<strong class="hl-tag"><span style="color: blue;">/filtering</span></strong>&gt;
    &lt;<span class="hl-tag"><span style="color: blue;">/resources</span></span>&gt;
  &lt;<span class="hl-tag"><span style="color: blue;">/build</span></span>&gt;
  </span><span><span style="font-size: medium;">[...]</span></span>
<span><span><span style="font-size: medium;"><span style="color: #339966;">  &lt;!--
    On peut ensuite définir des valeurs particulières en fonction
    d'un profile, et donc d'un environnement particulier.
   --&gt;</span></span></span></span>
<span style="font-size: medium;">  &lt;<strong><span class="hl-tag"><span style="color: blue;">profiles</span></span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">profile</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">id</span></strong>&gt;production&lt;<strong class="hl-tag"><span style="color: blue;">/id</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">properties</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">jdbc.driverClassName</span></strong>&gt;oracle.jdbc.driver.OracleDriver&lt;<strong class="hl-tag"><span style="color: blue;">/jdbc.driverClassName</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">jdbc.url</span></strong>&gt;jdbc:oracle:thin:@proddb01:1521:PROD&lt;<strong class="hl-tag"><span style="color: blue;">/jdbc.url</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">jdbc.username</span></strong>&gt;prod_user&lt;<strong class="hl-tag"><span style="color: blue;">/jdbc.username</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">jdbc.password</span></strong>&gt;s00p3rs3cr3t&lt;<strong class="hl-tag"><span style="color: blue;">/jdbc.password</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">/properties</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">/profile</span></strong>&gt;
  &lt;<strong class="hl-tag"><span style="color: blue;">/profiles</span></strong>&gt;</span>
<span style="font-size: medium;">&lt;<span class="hl-tag"><span style="color: blue;">/project</span></span>&gt;</span></pre>
</td>
</tr>
</tbody>
</table>
<p><span style="text-decoration: underline;">Avantage par rapport à la solution précédente</span> : On ne maintient qu&#8217;un seul fichier, tout est dans le pom.xml.</p>
<p><span style="text-decoration: underline;">Inconvénients</span> : Par contre, on se retrouve avec les autres problèmes : un package testé avec un profile peut ne pas marcher avec un autre profile. De même, il vous faudra connaître l&#8217;environnement pour configurer correctement l&#8217;application.</p>
<h3>Pas mal mais pas idéal !</h3>
<p>Les profiles, c&#8217;est pratique, ca permet de simplement gérer différents environnements (simplement mais avec pas mal de XML supplémentaire dans le pom). Le problème, nous l&#8217;avons vu, c&#8217;est que cela nécessite de connaître les environnements sur lesquels sera déployée l&#8217;application, chose relativement rare dans les grandes sociétés, ou la production gère la plupart des environnements.</p>
<p><span style="text-decoration: underline;">Remarque</span> : Je ne comprends pas cette <a title="Environnements selon Maven" href="http://maven.apache.org/guides/mini/guide-building-for-different-environments.html" target="_blank">page</a> de Maven où les profiles et le plugin antrun sont décrits comme étant le moyen de gérer divers environnements. Effectivement, c&#8217;en est un, je viens de le décrire mais il y a tout de même mieux&#8230; ne serait qu&#8217;en n&#8217;utilisant pas le plugin antrun !</p>
<h2>Retour au JEE !</h2>
<p>Et oui, depuis tout ce temps, on avait la solution sous les yeux sans vraiment s&#8217;en servir. JEE fournit une extension pour configurer correctement votre application : Java Naming and Directory Interface (<strong>JNDI</strong>). Cette extension permet de configurer votre application directement sur le serveur d&#8217;application. Je ne vais pas entrer dans les détails de JNDI, ce n&#8217;est pas l&#8217;objet de ce billet mais sachez simplement que vous pouvez configurer une url qui pointe vers un fichier et par exemple votre ficher de configuration.</p>
<h3>Configuration JNDI de l&#8217;application</h3>
<h4><span style="font-size: small;">Dans le code</span></h4>
<p>Soit en standard avec le lookup :</p>
<table style="border-color: #000000; border-width: 1px; background-color: #dcdada;" border="1" width="500">
<tbody>
<tr>
<td>
<pre><span style="font-size: small; font-family: courier new,courier; color: #000000;">try {
   URL configURL = (URL)initialContext.lookup("</span><span style="font-size: small; font-family: courier new,courier; color: #000000;"><span><strong><span class="pln">java:comp/env/url/MyAppConfig</span></strong></span></span><span style="font-size: small; font-family: courier new,courier; color: #000000;">");
   InputStream inputstream = </span><span style="font-size: small; font-family: courier new,courier;"><span><span style="color: #000000;">configURL.</span></span></span><span style="font-size: small; font-family: courier new,courier;">openStream()</span><span style="font-size: small; font-family: courier new,courier;">;
</span><span style="font-size: small; font-family: courier new,courier;">   Properties properties = new Properties();</span><span style="font-size: small; font-family: courier new,courier;">
</span><span style="font-size: small; font-family: courier new,courier;">   properties.load(inputstream);</span><span style="font-size: small; font-family: courier new,courier;">
</span><span style="font-size: small; font-family: courier new,courier; color: #000000;">}
catch (Exception e) {
   // ...
}</span></pre>
</td>
</tr>
</tbody>
</table>
<p>Soit si vous utilisez spring :</p>
<table style="border-color: #000000; border-width: 1px; background-color: #dcdada;" border="1" width="500">
<tbody>
<tr>
<td>
<pre class="programlisting"><span style="font-size: small; font-family: courier new,courier;"><span><span>&lt;<span class="hl-tag"><span style="color: blue;">bean</span></span> <span class="hl-attribute"><span style="color: blue;">class</span></span>=<span class="hl-value"><span style="color: blue;">"org.springframework.beans.factory.config.<strong>PropertyPlaceholderConfigurer</strong>"</span></span>&gt;
    &lt;<span style="color: blue;">property</span> <span class="hl-attribute"><span style="color: blue;">name</span></span>=<span class="hl-value"><span style="color: blue;">"locations"</span></span>&gt;
       </span></span></span><span style="font-size: small;"><span><span><span><span style="font-family: courier new,courier;"><span><span>  &lt;<span style="color: #0000ff;">list</span>&gt;</span></span></span></span></span></span>
                    <span><span><span><span style="font-family: courier new,courier;"><span><span>&lt;<span style="color: #0000ff;">ref bean="</span></span></span></span></span></span></span><span><span style="font-family: courier new,courier;"><span><span class="hl-value"><span style="color: blue;">appConfig</span></span></span></span></span><span><span><span><span style="font-family: courier new,courier;"><span><span><span style="color: #0000ff;">" /</span>&gt;</span></span></span></span></span></span>
</span><span style="font-size: small;">              [...]</span><span style="font-size: small;">
             <span><span><span><span style="font-family: courier new,courier;"><span><span>&lt;/<span style="color: #0000ff;">list</span>&gt;</span></span></span></span></span></span>
</span><span style="font-size: small; font-family: courier new,courier;"><span><span><span><span><span><span>    &lt;/<span style="color: blue;">property</span></span></span></span></span></span></span>&gt;
</span><span style="font-size: small; font-family: courier new,courier;"><span><span>&lt;<span class="hl-tag"><span style="color: blue;">/</span></span><span class="hl-tag"><span style="color: blue;">bean</span></span>&gt;</span></span>
</span><span style="font-size: small; font-family: courier new,courier;"><span>&lt;<span class="hl-tag"><span style="color: blue;">bean</span></span> <span class="hl-attribute"><span style="color: blue;">id</span></span>=<span class="hl-value"><span style="color: blue;">"appConfig"</span></span> <span class="hl-attribute"><span style="color: blue;">class</span></span>=<span class="hl-value"><span style="color: blue;">"org.springframework.core.io.UrlResource"</span></span>&gt;
    &lt;<span class="hl-tag"><span style="color: blue;">constructor-arg</span></span> <span class="hl-attribute"><span style="color: blue;">ref</span></span>=<span class="hl-value"><span style="color: blue;">"appConfigJndiUrlResource"</span></span>/&gt;
&lt;<span class="hl-tag"><span style="color: blue;">/</span></span><span class="hl-tag"><span style="color: blue;">bean</span></span>&gt;
</span></span><span style="font-size: small; font-family: courier new,courier;"><span>&lt;<span class="hl-tag"><span style="color: blue;">bean</span></span> <span class="hl-attribute"><span style="color: blue;">id</span></span>=<span class="hl-value"><span style="color: blue;">"</span></span></span></span><span style="font-size: small; font-family: courier new,courier;"><span><span><span class="hl-value"><span style="color: blue;">appConfigJndiUrlResource</span></span></span></span></span><span style="font-size: small; font-family: courier new,courier;"><span><span class="hl-value"><span style="color: blue;">"</span></span> <span class="hl-attribute"><span style="color: blue;">
      class</span></span>=<span class="hl-value"><span style="color: blue;">"org.springframework.jndi.<strong>JndiObjectFactoryBean</strong>"</span></span>&gt;
    &lt;<span style="color: blue;">property</span> <span class="hl-attribute"><span style="color: blue;">name</span></span>=<span class="hl-value"><span style="color: blue;">"jndiName" value="</span></span></span></span><span style="font-size: small; font-family: courier new,courier; color: #0000ff;"><span><strong><span class="pln">java:comp/env/url/MyAppConfig</span></strong></span></span><span style="font-size: small; font-family: courier new,courier;"><span><span class="hl-value"><span style="color: blue;">"</span></span> /&gt;
&lt;<span style="color: #000000;"><span class="hl-tag"><span>/</span></span></span><span class="hl-tag"><span style="color: blue;">bean</span></span>&gt;</span></span></pre>
</td>
</tr>
</tbody>
</table>
<h4><span style="font-size: small;">Descripteur de déploiement</span></h4>
<p>Bien entendu on référence la ressource dans le<span style="font-size: small;"> web.xml</span> :</p>
<table style="background-color: #d7d5d6; border-color: #000000; border-width: 1px;" border="1" width="500">
<tbody>
<tr>
<td>
<pre class="prettyprint"><span style="font-size: small; font-family: courier new,courier;"><span class="pun">&lt;</span><span style="color: #0000ff;"><span class="tag">resource-ref</span></span><span class="pun">&gt;</span><span class="pln">
       </span><span class="pun">&lt;</span><span style="color: #0000ff;"><span class="tag">res-ref-name</span></span><span class="pun">&gt;</span><span class="pln">myAppConfigResource</span><span class="pun">&lt;/</span><span style="color: #0000ff;"><span class="tag">res-ref-name</span></span><span class="pun">&gt;</span><span class="pln">
       </span><span class="pun">&lt;</span><span style="color: #0000ff;"><span class="tag">res-type</span></span><span class="pun">&gt;java.net.URL</span><span class="pun">&lt;/</span><span style="color: #0000ff;"><span class="tag">res-type</span></span><span class="pun">&gt;</span><span class="pln">
       </span><span class="pun">&lt;</span><span style="color: #0000ff;"><span class="tag">jndi-name</span></span><span class="pun">&gt;</span><strong><span class="pln">java:comp/env/url/MyAppConfig</span></strong><span class="pun">&lt;/</span><span style="color: #0000ff;"><span class="tag">jndi-name</span></span><span class="pun">&gt;</span><span class="pln">
</span><span class="pun">&lt;/</span><span style="color: #0000ff;"><span class="tag">resource-ref</span></span></span><span style="font-size: small;"><span class="pln">&gt;</span></span></pre>
</td>
</tr>
</tbody>
</table>
<h4 class="prettyprint"><span style="font-size: small;"><span class="pln">Sur le serveur d&#8217;application</span></span></h4>
<p>Tout dépend du serveur dont vous disposez mais vous n&#8217;avez qu&#8217;à configurer la resource URL url/MyAppConfig vers le fichier properties qui convient (ex : <em>file:/usr/Websphere/6.0/config/specific.properties</em>).</p>
<p>Évidemment, il faut déployer le fichier au bon endroit sur le serveur et donc le livrer avec l&#8217;application mais en dehors de l&#8217;ear ou du war et c&#8217;est là que Maven entre à nouveau en jeu !</p>
<h3>Maven assembly</h3>
<p>Le plugin <a title="Maven assembly" href="http://maven.apache.org/plugins/maven-assembly-plugin/" target="_blank">assembly</a> de Maven permet de générer un paquetage (pour ne pas dire package) zip, targz&#8230; regroupant un ou plusieurs packages et des fichiers divers (et notamment ceux qui nous intéressent, les properties). Encore une fois, je ne saurais vous conseiller le livre de sonatype pour les <a title="Maven assembly" href="http://www.sonatype.com/book/reference/assemblies.html" target="_blank">détails</a> sur la construction d&#8217;assemblies. Ici, je vais simplement construire un zip contenant l&#8217;ear et les fichiers properties externalisés. Dans un premier temps, il faut créer un projet supplémentaire :</p>
<table style="border-color: #000000; border-width: 1px; background-color: #d7d5d5;" border="1" width="500">
<tbody>
<tr>
<td>
<pre class="programlisting"><span style="font-size: medium;">&lt;<strong class="hl-tag"><span style="color: blue;">project</span></strong>&gt;
  [...]
  &lt;<strong class="hl-tag"><span style="color: blue;">dependencies</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">dependency</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">groupId</span></strong>&gt;fr.javasioux&lt;<strong class="hl-tag"><span style="color: blue;">/groupId</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">artifactId</span></strong>&gt;project-ear&lt;<strong class="hl-tag"><span style="color: blue;">/artifactId</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">version</span></strong>&gt;1.2&lt;<strong class="hl-tag"><span style="color: blue;">/version</span></strong>&gt;
      &lt;</span><span style="font-size: medium; color: blue;"><strong>type</strong></span><span style="font-size: medium;">&gt;ear&lt;<strong class="hl-tag"><span style="color: blue;">/type</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">/dependency</span></strong>&gt;
  &lt;<strong class="hl-tag"><span style="color: blue;">/dependencies</span></strong>&gt;
 &lt;<strong class="hl-tag"><span style="color: blue;">build</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">plugins</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">plugin</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">artifactId</span></strong>&gt;maven-assembly-plugin&lt;<strong class="hl-tag"><span style="color: blue;">/artifactId</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">version</span></strong>&gt;2.2-beta-2&lt;<strong class="hl-tag"><span style="color: blue;">/version</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">executions</span></strong>&gt;
          &lt;<strong class="hl-tag"><span style="color: blue;">execution</span></strong>&gt;
            &lt;<strong class="hl-tag"><span style="color: blue;">id</span></strong>&gt;create-zip-package&lt;<strong class="hl-tag"><span style="color: blue;">/id</span></strong>&gt;
            &lt;<strong class="hl-tag"><span style="color: blue;">phase</span></strong>&gt;package&lt;<strong class="hl-tag"><span style="color: blue;">/phase</span></strong>&gt;
            &lt;<strong class="hl-tag"><span style="color: blue;">goals</span></strong>&gt;
              &lt;<strong class="hl-tag"><span style="color: blue;">goal</span></strong>&gt;attached&lt;<strong class="hl-tag"><span style="color: blue;">/goal</span></strong>&gt;
            &lt;<strong class="hl-tag"><span style="color: blue;">/goals</span></strong>&gt;
            &lt;<strong class="hl-tag"><span style="color: blue;">configuration</span></strong>&gt;
              &lt;<strong class="hl-tag"><span style="color: blue;">descriptor</span></strong>&gt;
                  src/main/assembly/dep.xml
              &lt;<strong class="hl-tag"><span style="color: blue;">/descriptor</span></strong>&gt;
           &lt;<strong class="hl-tag"><span style="color: blue;">/configuration</span></strong>&gt;
          &lt;<strong class="hl-tag"><span style="color: blue;">/execution</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">/executions</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">/plugin</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">/plugins</span></strong>&gt;
  &lt;<strong class="hl-tag"><span style="color: blue;">/build</span></strong>&gt;
&lt;<strong class="hl-tag"><span style="color: blue;">/project</span></strong>&gt;</span></pre>
</td>
</tr>
</tbody>
</table>
<p>Ce pom dépend de l&#8217;ear et précise qu&#8217;il a besoin du plugin assembly et d&#8217;un fichier dep.xml décrivant comment sera fait l&#8217;assemblage :</p>
<table style="border-color: #000000; border-width: 1px; background-color: #dcdada;" border="1" width="500">
<tbody>
<tr>
<td>
<pre class="programlisting"><span style="font-size: medium;">&lt;<strong class="hl-tag"><span style="color: blue;">assembly</span></strong>&gt;
  &lt;<strong class="hl-tag"><span style="color: blue;">id</span></strong>&gt;project-assembly&lt;<strong class="hl-tag"><span style="color: blue;">/id</span></strong>&gt;
  &lt;<strong class="hl-tag"><span style="color: blue;">formats</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">format</span></strong>&gt;zip&lt;<strong class="hl-tag"><span style="color: blue;">/format</span></strong>&gt;
  &lt;<strong class="hl-tag"><span style="color: blue;">/formats</span></strong>&gt;
  &lt;<strong class="hl-tag"><span style="color: blue;">fileSets</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">fileSet</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">directory</span></strong>&gt;../project-war/src/main/resources&lt;<strong class="hl-tag"><span style="color: blue;">/directory</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">outputDirectory</span></strong>&gt;configuration&lt;<strong class="hl-tag"><span style="color: blue;">/</span></strong><strong><span><strong class="hl-tag"><span style="color: blue;">outputDirectory</span></strong></span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">includes</span></strong>&gt;
        &lt;<strong class="hl-tag"><span style="color: blue;">include</span></strong>&gt;**/*.*&lt;<strong class="hl-tag"><span style="color: blue;">/include</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">/includes</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">/fileSet</span></strong>&gt;
  &lt;<strong class="hl-tag"><span style="color: blue;">/fileSets</span></strong>&gt;
  &lt;<strong class="hl-tag"><span style="color: blue;">dependencySets</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">dependencySet</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">scope</span></strong>&gt;runtime&lt;<strong class="hl-tag"><span style="color: blue;">/scope</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">outputDirectory</span></strong>&gt;/&lt;<strong class="hl-tag"><span style="color: blue;">/outputDirectory</span></strong>&gt;
      &lt;<strong class="hl-tag"><span style="color: blue;">unpack</span></strong>&gt;false&lt;<strong class="hl-tag"><span style="color: blue;">/unpack</span></strong>&gt;
    &lt;<strong class="hl-tag"><span style="color: blue;">/dependencySet</span></strong>&gt;
  &lt;<strong class="hl-tag"><span style="color: blue;">/dependencySets</span></strong>&gt;
&lt;<strong class="hl-tag"><span style="color: blue;">/assembly</span></strong>&gt;</span></pre>
</td>
</tr>
</tbody>
</table>
<p>Ce petit fichier dep.xml nous dit qu&#8217;il faudra prendre les fichiers properties se trouvant dans les resources du projet war pour les mettre dans le répertoire configuration : c&#8217;est le <em>fileSets</em>. Il nous dit également qu&#8217;il faudra prendre les dépendances (l&#8217;ear) et le mettre à la racine sans le décompresser (remarque : unpack false est la valeur par défaut) : c&#8217;est le <em>dependencySets</em>.</p>
<p>En sortie de ce projet, après avoir saisi la commande <span style="font-size: medium; font-family: courier new,courier;">mvn assembly:assembly</span>, vous aurez un zip contenant l&#8217;ear à la racine et les fichiers resources dans un répertoire configuration. L&#8217;ear est donc indépendant de l&#8217;environnement, et la production se chargera de configurer les spécificités de chaque plateforme (base de données, resources spécifiques&#8230; et bien sûr le jndi qui vous permettra d&#8217;aller chercher cette configuration). Bien entendu, il faudra penser à livrer un minimum de documentation pour que la production puisse faire ce travail efficacement.</p>
<h2>Conclusion</h2>
<p>Maven fournit de nombreux moyens de gérer plusieurs environnements (et mes exemples étaient simples). Il faudra donc choisir celui qui s&#8217;adapte le plus à votre contexte :</p>
<ul>
<li>Est-ce que l&#8217;équipe de production accepte/impose les properties externalisées accessibles en JNDI ?</li>
<li>Est-ce que l&#8217;équipe de production ne déploie en prod que le package testé en préprod ?</li>
<li>Est-ce qu&#8217;on prend le temps d&#8217;investir dans un pom un peu plus complexe/complet mais qui nous permet de gérer efficacement les environnements ou bien on continue à la main au risque de faire des erreurs ?</li>
</ul>
<p>A défaut d&#8217;employer Maven pour générer un package avec le plugin assembly, vous pouvez toujours utiliser JNDI et fabriquer vous même le zip avec l&#8217;ensemble des binaires et de la config.</p>
<p>Après, si on est dans un process d&#8217;intégration continue un peu poussé (cf. mon billet sur l&#8217;<a title="Integration continue avec la prod" href="http://blog.octo.com/index.php/2008/10/06/162-integration-continue-performante-part-3" target="_blank">intéraction avec la production</a>), on pourra songer à utiliser Maven, relativement agréable une fois mis en place.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javasioux.fr/blog/2008/10/13/livraison-sur-environnements-multiples-avec-maven-ou-pas/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Transactions XA avec SQL Server</title>
		<link>http://www.javasioux.fr/blog/2008/10/04/transactions-xa-avec-sql-server/</link>
		<comments>http://www.javasioux.fr/blog/2008/10/04/transactions-xa-avec-sql-server/#comments</comments>
		<pubDate>Sat, 04 Oct 2008 20:51:03 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[jee]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[transaction]]></category>
		<category><![CDATA[xa]]></category>

		<guid isPermaLink="false">http://www.javasioux.fr/blog/?p=6</guid>
		<description><![CDATA[Si vous avez besoin d'accéder à plusieurs bases de données SQL Server via votre application JEE et le tout bien sûr dans une même transaction, voici les différentes actions à entreprendre pour que cela fonctionne.]]></description>
			<content:encoded><![CDATA[<h2>Configurer SQL Server</h2>
<p>Et oui, on ne peut pas simplement dire qu&#8217;on utilise une datasource XA, SQL Server doit disposer de différents éléments (notamment des procédures stockées spécifiques) pour que cela fonctionne.</p>
<ul>
<li>Pré-requis : SQL Serveur ne doit pas être installé sur Windows XP, des problèmes ont été rencontré sur cet OS, préférer Windows Server 2003.</li>
<li>Récupérer les <a title="drivers sql server" href="http://www.microsoft.com/downloads/details.aspx?displaylang=fr&amp;FamilyID=c47053eb-3b64-4794-950d-81e1ec91c1ba" target="_blank">drivers jdbc Microsoft pour SQL Server</a> (1.2).</li>
<li>Décompresser l&#8217;archive, aller dans le répertoire xa et choisir l&#8217;architecture de la machine (x86 ou 64bits).</li>
<li>Copier la dll <strong>sqljdbc_xa.dll</strong> dans le répertoire Binn de l&#8217;installation de SQL Server (ex : C:\Program Files\Microsoft SQL Server\MSSQL.2\MSSQL\Binn\).</li>
<li>Exécuter le script sql (<strong>xa_install.sql</strong>). Cela va créer des procédures stockées liées à XA (notamment master..xp_sqljdbc_xa_init).</li>
<li>L&#8217;utilisateur qui se connecte aux bases pour effectuer des requêtes transactionnées, typiquement l&#8217;utilisateur de votre application doit disposer du rôle <strong>SqlJDBCXAUser</strong> :</li>
</ul>
<pre>      use master
      go
      EXEC sp_grantdbaccess 'username', ' username'
      go
      EXEC sp_addrolemember \[SqlJDBCXAUser\], ' username'
      go</pre>
<h2>Configurer le DTC</h2>
<p>Ne le prenez pas mal, mais c&#8217;est comme cela qu&#8217;il s&#8217;appelle : le <strong>Distributed Transaction Coordinator</strong> (plus communément appelé MSDTC). C&#8217;est le service qui gère les transactions distribuées (transactions entre plusieurs bases). Plusieurs choses à vérifier à ce niveau :</p>
<ul>
<li>Vérifier que le service est démarré. Si ce n&#8217;est pas le cas, vous risquez une erreur du genre :</li>
</ul>
<pre>Caused by: javax.transaction.xa.XAException: java.sql.SQLException: Failed to create the XA control connection. Error: xp_sqljdbc_xa_init failure, status:0 msg:*** <strong>SQLJDBC_XA DTC_ERROR</strong> Context: xa_init, state=1, StatusCode:0 (0x00000000) ***.
at com.microsoft.sqlserver.jdbc.SQLServerXAResource.start(Unknown Source)</pre>
<ul>
<li>Il faut ensuite autoriser les transactions XA (extrait de la <a title="msdn" href="http://msdn.microsoft.com/fr-fr/library/aa342335(SQL.90).aspx" target="_blank">msdn</a>) :</li>
</ul>
<ol>
<li>Dans le Panneau de configuration, ouvrez Outils d&#8217;administration, puis ouvrez Services de composants.</li>
<li>Développez Services de composants, cliquez avec le bouton droit de la souris sur Poste de travail et sélectionnez Propriétés.</li>
<li>Cliquez sur l&#8217;onglet MSDTC, puis sur Configuration de la sécurité.</li>
<li>Activez la case à cocher Transactions XA, puis cliquez sur OK. Ceci entraînera le redémarrage du service MS DTC.</li>
<li>Cliquez à nouveau sur OK pour fermer la boîte de dialogue Propriétés, puis fermez Services de composants.</li>
<li>Arrêtez puis redémarrez SQL Server afin de garantir la synchronisation avec les modifications de MS DTC.</li>
</ol>
<h2>Configurer l&#8217;application</h2>
<p>Personnellement, j&#8217;utilise Spring 2.5 et Hibernate, mais vous pouvez travailler sur des versions antérieures, ca marchera aussi. Spring 2.5 fournit surtout des raccourcis&#8230;</p>
<h3>Datasources</h3>
<p>Vous déclarez vos datasources comme à votre habitude. En spring 2.5, vous pouvez simplement mettre :</p>
<pre>&lt;jee:jndi-lookup id="dataSource1" jndi-name="java:comp/env/jdbc/db1"/&gt;
&lt;jee:jndi-lookup id="dataSource2" jndi-name="java:comp/env/jdbc/db2"/&gt;</pre>
<h3>Transaction JTA</h3>
<p>C&#8217;est là que Spring 2.5 est intéressant car vous n&#8217;avez qu&#8217;à préciser <em>&lt;tx:jta-transaction-manager/&gt;</em> dans votre configuration spring pour qu&#8217;il se débrouille : il vérifie le type de serveur d&#8217;application dont vous disposez et choisit le transaction manager approprié. Par exemple pour Websphere, il utilisera le <em>WebSphereUowTransactionManager</em>. Plus de détails sur les transactions spring <a title="spring transaction" href="http://static.springframework.org/spring/docs/2.5.x/reference/transaction.html#transaction-application-server-integration" target="_blank">ici</a>.</p>
<h2>Configurer le serveur d&#8217;application</h2>
<p>Au niveau du serveur d&#8217;application, vous devez configurer les ressources jndi pour les datasources. Pour ce faire, utilisez la classe <em>com.microsoft.sqlserver.jdbc.SQLServerXADataSource</em>. Pour le reste, c&#8217;est du standard : configurez l&#8217;url, l&#8217;utilisateur, le password&#8230;</p>
<h2>Conclusion</h2>
<p>Alors que côté JEE, on reste dans une configuration assez standard et simple à mettre en place, niveau base de donnée, on a pas mal de choses à faire qui ne sont pas innées et qui ne s&#8217;inventent pas.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javasioux.fr/blog/2008/10/04/transactions-xa-avec-sql-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

