<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.guillaume-viel.com/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Guillaume VIEL :: blog Openfarm :: java jee tomcat linux</title>
  <link>http://blog.guillaume-viel.com/</link>
  <atom:link href="http://blog.guillaume-viel.com:82/feed/rss2" rel="self" type="application/rss+xml"/>
  <description>java, j2ee, jee, architecture, audit, conseil, expertise, SIG, géolocalisation, linux, logiciel libre</description>
  <language>fr</language>
  <pubDate>Wed, 16 May 2012 12:42:33 +0200</pubDate>
  <copyright>(c) 2008</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>vi commenter un bloc de code</title>
    <link>http://blog.guillaume-viel.com/post/2012/04/27/vi-commenter-un-bloc-de-code</link>
    <guid isPermaLink="false">urn:md5:31a54b25cb402ed4ae8c02ad1bbd1d88</guid>
    <pubDate>Fri, 27 Apr 2012 16:06:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>linux</category>
        <category>linux</category><category>regexp</category><category>vi</category>    
    <description>    &lt;p&gt;Après avoir essayé plusieurs trucs, j'ai enfin trouvé une solution
intéressante pour commenter un bloc de code sous vi qui ne propose pas du mode
visuel. Bien qu'intéressant quand on est sous vim, lorsqu'on est sur un serveur
sur une configuration Apache, les choses sont tout de suite moins visuelles...
L'idéal est d'utiliser les &lt;q&gt;markers&lt;/q&gt; et la &lt;q&gt;substitution&lt;/q&gt; :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;se placer sur la première ligne du bloc de code et taper
&lt;pre&gt;
&lt;code&gt;ma&lt;/code&gt;
&lt;/pre&gt;
pour placer le marqueur a&lt;/li&gt;
&lt;li&gt;positionner le curseur sur la dernière ligne du bloc à commenter&lt;/li&gt;
&lt;li&gt;du marqueur a ('a) à la ligne courante (.) remplacer chaque début de ligne
par un # :
&lt;pre&gt;
&lt;code&gt;:'a,.s/^/#/&lt;/code&gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Et voilà!&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2012/04/27/vi-commenter-un-bloc-de-code#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2012/04/27/vi-commenter-un-bloc-de-code#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/678738</wfw:commentRss>
      </item>
    
  <item>
    <title>Flex &quot;RSL error 1 of 1&quot;</title>
    <link>http://blog.guillaume-viel.com/post/2012/04/27/Flex-RSL-error</link>
    <guid isPermaLink="false">urn:md5:b752d4234d1e83f46074ca950d733341</guid>
    <pubDate>Fri, 27 Apr 2012 14:56:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>flex</category>
        <category>flex</category>    
    <description>    &lt;p&gt;Au secours! Lorsque Flex vous met un joli message &lt;q&gt;RSL error 1 of 1&lt;/q&gt;
c'est que vous avez tout simplement oublié de lui indiquer une librairie Flex
(librairie SWC ou SWZ).&lt;/p&gt;
&lt;p&gt;Dans mon cas c'est la librairie RPC (il y a en trois essentiel framework,
rpc et datavizualisation).&lt;/p&gt;
&lt;p&gt;Ensuite tout va beaucoup mieux!&lt;/p&gt;
&lt;p&gt;Sources :&lt;/p&gt;
&lt;p&gt;http://livedocs.adobe.com/flex/3/html/help.html?content=rsl_09.html&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2012/04/27/Flex-RSL-error#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2012/04/27/Flex-RSL-error#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/678717</wfw:commentRss>
      </item>
    
  <item>
    <title>Log4j : changer le niveau de log à chaud via JMX</title>
    <link>http://blog.guillaume-viel.com/post/2012/01/31/Log4j-%3A-changer-le-niveau-de-log-%C3%A0-chaud-via-JMX</link>
    <guid isPermaLink="false">urn:md5:30c1b0c37223c5a6d1f4e377be209b01</guid>
    <pubDate>Tue, 31 Jan 2012 10:49:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>java</category><category>jconsole</category><category>jee</category><category>jmx</category><category>log4j</category><category>logging</category><category>spring</category><category>springframework</category><category>visualvm</category>    
    <description>&lt;p&gt;Changer le niveau de log directement sans avoir à redéployer l'application
est parfois indispensable sur des plateformes critiques où il est impossible
d'interrompre le service. C'est aussi un moyen de déboguer directement sur une
plateforme qui est la seule à présenter un bug non reproductible ailleurs.&lt;/p&gt;
&lt;p&gt;Il existe plusieurs solutions dont :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;relecture de la configuration Log4j à intervalle régulier; il suffit alors
de modifier la configuration des niveaux de log directement (soit avec l'API
Log4j, soit avec les classes utilitaires de Spring Log4jWebConfigurer)&lt;/li&gt;
&lt;li&gt;changement des niveaux de log à l'aide de JMX&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C'est cette dernière solution que je préfère, car il est généralement
déconseillé de modifier directement des fichiers à chaud dans un serveur
d'applications.&lt;/p&gt;
&lt;p&gt;Il faut d'abord créer une classe avec une méthode permettant de modifier le
niveau de log de n'importe quel package :&lt;/p&gt;    &lt;br /&gt;
&lt;pre&gt;
&lt;code&gt;import org.apache.log4j.Level;&lt;br /&gt;import org.apache.log4j.Logger;&lt;br /&gt;import org.springframework.jmx.export.annotation.ManagedOperation;&lt;br /&gt;import org.springframework.jmx.export.annotation.ManagedOperationParameter;&lt;br /&gt;import org.springframework.jmx.export.annotation.ManagedOperationParameters;&lt;br /&gt;import org.springframework.jmx.export.annotation.ManagedResource;&lt;br /&gt;&lt;br /&gt;@ManagedResource(description=&amp;quot;Log4j debug level modifier&amp;quot;)&lt;br /&gt;public class Log4jLevelChanger {&lt;br /&gt;&lt;br /&gt; @ManagedOperation(description = &amp;quot;Change log level of a package&amp;quot;)&lt;br /&gt;  @ManagedOperationParameters({&lt;br /&gt;                     @ManagedOperationParameter(name = &amp;quot;loggerName&amp;quot;, description = &amp;quot;package name&amp;quot;),&lt;br /&gt;                    @ManagedOperationParameter(name = &amp;quot;level&amp;quot;, description = &amp;quot;log level (DEBUG, INFO, etc.)&amp;quot;)&lt;br /&gt; })&lt;br /&gt;        public void setLogLevel(String loggerName, String level) {&lt;br /&gt;                if (&amp;quot;debug&amp;quot;.equalsIgnoreCase(level)) {&lt;br /&gt;                    Logger.getLogger(loggerName).setLevel(Level.DEBUG);&lt;br /&gt;               } else if (&amp;quot;info&amp;quot;.equalsIgnoreCase(level)) {&lt;br /&gt;                      Logger.getLogger(loggerName).setLevel(Level.INFO);&lt;br /&gt;                } else if (&amp;quot;error&amp;quot;.equalsIgnoreCase(level)) {&lt;br /&gt;                     Logger.getLogger(loggerName).setLevel(Level.ERROR);&lt;br /&gt;               } else if (&amp;quot;fatal&amp;quot;.equalsIgnoreCase(level)) {&lt;br /&gt;                     Logger.getLogger(loggerName).setLevel(Level.FATAL);&lt;br /&gt;               } else if (&amp;quot;warn&amp;quot;.equalsIgnoreCase(level)) {&lt;br /&gt;                      Logger.getLogger(loggerName).setLevel(Level.WARN);&lt;br /&gt;                } else if (&amp;quot;trace&amp;quot;.equalsIgnoreCase(level)) {&lt;br /&gt;                     Logger.getLogger(loggerName).setLevel(Level.TRACE);&lt;br /&gt;               } else if (&amp;quot;off&amp;quot;.equalsIgnoreCase(level)) {&lt;br /&gt;                       Logger.getLogger(loggerName).setLevel(Level.OFF);&lt;br /&gt;         } else if (&amp;quot;all&amp;quot;.equalsIgnoreCase(level)) {&lt;br /&gt;                       Logger.getLogger(loggerName).setLevel(Level.ALL);&lt;br /&gt;         }&lt;br /&gt; }&lt;br /&gt;}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;On peut remarquer qu'on a déjà préparé le terrain pour Spring avec les
annotations @ManagedXXX. Cette classe sera instanciée par Spring comme
singleton et exposée via JMX :&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;        xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;     xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;     xsi:schemaLocation=&amp;quot;&lt;br /&gt;              http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&lt;br /&gt;              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd&amp;quot;&amp;gt;&lt;br /&gt;   &lt;br /&gt;&amp;lt;!-- RECUPERATION DU SERVEUR MBEAN DE LA PLATEFORME --&amp;gt;             &lt;br /&gt;&amp;lt;bean id=&amp;quot;mbeanServer&amp;quot; class=&amp;quot;java.lang.management.ManagementFactory&amp;quot; factory-method=&amp;quot;getPlatformMBeanServer&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- bean Log4jLevelChanger en singleton --&amp;gt;&lt;br /&gt;&amp;lt;bean id=&amp;quot;log4jLevelChanger&amp;quot; class=&amp;quot;fr.openfarm.util.Log4jLevelChanger&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- utilisation du MBean exporter de Spring pour exposer la méthode setLogLevel dans JMX --&amp;gt;&lt;br /&gt;&amp;lt;bean id=&amp;quot;exporter&amp;quot; class=&amp;quot;org.springframework.jmx.export.MBeanExporter&amp;quot; lazy-init=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;beans&amp;quot;&amp;gt;&lt;br /&gt;             &amp;lt;map&amp;gt;&lt;br /&gt;                       &amp;lt;entry key=&amp;quot;fr.openfarm.util:name=Log4jLevelChanger&amp;quot; value-ref=&amp;quot;log4jLevelChanger&amp;quot; /&amp;gt;&lt;br /&gt;               &amp;lt;/map&amp;gt;&lt;br /&gt;      &amp;lt;/property&amp;gt;&lt;br /&gt; &amp;lt;property name=&amp;quot;assembler&amp;quot; ref=&amp;quot;metadataAssembler&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;namingStrategy&amp;quot; ref=&amp;quot;namingStrategy&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;       &lt;br /&gt;&lt;br /&gt;&amp;lt;bean id=&amp;quot;jmxAttributeSource&amp;quot; class=&amp;quot;org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource&amp;quot;/&amp;gt;&lt;br /&gt;         &lt;br /&gt;&amp;lt;bean id=&amp;quot;namingStrategy&amp;quot; class=&amp;quot;org.springframework.jmx.export.naming.MetadataNamingStrategy&amp;quot;&amp;gt;&lt;br /&gt;       &amp;lt;property name=&amp;quot;attributeSource&amp;quot; ref=&amp;quot;jmxAttributeSource&amp;quot;/&amp;gt;&lt;br /&gt;   &amp;lt;/bean&amp;gt;&lt;br /&gt;   &lt;br /&gt;&amp;lt;bean id=&amp;quot;metadataAssembler&amp;quot; class=&amp;quot;org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler&amp;quot;&amp;gt;&lt;br /&gt;       &amp;lt;property name=&amp;quot;attributeSource&amp;quot; ref=&amp;quot;jmxAttributeSource&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;On indique que les annotations seront utilisées comme source de données de
configuration pour JMX avec le bean &lt;code&gt;jmxAttributeSource&lt;/code&gt;. Ensuite,
on indique que la stratégie de nommage des MBeans JMX sera faite à partir des
annotations (bean &lt;code&gt;namingStrategy&lt;/code&gt;) et que les metadata du MBean
également utiliseront les annotations (bean &lt;code&gt;metadataAssembler&lt;/code&gt;). Si
les metadata ne sont pas utilisés, les noms de paramètres affichés dans la
console JMX seront alors nommés arbitrairement p1 et p2.&lt;/p&gt;
&lt;p&gt;Enfin, les deux beans &lt;code&gt;namingStrategy&lt;/code&gt; et
&lt;code&gt;metadataAssembler&lt;/code&gt; sont passés en attribut de
l'&lt;code&gt;exporter&lt;/code&gt; qui sera chargé d'exposer le ou les MBeans dans
JMX.&lt;/p&gt;
&lt;p&gt;Voici le résultat dans JVisualVM (ou jconsole) :&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.guillaume-viel.com/public/monitoring/jmx_mbean_log4j_level_modifier.png&quot; title=&quot;log4j debug level modifier&quot;&gt;&lt;img title=&quot;log4j debug level modifier&quot; style=&quot;float: center; margin: 0 1em 1em 0;&quot; alt=&quot;log4j debug level modifier&quot; src=&quot;http://blog.guillaume-viel.com/public/monitoring/.jmx_mbean_log4j_level_modifier_m.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2012/01/31/Log4j-%3A-changer-le-niveau-de-log-%C3%A0-chaud-via-JMX#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2012/01/31/Log4j-%3A-changer-le-niveau-de-log-%C3%A0-chaud-via-JMX#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/663830</wfw:commentRss>
      </item>
    
  <item>
    <title>Log4j avec Spring et applications multiples dans Tomcat</title>
    <link>http://blog.guillaume-viel.com/post/2012/01/04/Log4j-avec-Spring-et-applications-multiples-dans-Tomcat</link>
    <guid isPermaLink="false">urn:md5:8c1b152d0da58447f493d330d4b2a172</guid>
    <pubDate>Wed, 04 Jan 2012 12:15:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>java</category><category>jee</category><category>log4j</category><category>logging</category><category>springframework</category><category>tomcat</category>    
    <description>&lt;p&gt;Je déploie habituellement les applications web dans Tomcat en multi-instance
avec une instance Tomcat par application (ceux qui croient que c'est une
hérésie iront voir les concepteurs de Tomcat Mark Thomas et Filip Hanik qui
préconisent eux mêmes cette solution). Cependant, dans certains contextes, et
notamment chez certains clients, les contraintes font que l'on est obligé de
faire autrement...&lt;/p&gt;
&lt;p&gt;Dans le cas présent, c'est la configuration de log4j via Spring qui pose
(encore) problème : je déploie 2 applications identiques (avec configuration
applicative légèrement différente) sous 2 contextes différents dans le même
serveur Tomcat. Se posent donc 2 problèmes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;il faut pouvoir packager l'application sous des formes différentes et
notamment 2 contextes différents : /my-app1 et /my-app2, donc paramétrer le
packaging&lt;/li&gt;
&lt;li&gt;la configuration log4j est à priori identique pour ces 2 applications
(packages identiques) : ceci pose le problème de la séparation des logs (et
éventuellement la différenciation des niveaux de log)&lt;/li&gt;
&lt;/ul&gt;    Voici un exemple de configuration Log4j utilisée :
&lt;pre&gt;
&lt;code&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE log4j:configuration SYSTEM &amp;quot;log4j.dtd&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;log4j:configuration debug=&amp;quot;true&amp;quot; xmlns:log4j=&amp;quot;http://jakarta.apache.org/log4j/&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;   &amp;lt;appender name=&amp;quot;console&amp;quot; class=&amp;quot;org.apache.log4j.ConsoleAppender&amp;quot;&amp;gt;&lt;br /&gt;          &amp;lt;param name=&amp;quot;Target&amp;quot; value=&amp;quot;System.out&amp;quot; /&amp;gt;&lt;br /&gt;          &amp;lt;layout class=&amp;quot;org.apache.log4j.PatternLayout&amp;quot;&amp;gt;&lt;br /&gt;                     &amp;lt;param name=&amp;quot;ConversionPattern&amp;quot; value=&amp;quot;%d{yyyy-MM-dd HH:mm:ss} %p [%c] - %m%n&amp;quot; /&amp;gt;&lt;br /&gt;           &amp;lt;/layout&amp;gt;&lt;br /&gt;   &amp;lt;/appender&amp;gt;&lt;br /&gt; &lt;br /&gt;  &amp;lt;appender name=&amp;quot;logFile&amp;quot; class=&amp;quot;org.apache.log4j.DailyRollingFileAppender&amp;quot;&amp;gt;&lt;br /&gt;         &amp;lt;param name=&amp;quot;File&amp;quot; value=&amp;quot;logs/${app.ctx}.log&amp;quot; /&amp;gt;&lt;br /&gt;           &amp;lt;param name=&amp;quot;DatePattern&amp;quot; value=&amp;quot;'.'yyyy-MM-dd&amp;quot;/&amp;gt;&lt;br /&gt;           &amp;lt;param name=&amp;quot;Append&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;                &amp;lt;layout class=&amp;quot;org.apache.log4j.PatternLayout&amp;quot;&amp;gt;&lt;br /&gt;                     &amp;lt;param name=&amp;quot;ConversionPattern&amp;quot; value=&amp;quot;%d{yyyy-MM-dd HH:mm:ss} %p [%c] - %m%n&amp;quot; /&amp;gt;&lt;br /&gt;           &amp;lt;/layout&amp;gt;&lt;br /&gt;   &amp;lt;/appender&amp;gt;&lt;br /&gt; &lt;br /&gt;  &amp;lt;appender name=&amp;quot;monitoring&amp;quot; class=&amp;quot;org.apache.log4j.DailyRollingFileAppender&amp;quot;&amp;gt;&lt;br /&gt;              &amp;lt;param name=&amp;quot;File&amp;quot; value=&amp;quot;logs/${app.ctx}_monitoring.log&amp;quot; /&amp;gt;&lt;br /&gt;                &amp;lt;param name=&amp;quot;DatePattern&amp;quot; value=&amp;quot;'.'yyyy-MM-dd&amp;quot;/&amp;gt;&lt;br /&gt;           &amp;lt;param name=&amp;quot;Append&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;                &amp;lt;layout class=&amp;quot;org.apache.log4j.PatternLayout&amp;quot;&amp;gt;&lt;br /&gt;                     &amp;lt;param name=&amp;quot;ConversionPattern&amp;quot; value=&amp;quot;%d{yyyy-MM-dd HH:mm:ss} %p - %m%n&amp;quot; /&amp;gt;&lt;br /&gt;                &amp;lt;/layout&amp;gt;&lt;br /&gt;   &amp;lt;/appender&amp;gt;&lt;br /&gt; &lt;br /&gt;  &amp;lt;appender name=&amp;quot;errors&amp;quot; class=&amp;quot;org.apache.log4j.DailyRollingFileAppender&amp;quot;&amp;gt;&lt;br /&gt;          &amp;lt;param name=&amp;quot;File&amp;quot; value=&amp;quot;logs/${app.ctx}_errors.log&amp;quot; /&amp;gt;&lt;br /&gt;            &amp;lt;param name=&amp;quot;DatePattern&amp;quot; value=&amp;quot;'.'yyyy-MM-dd&amp;quot;/&amp;gt;&lt;br /&gt;           &amp;lt;param name=&amp;quot;Append&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;                &amp;lt;layout class=&amp;quot;org.apache.log4j.PatternLayout&amp;quot;&amp;gt;&lt;br /&gt;                     &amp;lt;param name=&amp;quot;ConversionPattern&amp;quot; value=&amp;quot;%d{yyyy-MM-dd HH:mm:ss} %p [%c] - %m%n&amp;quot; /&amp;gt;&lt;br /&gt;           &amp;lt;/layout&amp;gt;&lt;br /&gt;   &amp;lt;/appender&amp;gt;       &lt;br /&gt;&lt;br /&gt;    &amp;lt;appender name=&amp;quot;requests&amp;quot; class=&amp;quot;org.apache.log4j.DailyRollingFileAppender&amp;quot;&amp;gt;&lt;br /&gt;                &amp;lt;param name=&amp;quot;File&amp;quot; value=&amp;quot;logs/${app.ctx}_requests.log&amp;quot; /&amp;gt;&lt;br /&gt;          &amp;lt;param name=&amp;quot;DatePattern&amp;quot; value=&amp;quot;'.'yyyy-MM-dd&amp;quot;/&amp;gt;&lt;br /&gt;           &amp;lt;param name=&amp;quot;Append&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;                &amp;lt;layout class=&amp;quot;org.apache.log4j.PatternLayout&amp;quot;&amp;gt;&lt;br /&gt;                     &amp;lt;param name=&amp;quot;ConversionPattern&amp;quot; value=&amp;quot;%d{yyyy-MM-dd HH:mm:ss} %p [%c] - %m%n&amp;quot; /&amp;gt;&lt;br /&gt;           &amp;lt;/layout&amp;gt;&lt;br /&gt;   &amp;lt;/appender&amp;gt;       &lt;br /&gt;          &lt;br /&gt;  &amp;lt;logger name=&amp;quot;org.apache.catalina&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;              &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;org.apache.jasper&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;                &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;org.springframework&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;              &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;   &lt;br /&gt;  &amp;lt;logger name=&amp;quot;org.hibernate&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;org.hibernate.cfg&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;                &amp;lt;level value=&amp;quot;WARN&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;   &lt;br /&gt;  &amp;lt;logger name=&amp;quot;org.codehaus.xfire&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;               &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;   &lt;br /&gt;  &amp;lt;logger name=&amp;quot;org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;          &amp;lt;level value=&amp;quot;FATAL&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;appender-ref ref=&amp;quot;errors&amp;quot; /&amp;gt;&lt;br /&gt;               &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;org.codehaus.xfire.handler.DefaultFaultHandler&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;           &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;errors&amp;quot; /&amp;gt;&lt;br /&gt;               &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;           &lt;br /&gt;  &amp;lt;logger name=&amp;quot;net.sf.ehcache&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;           &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;   &lt;br /&gt;  &amp;lt;logger name=&amp;quot;org.apache.commons.httpclient&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;org.apache.commons.beanutils.BeanUtils&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;           &amp;lt;level value=&amp;quot;WARN&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;org.apache.commons.beanutils.PropertyUtils&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;               &amp;lt;level value=&amp;quot;WARN&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;   &lt;br /&gt;  &amp;lt;logger name=&amp;quot;org.apache.commons.digester&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;              &amp;lt;level value=&amp;quot;WARN&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;org.hibernate.cache&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;              &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;net.sf.ehcache.hibernate&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;         &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;freemarker.cache&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;         &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;freemarker.bean&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;          &amp;lt;level value=&amp;quot;WARN&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt; &lt;br /&gt;    &amp;lt;logger name=&amp;quot;fr.openfarm&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;              &amp;lt;level value=&amp;quot;DEBUG&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;fr.openfarm.service.impl.ServiceImpl&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;             &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;fr.openfarm.service.impl.ServiceImpl2&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;fr.openfarm.domain.model.HibernateSchemaInterceptor&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;              &amp;lt;level value=&amp;quot;DEBUG&amp;quot; /&amp;gt;&lt;br /&gt;             &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;                                                   &lt;br /&gt;  &amp;lt;logger name=&amp;quot;fr.openfarm.service.exception&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;errors&amp;quot; /&amp;gt;&lt;br /&gt;               &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;logger name=&amp;quot;fr.openfarm.ws.fault&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;             &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;errors&amp;quot; /&amp;gt;&lt;br /&gt;               &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/logger&amp;gt; &lt;br /&gt;&lt;br /&gt;    &amp;lt;logger name=&amp;quot;fr.openfarm.aop.PerformanceProfilerAspect&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;                &amp;lt;level value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;requests&amp;quot;/&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;monitoring&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/logger&amp;gt;&lt;br /&gt;            &lt;br /&gt; &amp;lt;root&amp;gt;&lt;br /&gt;              &amp;lt;priority value=&amp;quot;INFO&amp;quot; /&amp;gt;&lt;br /&gt;           &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;appender-ref ref=&amp;quot;logFile&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/root&amp;gt;&lt;br /&gt;     &lt;br /&gt;&amp;lt;/log4j:configuration&amp;gt; &lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;La configuration est ensuite activée par Spring au niveau du fichier web.xml
grâce au org.springframework.web.util.Log4jConfigListener pour lequel il faut
ajouter le paramètre log4jConfigLocation qui indique où se trouve le fichier de
configuration log4j. Dans notre cas, ce nom de fichier est paramétré grâce à
une variable d'environnement java &amp;quot;env&amp;quot; que l'on passera à la JVM (ex:
-Denv=preprod pour choisir le fichier log4j-preprod.xml ) et l'on considère que
les niveaux de logs n'auront pas à être différenciés. Les deux applications
étant à l'intérieur du même serveur Tomcat, donc la même JVM, partagerons donc
le même fichier de log log4j-${env}.xml&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;web-app xmlns=&amp;quot;http://java.sun.com/xml/ns/j2ee&amp;quot;&lt;br /&gt;     xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;     xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&amp;quot;&lt;br /&gt;      version=&amp;quot;2.4&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;   &amp;lt;display-name&amp;gt;OPENFARM WebServices&amp;lt;/display-name&amp;gt;&lt;br /&gt;     &lt;br /&gt;  &amp;lt;context-param&amp;gt;&lt;br /&gt;            &amp;lt;param-name&amp;gt;log4jConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;         &amp;lt;param-value&amp;gt;/WEB-INF/classes/log4j-${env}.xml&amp;lt;/param-value&amp;gt;&lt;br /&gt; &amp;lt;/context-param&amp;gt;&lt;br /&gt;    &lt;br /&gt;  &amp;lt;context-param&amp;gt;&lt;br /&gt;             &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;                &amp;lt;param-value&amp;gt;&lt;br /&gt;                       classpath:applicationContext.xml,&lt;br /&gt;                 classpath:applicationContext-hibernate.xml,&lt;br /&gt;                       /WEB-INF/xfire-servlet.xml&lt;br /&gt;                &amp;lt;/param-value&amp;gt;&lt;br /&gt;      &amp;lt;/context-param&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;listener&amp;gt;&lt;br /&gt;         &amp;lt;listener-class&amp;gt;&lt;br /&gt;                   org.springframework.web.util.Log4jConfigListener&lt;br /&gt;         &amp;lt;/listener-class&amp;gt;&lt;br /&gt;  &amp;lt;/listener&amp;gt;&lt;br /&gt;    &lt;br /&gt;       &amp;lt;listener&amp;gt;&lt;br /&gt;          &amp;lt;listener-class&amp;gt;&lt;br /&gt;                    org.springframework.web.context.ContextLoaderListener&lt;br /&gt;             &amp;lt;/listener-class&amp;gt;&lt;br /&gt;   &amp;lt;/listener&amp;gt;&lt;br /&gt;&lt;br /&gt;   &amp;lt;!-- XFire SOAP servlets --&amp;gt;&lt;br /&gt;        &amp;lt;servlet&amp;gt;&lt;br /&gt;           &amp;lt;servlet-name&amp;gt;xfire&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;            &amp;lt;servlet-class&amp;gt;&lt;br /&gt;                     org.codehaus.xfire.spring.XFireSpringServlet&lt;br /&gt;              &amp;lt;/servlet-class&amp;gt;&lt;br /&gt;    &amp;lt;/servlet&amp;gt;&lt;br /&gt;  &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;           &amp;lt;servlet-name&amp;gt;xfire&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;            &amp;lt;url-pattern&amp;gt;/services/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;        &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;resource-ref&amp;gt;&lt;br /&gt;        &amp;lt;description&amp;gt;SYCAR database&amp;lt;/description&amp;gt;&lt;br /&gt;     &amp;lt;res-ref-name&amp;gt;jdbc/mydb&amp;lt;/res-ref-name&amp;gt;&lt;br /&gt;        &amp;lt;res-ref-type&amp;gt;javax.sql.DataSource&amp;lt;/res-ref-type&amp;gt;&lt;br /&gt;     &amp;lt;res-auth&amp;gt;Container&amp;lt;/res-auth&amp;gt;&lt;br /&gt;      &amp;lt;/resource-ref&amp;gt;&lt;br /&gt;     &lt;br /&gt;  &amp;lt;!-- Compress SOAP servlets --&amp;gt;&lt;br /&gt;     &amp;lt;filter&amp;gt;&lt;br /&gt;            &amp;lt;filter-name&amp;gt;CompressingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;          &amp;lt;filter-class&amp;gt;&lt;br /&gt;                      com.planetj.servlet.filter.compression.CompressingFilter&lt;br /&gt;          &amp;lt;/filter-class&amp;gt;&lt;br /&gt;             &amp;lt;init-param&amp;gt;&lt;br /&gt;                        &amp;lt;param-name&amp;gt;debug&amp;lt;/param-name&amp;gt;&lt;br /&gt;                        &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;&lt;br /&gt;               &amp;lt;/init-param&amp;gt;&lt;br /&gt;               &amp;lt;init-param&amp;gt;&lt;br /&gt;                        &amp;lt;param-name&amp;gt;statsEnabled&amp;lt;/param-name&amp;gt;&lt;br /&gt;                 &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;&lt;br /&gt;               &amp;lt;/init-param&amp;gt;&lt;br /&gt;       &amp;lt;/filter&amp;gt;&lt;br /&gt;   &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;            &amp;lt;filter-name&amp;gt;CompressingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;          &amp;lt;url-pattern&amp;gt;/services/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;        &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;welcome-file-list&amp;gt;&lt;br /&gt;         &amp;lt;welcome-file&amp;gt;index.html&amp;lt;/welcome-file&amp;gt;&lt;br /&gt;       &amp;lt;/welcome-file-list&amp;gt;&lt;br /&gt;&amp;lt;/web-app&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Cette configuration appliquée aux deux applications présente un premier
problème : les noms des fichier de log des appenders ne peuvent pas être
identiques si l'on veut que les logs soient bien séparées pour chaque
application. On remarquera d'ailleurs que nous avons mis logs/${app.ctx}_*.log
pour les noms de fichier. En effet, la seule possibilité est de générer un
fichier log4j différent selon le contexte de l'application à la compilation.
Pour cela nous utilisons les &lt;a hreflang=&quot;en&quot; href=&quot;http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html&quot;&gt;filtres
maven&lt;/a&gt; qui permettent d'effectuer des remplacements dans les fichiers
textes. Il faut ajouter quelques éléments de configuration à plusieurs endroits
dans notre fichier pom.xml :&lt;/p&gt;
&lt;p&gt;D'abord au niveau du plugin war pour qu'il applique le filtrage et fasse le
remplacement des properties / variables passées à maven dans le fichier web.xml
:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;             &amp;lt;plugin&amp;gt;&lt;br /&gt;                    &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;                   &amp;lt;artifactId&amp;gt;maven-war-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;                     &amp;lt;version&amp;gt;2.1.1&amp;lt;/version&amp;gt;&lt;br /&gt;                              &amp;lt;configuration&amp;gt;&lt;br /&gt;                                     &amp;lt;!-- filtrage du fichier web.xml pour injecter la valeur app.ctx --&amp;gt;&lt;br /&gt;                                        &amp;lt;filteringDeploymentDescriptors&amp;gt;true&amp;lt;/filteringDeploymentDescriptors&amp;gt;&lt;br /&gt;                         &amp;lt;/configuration&amp;gt;&lt;br /&gt;            &amp;lt;/plugin&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Ensuite au niveau de la gestion des fichiers ressources pendant la phase de
compilation pour qu'il applique le filtrage et fasse le remplacement des
properties / variables passées à maven dans les fichiers xml  ou
properties. On notera d'ailleurs que le tag &amp;lt;finalName&amp;gt; prend aussi la
valeur ${app.ctx} puisque c'est le nom du contexte web de l'appli.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;     &amp;lt;build&amp;gt;&lt;br /&gt;             &amp;lt;!-- le nom du contexte de l'application est passé en paramètre --&amp;gt;&lt;br /&gt;         &amp;lt;finalName&amp;gt;${app.ctx}&amp;lt;/finalName&amp;gt;&lt;br /&gt;             &amp;lt;resources&amp;gt;&lt;br /&gt;                 &amp;lt;!-- filtrage des fichiers ressources log4j.xml et *.properties --&amp;gt;&lt;br /&gt;                 &amp;lt;resource&amp;gt;&lt;br /&gt;                          &amp;lt;directory&amp;gt;src/main/resources&amp;lt;/directory&amp;gt;&lt;br /&gt;                             &amp;lt;filtering&amp;gt;true&amp;lt;/filtering&amp;gt;&lt;br /&gt;                           &amp;lt;includes&amp;gt;&lt;br /&gt;                                          &amp;lt;include&amp;gt;**/*.xml&amp;lt;/include&amp;gt;&lt;br /&gt;                                   &amp;lt;include&amp;gt;**/*.properties&amp;lt;/include&amp;gt;&lt;br /&gt;                            &amp;lt;/includes&amp;gt;&lt;br /&gt;                 &amp;lt;/resource&amp;gt;&lt;br /&gt;                 &amp;lt;!-- pas de filtrage pour les autres fichiers notamment binaires --&amp;gt;&lt;br /&gt;                        &amp;lt;resource&amp;gt;&lt;br /&gt;                          &amp;lt;directory&amp;gt;src/main/resources&amp;lt;/directory&amp;gt;&lt;br /&gt;                             &amp;lt;filtering&amp;gt;false&amp;lt;/filtering&amp;gt;&lt;br /&gt;                          &amp;lt;excludes&amp;gt;&lt;br /&gt;                                          &amp;lt;exclude&amp;gt;**/*.xml&amp;lt;/exclude&amp;gt;&lt;br /&gt;                                   &amp;lt;exclude&amp;gt;**/*.properties&amp;lt;/exclude&amp;gt;&lt;br /&gt;                            &amp;lt;/excludes&amp;gt;&lt;br /&gt;                 &amp;lt;/resource&amp;gt;&lt;br /&gt;         &amp;lt;/resources&amp;gt;&lt;br /&gt;        [...]&lt;br /&gt;&lt;br /&gt;       &amp;lt;/build&amp;gt; &lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;ATTENTION : il faut prendre quelques précautions avec les filtres maven,
notamment en ajoutant une section ne filtrant pas les autres fichiers binaires
sous peine de corrompre ceux-ci puisque maven recopie ces fichiers en les
considérant comme des fichiers textes!&lt;/p&gt;
&lt;p&gt;Il suffit alors de compiler les deux applications comme suit :&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
$ mvn -Dapp.ctx=my-app1 clean package&lt;br /&gt;$ mvn -Dapp.ctx=my-app2 clean package
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;On peut alors constater qu'il y a bien eu modification des noms des fichiers
de log pour chacune des applications my-app1 et my-app2. Cependant lors de
l'exécution, on s'aperçoit qu'une seule des applications est logguée et que
l'erreur suivante apparait :&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
Exception lors de l'envoi de l'événement contexte initialisé (context initialized) à  l'instance de classe d'écoute (listener) org.springframework.web.util.Log4jConfigListener&lt;br /&gt;java.lang.IllegalStateException: Web app root system property already set to different value: 'webapp.root' = [/tomcat-webapps/my-app2/] instead of [/tomcat-webapps/my-app1/] - Choose unique values for the 'webAppRootKey' context-param in your web.xml files!&lt;br /&gt;    at org.springframework.web.util.WebUtils.setWebAppRootSystemProperty(WebUtils.java:132)&lt;br /&gt;    at org.springframework.web.util.Log4jWebConfigurer.initLogging(Log4jWebConfigurer.java:117)&lt;br /&gt;    at org.springframework.web.util.Log4jConfigListener.contextInitialized(Log4jConfigListener.java:51)&lt;br /&gt;    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3729)&lt;br /&gt;    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4187)&lt;br /&gt;    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:759)&lt;br /&gt;    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:739)&lt;br /&gt;    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:524)&lt;br /&gt;    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:608)&lt;br /&gt;    at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:535)&lt;br /&gt;    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:470)&lt;br /&gt;    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1122)&lt;br /&gt;    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:310)&lt;br /&gt;    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)&lt;br /&gt;    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1021)&lt;br /&gt;    at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)&lt;br /&gt;    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1013)&lt;br /&gt;    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)&lt;br /&gt;    at org.apache.catalina.core.StandardService.start(StandardService.java:450)&lt;br /&gt;    at org.apache.catalina.core.StandardServer.start(StandardServer.java:709)&lt;br /&gt;    at org.apache.catalina.startup.Catalina.start(Catalina.java:551)&lt;br /&gt;    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&lt;br /&gt;    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)&lt;br /&gt;    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)&lt;br /&gt;    at java.lang.reflect.Method.invoke(Method.java:597)&lt;br /&gt;    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:294)&lt;br /&gt;    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:432)
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;En regardant la documentation Spring sur &lt;a hreflang=&quot;en&quot; href=&quot;http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/web/util/Log4jWebConfigurer.html&quot;&gt;
Log4jWebConfigurer&lt;/a&gt;, on peut lire la mise en garde suivante :&lt;/p&gt;
&lt;p&gt;&lt;q&gt;&lt;strong&gt;WARNING:&lt;/strong&gt; Some containers (like Tomcat) do &lt;em&gt;not&lt;/em&gt;
keep system properties separate per web app. You have to use unique
&amp;quot;webAppRootKey&amp;quot; context-params per web app then, to avoid clashes. Other
containers like Resin do isolate each web app's system properties: Here you can
use the default key (i.e. no &amp;quot;webAppRootKey&amp;quot; context-param at all) without
worrying&lt;/q&gt;&lt;/p&gt;
&lt;p&gt;Il faut donc ajouter ce paramètre dans le web.xml en y mettant le nom du
contexte applicatif ${app.ctx} de façon à ce que le paramètre
&lt;em&gt;webAppRootKey&lt;/em&gt; soit unique :&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;     &amp;lt;context-param&amp;gt;&lt;br /&gt;             &amp;lt;param-name&amp;gt;webAppRootKey&amp;lt;/param-name&amp;gt;&lt;br /&gt;                &amp;lt;param-value&amp;gt;${app.ctx}&amp;lt;/param-value&amp;gt;&lt;br /&gt; &amp;lt;/context-param&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;D'autre part, il ne faut pas non plus oublier de configurer le mode de
gestion des properties dans Spring et notamment celles des &lt;em&gt;system
properties&lt;/em&gt;. En effet, il faut indiquer à Spring si les properties du
système doivent écraser les valeurs pouvant être définies dans le contexte
Spring. Ceci ce fait grâce au &lt;a hreflang=&quot;en&quot; href=&quot;http://static.springsource.org/spring/docs/2.0.2/api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html&quot;&gt;
PropertyPlaceholderConfigurer&lt;/a&gt; avec la propriété systemPropertiesModeName
qui peut prendre plusieurs valeurs :&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;     &amp;lt;bean id=&amp;quot;propertyConfigurer&amp;quot;&lt;br /&gt;          class=&amp;quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&amp;quot;&amp;gt;&lt;br /&gt;                &amp;lt;property name=&amp;quot;locations&amp;quot;&amp;gt;&lt;br /&gt;                 &amp;lt;list&amp;gt;&lt;br /&gt;                              &amp;lt;value&amp;gt;classpath:/jdbc.properties&amp;lt;/value&amp;gt;&lt;br /&gt;                             &amp;lt;value&amp;gt;classpath:/hib3.properties&amp;lt;/value&amp;gt;&lt;br /&gt;                             &amp;lt;value&amp;gt;classpath:/myapp.properties&amp;lt;/value&amp;gt;&lt;br /&gt;                    &amp;lt;/list&amp;gt;&lt;br /&gt;             &amp;lt;/property&amp;gt;&lt;br /&gt;         &amp;lt;property name=&amp;quot;systemPropertiesModeName&amp;quot; value=&amp;quot;SYSTEM_PROPERTIES_MODE_OVERRIDE&amp;quot;/&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;En utilisant la valeur SYSTEM_PROPERTIES_MODE_OVERRIDE , Spring vérifiera
d'abord les &lt;em&gt;system properties&lt;/em&gt; en premier avant tout autre property
spécifiée par ailleurs.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Sources&lt;/ins&gt; :&lt;/p&gt;
&lt;p&gt;
http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/web/util/Log4jWebConfigurer.html&lt;/p&gt;
&lt;p&gt;
http://tai-dev.blog.co.uk/2008/08/07/glassfish-spring-multiple-applications-p-4555617/&lt;/p&gt;
&lt;p&gt;
http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html&lt;/p&gt;
&lt;p&gt;http://maven.apache.org/plugins/maven-war-plugin/faq.html#filtering&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2012/01/04/Log4j-avec-Spring-et-applications-multiples-dans-Tomcat#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2012/01/04/Log4j-avec-Spring-et-applications-multiples-dans-Tomcat#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/658522</wfw:commentRss>
      </item>
    
  <item>
    <title>commande find : trouver les derniers fichiers modifiés à partir d'une certaine date</title>
    <link>http://blog.guillaume-viel.com/post/2011/11/18/commande-find-%3A-trouver-les-derniers-fichiers-modifi%C3%A9s-%C3%A0-partir-d-une-certaine-date</link>
    <guid isPermaLink="false">urn:md5:9f4c3fdc2eb59ba941ea0ede4134d87e</guid>
    <pubDate>Fri, 18 Nov 2011 23:33:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>linux</category>
            
    <description>    &lt;p&gt;La commande find est très puissante mais il faut parfois creuser un peu pour
trouver la bonne syntaxe...&lt;/p&gt;
&lt;p&gt;Pour trouver tous les fichiers réguliers modifiés dans les dernières 24
heures dans un répertoire et ses sous-répertoire voici la commande :&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;find /mydir -type f -mtime -1 -print&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Pour trouver tous les fichiers réguliers modifiés à partir du début de la
journée dans un répertoire et ses sous-répertoire il faut ruser un peu...&lt;/p&gt;
&lt;p&gt;On créée d'abord un fichier factice à l'aide de la commande touch en forçant
la date de ce dernier :&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
$ touch -t `date +%m%d0000` /tmp/$$&lt;br /&gt;$ ls -l /tmp/&lt;br /&gt;-rw-r--r-- 1 moi moi 0 2011-11-18 00:00 5992&lt;br /&gt;$ find /mydir -type f -newer /tmp/5992&lt;br /&gt;$ rm /tmp/5992&lt;br /&gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;En effet dans la documentation de la commande touch on lit ceci sur l'option
-t :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;q&gt; -t STAMP        use
[[CC]YY]MMDDhhmm[.ss] instead of current time&lt;/q&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Il est donc ensuite très facile d'étendre la commande précédente pour lui
faire rechercher des fichiers après n'importe quelle date.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2011/11/18/commande-find-%3A-trouver-les-derniers-fichiers-modifi%C3%A9s-%C3%A0-partir-d-une-certaine-date#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2011/11/18/commande-find-%3A-trouver-les-derniers-fichiers-modifi%C3%A9s-%C3%A0-partir-d-une-certaine-date#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/650192</wfw:commentRss>
      </item>
    
  <item>
    <title>OFBiz : affichage d'une chaine HTML avec Freemarker</title>
    <link>http://blog.guillaume-viel.com/post/2011/09/27/OFBiz-%3A-affichage-d-une-chaine-HTML-avec-Freemarker</link>
    <guid isPermaLink="false">urn:md5:382cfee2185fbfc7a56d2a047dadda4c</guid>
    <pubDate>Tue, 27 Sep 2011 09:50:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>OFBiz</category>
        <category>freemarker</category><category>HTML</category><category>OFBiz</category>    
    <description>    &lt;p&gt;Lorsqu'on doit inclure du code HTML généré dans une page freemarker (sous la
forme d'une chaîne), il faut utiliser cette syntaxe pour que les tags HTML ne
soient pas &amp;quot;échappés&amp;quot; :&lt;/p&gt;
&lt;p&gt;${StringUtil.wrapString( htmlString ? if_exists ) }&lt;/p&gt;
&lt;p&gt;htmlString étant une chaine qui aura par exemple été mis dans le contexte
via un script grovvy ou un service.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2011/09/27/OFBiz-%3A-affichage-d-une-chaine-HTML-avec-Freemarker#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2011/09/27/OFBiz-%3A-affichage-d-une-chaine-HTML-avec-Freemarker#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/639052</wfw:commentRss>
      </item>
    
  <item>
    <title>Audit des requêtes SQL Hibernate</title>
    <link>http://blog.guillaume-viel.com/post/2011/08/23/Audit-requetes-SQL-Hibernate</link>
    <guid isPermaLink="false">urn:md5:4d274c30a1947d5d3e55d03e875d10df</guid>
    <pubDate>Tue, 23 Aug 2011 15:03:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>hibernate</category><category>java</category><category>SQL</category>    
    <description>    &lt;p&gt;Obtenir les traces des prepared statements d'Hibernate est assez simple et
tout le monde connaît cette configuration. Il suffit d'indiquer&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;hibernate.show_sql=true&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;dans le fichier de configuration XML Hibernate pour obtenir la requête qui
sera utilisé avec le SGBD. La requête sera affichée sous la forme d'un
preparedStatement avec des &amp;quot;?&amp;quot; à la place des valeurs.&lt;/p&gt;
&lt;p&gt;Une question alors fréquemment posée est : comment obtenir aussi les valeurs
passée avec la requête?!&lt;/p&gt;
&lt;p&gt;L'information est quelque part connue en interne dans Hibernate : le tout
est de la mettre en valeur en modifiant le paramétrage du logger. Par exemple
avec log4j il suffit de mettre en level DEBUG les packages suivants et de les
router vers un appender spécifique avec une additivité à false :&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;log4j.logger.org.hibernate.SQL=DEBUG,SQL_APPENDER&lt;br /&gt;log4j.additivity.org.hibernate.SQL=false&lt;br /&gt;org.hibernate.type=DEBUG,SQL_APPENDER&lt;br /&gt;log4j.additivity.org.hibernate.type=false&lt;/code&gt;
&lt;/pre&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2011/08/23/Audit-requetes-SQL-Hibernate#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2011/08/23/Audit-requetes-SQL-Hibernate#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/632163</wfw:commentRss>
      </item>
    
  <item>
    <title>bzip2 gzip tar avec stdin et stdout</title>
    <link>http://blog.guillaume-viel.com/post/2011/05/03/bzip2-gzip-tar-stdin-stdout</link>
    <guid isPermaLink="false">urn:md5:94cc62621175a90dfd22b1d19755f0bc</guid>
    <pubDate>Tue, 03 May 2011 15:39:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>linux</category>
            
    <description>    &lt;p&gt;Dans les scripts shell, il est toujours utile de savoir manipuler
correctement les commandes courantes de compression comme bzip2, gzip et tar,
et notamment leurs interactions possibles avec l'entrée standard (stdin) et la
sortie standard (stdout). L'avantage d'utiliser cette méthode est qu'elle est
compatible avec tous les systèmes *NIX !&lt;/p&gt;
&lt;h2&gt;Créer des archives&lt;/h2&gt;
&lt;p&gt;On utilise l'option c(reate) de tar dont le résultat est envoyé dans un pipe
vers gzip ou bzip2. La redirection &amp;gt; permet d'envoyer le résultat final dans
un fichier :&lt;/p&gt;
&lt;pre&gt;
   tar cv file1 [file2] ... | gzip &amp;gt; archname.tar.gz&lt;br /&gt;   tar cv file1 [file2] ... | bzip2 &amp;gt; archname.tar.bz2
&lt;/pre&gt;
&lt;h2&gt;Décompacter des archives&lt;/h2&gt;
&lt;pre&gt;
   gzip -cd archname.tar.gz | tar xv&lt;br /&gt;   bzip2 -cd archname.tar.bz2 | tar xv
&lt;/pre&gt;
&lt;h2&gt;Lire le contenu d'une acrhive&lt;/h2&gt;
&lt;pre&gt;
   gzip -cd archname.tar.gz | tar tv&lt;br /&gt;   bzip2 -cd archname.tar.bz2 | tar tv
&lt;/pre&gt;
&lt;h3&gt;NOTA BENE&lt;/h3&gt;
&lt;p&gt;Le programme &lt;q&gt;tar&lt;/q&gt; peut parfois pointer par défaut sur un device
prédéfini (comme un magnéto à bande) si l'option &lt;q&gt;f&lt;/q&gt; n'est pas précisée.
Sur certains systèmes il faut donc préciser &lt;q&gt;f -&lt;/q&gt; pour forcer &lt;q&gt;tar&lt;/q&gt; à
orienter vers l'entrée / sortie standard. Exemple :&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;tar cvf - file1 [file2] ... | gzip &amp;gt; archname.tar.gz&lt;/code&gt;
&lt;/pre&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2011/05/03/bzip2-gzip-tar-stdin-stdout#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2011/05/03/bzip2-gzip-tar-stdin-stdout#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/605373</wfw:commentRss>
      </item>
    
  <item>
    <title>Maven récupération du code source et de la javadoc</title>
    <link>http://blog.guillaume-viel.com/post/2011/03/02/Maven-code-source-et-javadoc</link>
    <guid isPermaLink="false">urn:md5:f4fb941b2607480ec815d5193cbc0ba7</guid>
    <pubDate>Wed, 02 Mar 2011 11:15:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>java</category><category>jee</category><category>maven</category>    
    <description>    &lt;p&gt;Pour récupérer les codes sources et la javadoc, il suffit d'ajouter au
lancement de maven&lt;/p&gt;
&lt;pre&gt;
-DdownloadSources=true -DdownloadJavadocs=true
&lt;/pre&gt;
&lt;p&gt;ou bien ceci dans le pom.xml&lt;/p&gt;
&lt;pre&gt;
&amp;lt;properties&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;downloadSources&amp;gt;true&amp;lt;/downloadSources&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;downloadJavadocs&amp;gt;true&amp;lt;/downloadJavadocs&amp;gt;&lt;br /&gt;&lt;br /&gt;     ....&lt;br /&gt;&lt;br /&gt;&amp;lt;/properties&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Il est utile d'avoir les sources lors des phases de debugging pour
comprendre parfois le comportement d'un framework.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2011/03/02/Maven-code-source-et-javadoc#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2011/03/02/Maven-code-source-et-javadoc#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/591369</wfw:commentRss>
      </item>
    
  <item>
    <title>Message Bundle avec Spring et problèmes d'encodage des fichiers de properties</title>
    <link>http://blog.guillaume-viel.com/post/2011/02/22/Message-Bundle-avec-Spring-et-probl%C3%A8me-d-encodage-des-fichiers-de-properties</link>
    <guid isPermaLink="false">urn:md5:8bb234a7ac649dfa821cc0a288efcaee</guid>
    <pubDate>Tue, 22 Feb 2011 18:23:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>encoding</category><category>i18n</category><category>java</category><category>jee</category><category>spring</category><category>springframework</category><category>UTF-8</category>    
    <description>    &lt;p&gt;Sur une application destinée à l'international, j'ai tout naturellement
souhaité introduire l'internationalisation (i18n) des messages destinés aux
utilisateurs, aux logs, aux erreurs etc.&lt;/p&gt;
&lt;p&gt;Je me suis penché sur ce que propose Spring et j'ai commencé avec cette
configuration très sommaire :&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;bean id=&amp;quot;messageSource&amp;quot; class=&amp;quot;org.springframework.context.support.ResourceBundleMessageSource&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;basename&amp;quot; value=&amp;quot;message&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Le premier problème c'est l'apparition de &lt;q&gt;???&lt;/q&gt; à la place de certains
caractères UTF-8 : gênant non?! Ceci est en fait dû au
&lt;code&gt;ResourceBundleMessageSource&lt;/code&gt; de Spring qui utilise les classes
standards &lt;code&gt;java.util.ResourceBundle&lt;/code&gt; et
&lt;code&gt;java.util.Properties&lt;/code&gt;, or ces dernières ne supportent visiblement
que l'encodage ISO-8859-1 !!!&lt;/p&gt;
&lt;p&gt;La solution est d'utiliser le
&lt;code&gt;ReloadableResourceBundleMessageSource&lt;/code&gt; de Spring, plus complet. Il
suffit de lui indiquer le &lt;code&gt;defaultEncoding&lt;/code&gt; choisi.&lt;/p&gt;
&lt;p&gt;L'autre problème est la non reconnaissance des fichiers de properties (mis
dans le classpath) que j'ai nommés &lt;code&gt;message_en.properties&lt;/code&gt; ,
&lt;code&gt;message_fr.properties&lt;/code&gt;, etc. Apparemment il faut ajouter le
paramètre &lt;code&gt;fallbackToSystemLocale=false&lt;/code&gt; sur le
&lt;code&gt;ReloadableResourceBundleMessageSource&lt;/code&gt; de Spring pour éviter que
soient recherchés les fichiers du type &lt;code&gt;message_fr_FR&lt;/code&gt; ou
&lt;code&gt;message_en_FR&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;bean id=&amp;quot;messageSource&amp;quot; class=&amp;quot;org.springframework.context.support.ReloadableResourceBundleMessageSource&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;basename&amp;quot; value=&amp;quot;classpath:message&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;fallbackToSystemLocale&amp;quot; value=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;defaultEncoding&amp;quot; value=&amp;quot;UTF-8&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;ins&gt;Sources&lt;/ins&gt; :&lt;/p&gt;
&lt;p&gt;
http://www.cakesolutions.net/teamblogs/2009/04/02/utf-8-encoding-and-message-sources/&lt;/p&gt;
&lt;p&gt;http://forum.springsource.org/showthread.php?t=18199&amp;amp;page=2&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2011/02/22/Message-Bundle-avec-Spring-et-probl%C3%A8me-d-encodage-des-fichiers-de-properties#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2011/02/22/Message-Bundle-avec-Spring-et-probl%C3%A8me-d-encodage-des-fichiers-de-properties#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/589455</wfw:commentRss>
      </item>
    
  <item>
    <title>Données utilisateur visualVM</title>
    <link>http://blog.guillaume-viel.com/post/2011/02/17/Donn%C3%A9es-utilisateur-visualVM</link>
    <guid isPermaLink="false">urn:md5:fffadaee8796b26ede6d165859248328</guid>
    <pubDate>Thu, 17 Feb 2011 16:11:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>visualvm</category><category>windows</category>    
    <description>    &lt;p&gt;Lors d'un changement de JVM, il se peut que les données de configuration
VisualVM ne soient pas récupérées (notamment passage de Java 6 à Java 7). Sur
un poste windows, il est très simple de récupérer ses configurations d'hôtes à
monitorer. Elles se trouvent dans :&lt;/p&gt;
&lt;p&gt;C:\Documents and Settings\utilisateur\Application Data\.visualvm\6u30&lt;/p&gt;
&lt;p&gt;Les hôtes déclarés sont dans le répertoire repository. Il suffit de recopier
les données vers le répertoire C:\Documents and
Settings\utilisateur\Application Data\.visualvm\7 si vous venez d'installer la
dernière JVM 7.&lt;/p&gt;
&lt;p&gt;D'une version 6 à une autre, le premier répertoire créé semble être conservé
pour les versions suivantes.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2011/02/17/Donn%C3%A9es-utilisateur-visualVM#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2011/02/17/Donn%C3%A9es-utilisateur-visualVM#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/588370</wfw:commentRss>
      </item>
    
  <item>
    <title>Problème avec le Maven archetype plugin</title>
    <link>http://blog.guillaume-viel.com/post/2011/02/16/probleme-maven-archetype-plugin</link>
    <guid isPermaLink="false">urn:md5:2e0ed1b314c9bcb7cc565c770fe51a68</guid>
    <pubDate>Wed, 16 Feb 2011 16:12:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>archetype</category><category>java</category><category>jee</category><category>maven</category>    
    <description>    &lt;p&gt;Lors d'un test de l'archetype plugin de maven, j'obtenais un &lt;q&gt;build
failure&lt;/q&gt; avec un &lt;q&gt;Required goal not found&lt;/q&gt; alors que tout fonctionnait
auparavant...&lt;/p&gt;
&lt;p&gt;Voici le contenu du
.m2\repository\org\apache\maven\plugins\maven-archetype-plugin\maven-metadata-central.xml&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&amp;lt;metadata&amp;gt;&lt;br /&gt;  &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;  &amp;lt;artifactId&amp;gt;maven-archetype-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;  &amp;lt;versioning&amp;gt;&lt;br /&gt;    &amp;lt;latest&amp;gt;1.0-alpha-4&amp;lt;/latest&amp;gt;&lt;br /&gt;    &amp;lt;release&amp;gt;1.0-alpha-4&amp;lt;/release&amp;gt;&lt;br /&gt;    &amp;lt;versions&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;1.0-alpha-3&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;1.0-alpha-4&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;/versions&amp;gt;&lt;br /&gt;    &amp;lt;lastUpdated&amp;gt;20060507072802&amp;lt;/lastUpdated&amp;gt;&lt;br /&gt;  &amp;lt;/versioning&amp;gt;&lt;br /&gt;&amp;lt;/metadata&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;En fait, il faut le corriger comme ceci pour que tout fonctionne
correctement (en téléchargeant directement sur un repository en ligne le
fichier maven-metadata.xml)&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;metadata&amp;gt;&lt;br /&gt;  &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;  &amp;lt;artifactId&amp;gt;maven-archetype-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;  &amp;lt;versioning&amp;gt;&lt;br /&gt;    &amp;lt;latest&amp;gt;2.0&amp;lt;/latest&amp;gt;&lt;br /&gt;    &amp;lt;release&amp;gt;2.0&amp;lt;/release&amp;gt;&lt;br /&gt;    &amp;lt;versions&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;1.0-alpha-3&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;1.0-alpha-4&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;1.0-alpha-7&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;2.0-alpha-1&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;2.0-alpha-2&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;2.0-alpha-3&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;2.0-alpha-4&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;2.0-alpha-5&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;2.0&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;/versions&amp;gt;&lt;br /&gt;    &amp;lt;lastUpdated&amp;gt;20101028011818&amp;lt;/lastUpdated&amp;gt;&lt;br /&gt;  &amp;lt;/versioning&amp;gt;&lt;br /&gt;&amp;lt;/metadata&amp;gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Et voilà!&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2011/02/16/probleme-maven-archetype-plugin#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2011/02/16/probleme-maven-archetype-plugin#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/588102</wfw:commentRss>
      </item>
    
  <item>
    <title>Archetype maven et quickstart pour spring batch</title>
    <link>http://blog.guillaume-viel.com/post/2011/02/16/Archetype-maven-pour-spring-batch</link>
    <guid isPermaLink="false">urn:md5:4a71602046db0ed458fa234340ec6045</guid>
    <pubDate>Wed, 16 Feb 2011 11:57:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>archetype</category><category>java</category><category>jee</category><category>maven</category><category>spring</category><category>springframework</category>    
    <description>    Les archetypes maven ne semblent pas très fonctionnels... Pour créer un
template de projet à partir d'un archetype existant voici la commande à
exécuter :&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
&lt;code&gt;$ mvn archetype:generate&lt;/code&gt;
&lt;/pre&gt;
Maven sort alors une liste d'une vingtaines d'archetypes possibles. On peut
alors choisir l'archetype à utiliser et le customiser. Maven génère alors un
répertoire projet prêt à l'emploi. En les testant on s'aperçoit que sur la
majorité des archetypes disponibles, seuls quelques uns fonctionnent
vraiment...&lt;br /&gt;
La liste des archetypes possibles se trouve ici :
http://docs.codehaus.org/display/MAVENUSER/Archetypes+List&lt;br /&gt;
C'est un peu décevant...&lt;br /&gt;
&lt;br /&gt;
De même, j'ai cherché un archetype pour Spring-batch. Visiblement rien n'existe
et l'infrastructure maven ne semble pas être utilisée pour ça. Le mieux que
j'ai trouvé c'est d'aller directement récupérer les exemples de code qui
existent sur le repository SVN de spring !&lt;br /&gt;
&lt;br /&gt;
$ svn export 
https://src.springframework.org/svn/spring-batch/trunk/archetypes/simple-cli&lt;br /&gt;

$ cd simple-cli&lt;br /&gt;
$ mvn test&lt;br /&gt;
&lt;br /&gt;
Et voilà! On y trouvera aussi d'autres exemples de projet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2011/02/16/Archetype-maven-pour-spring-batch#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2011/02/16/Archetype-maven-pour-spring-batch#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/588041</wfw:commentRss>
      </item>
    
  <item>
    <title>Uptime d'un serveur</title>
    <link>http://blog.guillaume-viel.com/post/2010/12/15/Uptime-sous-windows-XP</link>
    <guid isPermaLink="false">urn:md5:ca9fa06868d04f7c0e7136a85fe2135a</guid>
    <pubDate>Wed, 15 Dec 2010 17:28:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>linux</category>
            
    <description>    &lt;p&gt;Pour connaitre le temps d'activité d'un serveur depuis son dernier
démarrage, sous Linux, c'est la commande uptime :&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;# uptime&lt;br /&gt; 10:38:26 up 153 days, 19:49,  1 user,  load average: 1.18, 0.76, 0.46&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Par contre sous windows, c'est un peu plus compliqué, et les calculs sont à
faire par vos soins (où alors je n'ai pas trouvé la commande!)... Je n'ai
trouvé que ça :&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;gt;net statistics serveur&lt;br /&gt;Statistiques de serveur de \\MYSERVER&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Statistiques depuis 10/13/2010 10:07 AM&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Sessions acceptées                             1&lt;br /&gt;Déconnexions automatiques                      0&lt;br /&gt;Déconnexions sur erreur                        6&lt;br /&gt;&lt;br /&gt;Kilo-octets envoyés                            8&lt;br /&gt;Kilo-octets reçus                              11&lt;br /&gt;&lt;br /&gt;Temps de réponse moyen (ms)                    0&lt;br /&gt;&lt;br /&gt;Erreurs système                                0&lt;br /&gt;Violations d'autorisation                      12&lt;br /&gt;Violations de mot de passe                     0&lt;br /&gt;&lt;br /&gt;Fichiers utilisés                              0&lt;br /&gt;Périphériques comm. utilisés                   0&lt;br /&gt;Travaux d'impression mis en file d'attente     0&lt;br /&gt;&lt;br /&gt;Saturation des zones tampon&lt;br /&gt;&lt;br /&gt;  de grande taille                             0&lt;br /&gt;  de demande                                   0&lt;br /&gt;&lt;br /&gt;La commande s'est terminée correctement.&lt;/code&gt;
&lt;/pre&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/12/15/Uptime-sous-windows-XP#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/12/15/Uptime-sous-windows-XP#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/570670</wfw:commentRss>
      </item>
    
  <item>
    <title>SOAPUI connexion JDBC</title>
    <link>http://blog.guillaume-viel.com/post/2010/11/30/SOAPUI-connexion-JDBC</link>
    <guid isPermaLink="false">urn:md5:fa55ab5b6b29174c6b6ef7c1dc725bcd</guid>
    <pubDate>Tue, 30 Nov 2010 11:28:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>groovy</category><category>jdbc</category><category>SOAPUI</category><category>tests</category>    
    <description>    &lt;p&gt;Pour réaliser des tests plus industriels, il est nécessaire que le script de
test puisse accéder à une base de données. Sur la version non payante de
SOAPUI&lt;/p&gt;
&lt;pre&gt;
import com.eviware.soapui.*;&lt;br /&gt;import groovy.sql.Sql;&lt;br /&gt;&lt;br /&gt;def dbUrl = &amp;quot;jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = host1.mydomain.com)(PORT = 1523))(ADDRESS = (PROTOCOL = TCP)(HOST = host2.mydomain.com&lt;br /&gt;)(PORT = 1521))(FAILOVER = false))(CONNECT_DATA =(SERVICE_NAME = MYDB.MYDOMAIN.COM)))&amp;quot;;&lt;br /&gt;def dbUser = &amp;quot;user&amp;quot;;&lt;br /&gt;def dbPwd = &amp;quot;mypassword&amp;quot;;&lt;br /&gt;def sql;&lt;br /&gt;try {&lt;br /&gt;    sql = Sql.newInstance(dbUrl, dbUser, dbPwd, &amp;quot;oracle.jdbc.OracleDriver&amp;quot;);&lt;br /&gt;    //def res = sql.firstRow(&amp;quot;SELECT * FROM MA_TABLE&amp;quot;);&lt;br /&gt;    //log.info res.ID + &amp;quot; &amp;quot; + res.CHAMP1;&lt;br /&gt;    //res.close();&lt;br /&gt;    sql.eachRow(&amp;quot;SELECT * FROM MA_TABLE&amp;quot;) {&lt;br /&gt;            log.info &amp;quot;${it.ID} / ${it.CHAMP1}&amp;quot;&lt;br /&gt;    }&lt;br /&gt;    sql.close();&lt;br /&gt;    log.info &amp;quot;Closed Database Connection.&amp;quot;;&lt;br /&gt;} catch (Exception e) {&lt;br /&gt;    log.error &amp;quot;Could not establish connection to the database.&amp;quot;;&lt;br /&gt;}
&lt;/pre&gt;
&lt;p&gt;Voilà une première étape de franchie. On peut aller plus loin en utilisant
ceci au niveau des scripts de &lt;q&gt;setup&lt;/q&gt; et &lt;q&gt;tear down&lt;/q&gt; d'un jeu de
test.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/11/30/SOAPUI-connexion-JDBC#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/11/30/SOAPUI-connexion-JDBC#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/566526</wfw:commentRss>
      </item>
    
  <item>
    <title>Hibernate interceptor : nom de schéma dynamique</title>
    <link>http://blog.guillaume-viel.com/post/2010/11/07/Hibernate-interceptor-nom-de-sch%C3%A9ma-dynamique</link>
    <guid isPermaLink="false">urn:md5:02fa30833689e9f16a19b2a0979188da</guid>
    <pubDate>Sun, 07 Nov 2010 23:15:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>hibernate</category><category>java</category><category>jee</category>    
    <description>&lt;p&gt;Bien d'Hibernate soit capable d'aller chercher des données dans des tables
situées dans différents schémas, il n'est pas possible directement de changer
le schéma à l'exécution. En effet, les annotations sont lues à  la
compilation et le code d'une @Entity est alors figé sur un schéma et une
table.&lt;/p&gt;
&lt;pre&gt;
@Entity&lt;br /&gt;@Table(name=&amp;quot;MON_OBJET&amp;quot;,schema=&amp;quot;MON_SCHEMA&amp;quot;)&lt;br /&gt;public class MonObjet implements Serializable {&lt;br /&gt;...&lt;br /&gt;   private Etat etat;&lt;br /&gt;...&lt;br /&gt;   @OneToOne(...)&lt;br /&gt;   public Etat getEtat() { ... }&lt;br /&gt;   public void setEtat(Etat etat) { ... }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Entity&lt;br /&gt;@Table(name=&amp;quot;ETAT&amp;quot;,schema=&amp;quot;MON_SCHEMA&amp;quot;)&lt;br /&gt;public class Etat {&lt;br /&gt;...&lt;br /&gt;}
&lt;/pre&gt;
&lt;p&gt;Ceci devient gênant lorsque par exemple, une des entités peut se trouver
dans différents schémas qui correspondent par exemple à des environnements
différents. Par exemple, si MonObject est attaché en relation un à un à un
objet Etat qui peut se trouver dans MON_SCHEMA, SCHEMA_PREPROD ou SCHEMA_PROD,
on devra alors packager une application par schéma!&lt;/p&gt;
&lt;p&gt;Une solution possible serait de créer un profile maven pour chaque
environnement, puis d'utiliser la phase de génération des sources pour modifier
les annotations dans le code java... Ce qui semble plutôt lourd à mettre en
place! Et au final, il faut toujours une application par schéma utilisé! Il
existe cependant une solution avec les &lt;em&gt;interceptor&lt;/em&gt; d'Hibernate pour ne
déployer qu'une seule application...&lt;/p&gt;    Les &lt;em&gt;interceptors&lt;/em&gt; d'Hibernate permettent d'intervenir au niveau des
opérations réalisées au niveau des entités. La capture ci-dessous permet de
voir la liste des méthodes qu'il est possible de surcharger :&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://blog.guillaume-viel.com/public/hibernate/hibernate_EmptyInterceptor.png&quot;&gt;&lt;img title=&quot;Hibernate EmptyInterceptor, nov. 2010&quot; alt=&quot;&quot; src=&quot;http://blog.guillaume-viel.com/public/hibernate/hibernate_EmptyInterceptor.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans le cas qui nous intéresse, nous allons surcharger la méthode
onPrepareStatement(String) sur un héritage de la classe EmptyInterceptor
d'Hibernate car c'est à cet endroit qu'il est possible de modifier à la volée
les requêtes réalisées par Hibernate sur l'entité.&lt;br /&gt;
En supposant que le schéma de l'environnement est connu par l'intermédiaire
d'une propriété système Java &amp;quot;env&amp;quot; (ex: -Denv=SCHEMA_PROD), on peut alors à
l'exécution remplacer à la volée le nom du schéma par le schéma d'environnement
uniquement pour l'objet Etat, c'est à dire pour l'entité pointant sur la table
ETAT. Dans toute la requête SQL fabriquée par Hibernate, on aura alors remplacé
tous les MON_SCHEMA.ETAT par SCHEMA_PROD.ETAT.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
import org.hibernate.EmptyInterceptor;&lt;br /&gt;&lt;br /&gt;public class SchemaInterceptor extends EmptyInterceptor {&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public String onPrepareStatement(String sql) {&lt;br /&gt;        String pstmt = super.onPrepareStatement(sql);&lt;br /&gt;        String schema = System.getProperty(&amp;quot;env&amp;quot;);&lt;br /&gt;        if( pstmt.matches(&amp;quot;MON_SCHEMA.ETAT&amp;quot;)) {&lt;br /&gt;            pstmt = pstmt.replaceAll(&amp;quot;MON_SCHEMA.ETAT&amp;quot;, schema + &amp;quot;.ETAT&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;        return pstmt;&lt;br /&gt;    }&lt;br /&gt;}
&lt;/pre&gt;
Ensuite, il faut intégrer l'intercepteur dans la sessionFactory Hibernate
(contexte Spring) :&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
&amp;lt;bean id=&amp;quot;schemaInterceptor&amp;quot; class=&amp;quot;fr.openfarm.hibernate.interceptors.SchemaInterceptor&amp;quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id=&amp;quot;sessionFactory&amp;quot; class=&amp;quot;org.springframework.orm.hibernate3.LocalSessionFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;     &amp;lt;property name=&amp;quot;dataSource&amp;quot;&amp;gt;...&amp;lt;/property&amp;gt;&lt;br /&gt;     ...&lt;br /&gt;     &amp;lt;property name=&amp;quot;entityInterceptor&amp;quot;&amp;gt;&lt;br /&gt;         &amp;lt;ref bean=&amp;quot;schemaInterceptor&amp;quot;/&amp;gt;&lt;br /&gt;     &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
Attention : on ne peut déclarer qu'un seul intercepteur par session.&lt;br /&gt;
Les sources ci-dessous donnent d'autres exemples d'utilisation des
intercepteurs (audit des entités ou la sécurité) :&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://java.dzone.com/articles/using-a-hibernate-interceptor-&quot;&gt;Using a
Hibernate Interceptor To Set Audit Trail Properties&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://java.dzone.com/articles/hibernate-dynamic-table-routin&quot;&gt;Hibernate :
dynamic table routing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/11/07/Hibernate-interceptor-nom-de-sch%C3%A9ma-dynamique#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/11/07/Hibernate-interceptor-nom-de-sch%C3%A9ma-dynamique#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/560124</wfw:commentRss>
      </item>
    
  <item>
    <title>Tomcat : configuration proxy HTTPS</title>
    <link>http://blog.guillaume-viel.com/post/2010/10/13/Tomcat-configuration-proxy-HTTPS</link>
    <guid isPermaLink="false">urn:md5:269a07fac0263c84a5fa07a0c4e2e41e</guid>
    <pubDate>Wed, 13 Oct 2010 12:24:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>java</category><category>jee</category><category>proxy</category><category>tomcat</category>    
    <description>    &lt;p&gt;La configuration d'un proxy HTTPS pour Tomcat est plus cohérente que celle
de maven et plus directe; il suffit juste d'indiquer les propriétés système de
Java dans le fichier $CATALINA_HOME/conf/catalina.properties :&lt;/p&gt;
&lt;pre&gt;
http.proxyHost=proxy.mydomain.com&lt;br /&gt;http.proxyPort=8080&lt;br /&gt;http.nonProxyHost=localhost|10.*&lt;br /&gt;&lt;br /&gt;https.proxyHost=proxy.mydomain.com&lt;br /&gt;https.proxyPort=8080
&lt;/pre&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/10/13/Tomcat-configuration-proxy-HTTPS#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/10/13/Tomcat-configuration-proxy-HTTPS#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/554201</wfw:commentRss>
      </item>
    
  <item>
    <title>Maven : configuration proxy HTTPS</title>
    <link>http://blog.guillaume-viel.com/post/2010/10/13/maven-configuration-proxy-HTTPS</link>
    <guid isPermaLink="false">urn:md5:f94951f659bd79ee47a575d0dbd9871b</guid>
    <pubDate>Wed, 13 Oct 2010 12:08:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>java</category><category>jee</category><category>maven</category><category>proxy</category>    
    <description>    &lt;p&gt;La configuration d'un proxy sous maven est a priori simple : il suffit
d'ajouter la section suivante dans le fichier ~/.m2/settings.xml :&lt;/p&gt;
&lt;pre&gt;
&amp;lt;proxies&amp;gt;&lt;br /&gt;&amp;lt;proxy&amp;gt;&lt;br /&gt;&amp;lt;active&amp;gt;true&amp;lt;/active&amp;gt;&lt;br /&gt;&amp;lt;protocol&amp;gt;http&amp;lt;/protocol&amp;gt;&lt;br /&gt;&amp;lt;host&amp;gt;proxy.somewhere.com&amp;lt;/host&amp;gt;&lt;br /&gt;&amp;lt;port&amp;gt;8080&amp;lt;/port&amp;gt;&lt;br /&gt;&amp;lt;username&amp;gt;proxyuser&amp;lt;/username&amp;gt;&lt;br /&gt;&amp;lt;password&amp;gt;somepassword&amp;lt;/password&amp;gt;&lt;br /&gt;&amp;lt;nonProxyHosts&amp;gt;localhost|10.*&amp;lt;/nonProxyHosts&amp;gt;&lt;br /&gt;&amp;lt;/proxy&amp;gt;&lt;br /&gt;&amp;lt;/proxies&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Mais pour le protocole HTTPS la documentation n'indique rien! Si l'on essaye
de transposer et d'ajouter un proxy avec&lt;br /&gt;
&amp;lt;protocol&amp;gt;https&amp;lt;/protocol&amp;gt;&lt;br /&gt;
cela ne marche pas beaucoup plus...&lt;br /&gt;
La solution consiste à ajouter ceci à la variable d'environnement MAVEN_OPTS
:&lt;/p&gt;
&lt;pre&gt;
&lt;strong&gt;MAVEN_OPTS=$MAVEN_OPTS -Dhttps.proxyHost=proxy.somewhere.com -Dhttps.proxyPort=8080&lt;/strong&gt;
&lt;/pre&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/10/13/maven-configuration-proxy-HTTPS#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/10/13/maven-configuration-proxy-HTTPS#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/554197</wfw:commentRss>
      </item>
    
  <item>
    <title>Implémentation d'un Interceptor CXF pour logger le temps d'exécution</title>
    <link>http://blog.guillaume-viel.com/post/2010/10/04/Impl%C3%A9mentation-interceptor-CXF-pour-logger-temps-ex%C3%A9cution</link>
    <guid isPermaLink="false">urn:md5:45dadca47c0c59c6785040f46cd0f00a</guid>
    <pubDate>Mon, 04 Oct 2010 11:59:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>CXF</category><category>java</category><category>jee</category><category>logging</category><category>SOAP</category><category>webservices</category>    
    <description>&lt;p&gt;Les intercepteurs de CXF permettent, comme leur nom l'indique, d'intercepter
le flux en entrée ou en sortie d'un webservice et d'exécuter un traitement.
Tout comme les filtres de servlet, ils sont puissant pour réaliser des
opérations techniques sur les données.&lt;/p&gt;
&lt;p&gt;Si l'on veut tracer le temps d'exécution d'un webservice à toutes les étapes
et notamment juste avant l'entrée dans l'implémentation.&lt;/p&gt;    &lt;h2&gt;Implémentation d'intercepteurs CXF&lt;/h2&gt;
&lt;p&gt;L'implémentation d'un intercepteur est assez simple. Il suffit d'implémenter
l'interface Interceptor. Plusieurs implémentation abstraite existent pour
faciliter la tâche. Les deux plus fréquentes sont AbstractPhaseInterceptor et
AbstractSoapInterceptor qui permettent d'accéder au Message ou au
SoapMessage.&lt;/p&gt;
&lt;p&gt;Le premier intercepteur créé va permettre la prise de date du démarrage de
l'appel au web service et devra être placé en input. On démarre le
ExecTimeCalculator dans la méthode handleMessage.&lt;/p&gt;
&lt;pre&gt;
import org.apache.cxf.interceptor.Fault;&lt;br /&gt;import org.apache.cxf.message.Message;&lt;br /&gt;import org.apache.cxf.phase.AbstractPhaseInterceptor;&lt;br /&gt;import org.apache.cxf.phase.Phase;&lt;br /&gt;&lt;br /&gt;public class LogInTimeInterceptor extends AbstractPhaseInterceptor&amp;lt;Message&amp;gt; {&lt;br /&gt;&lt;br /&gt;    public LogInTimeInterceptor() {
        super(Phase.RECEIVE);&lt;br /&gt;    }&lt;br /&gt;    public void handleMessage(Message message) throws Fault {&lt;br /&gt;        ExecTimeCalculator.getInstance().start();&lt;br /&gt;    }&lt;br /&gt;}
&lt;/pre&gt;
&lt;p&gt;Le deuxième intercepteur va s'occuper de récupérer le nom du service et de
l'opération appelée, et les envoyer à l'ExecTimeCalculator pour arrêter la date
de fin d'exécution et afficher le service, l'opération et le temps total
d'exécution.&lt;/p&gt;
&lt;pre&gt;
import javax.xml.namespace.QName;&lt;br /&gt;&lt;br /&gt;import org.apache.cxf.interceptor.Fault;&lt;br /&gt;import org.apache.cxf.message.Message;&lt;br /&gt;import org.apache.cxf.phase.AbstractPhaseInterceptor;&lt;br /&gt;import org.apache.cxf.phase.Phase;&lt;br /&gt;&lt;br /&gt;public class LogOutTimeInterceptor extends AbstractPhaseInterceptor&amp;lt;Message&amp;gt; {&lt;br /&gt;    &lt;br /&gt;    //private static final Logger logger = Logger.getLogger(LogOutTimeInterceptor.class);&lt;br /&gt;    &lt;br /&gt;    public LogOutTimeInterceptor() {&lt;br /&gt;        super(Phase.SEND);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public void handleMessage(Message message) throws Fault {&lt;br /&gt;        QName service = (QName) message.get(Message.WSDL_SERVICE);&lt;br /&gt;        QName op = (QName) message.get(Message.WSDL_OPERATION);&lt;br /&gt;        ExecTimeCalculator.getExecTime(service.getLocalPart(), op.getLocalPart());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}
&lt;/pre&gt;
&lt;h2&gt;Configuration du webservice avec les intercepteurs&lt;/h2&gt;
&lt;p&gt;La configuration dans le contexte Spring CXF du webservice se fait très
simplement avec en plus des sections &amp;lt;jaxws:inInterceptors&amp;gt; et
&amp;lt;jaxws:outInterceptors&amp;gt; dans laquelle on va rajouter nos intercepteurs
:&lt;/p&gt;
&lt;pre&gt;
    &amp;lt;bean id=&amp;quot;serviceImpl&amp;quot; class=&amp;quot;fr.openfarm.wss.ServiceTestImpl&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;logInTime&amp;quot; class=&amp;quot;fr.openfarm.wss.LogInTimeInterceptor&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;logOutTime&amp;quot; class=&amp;quot;fr.openfarm.wss.LogOutTimeInterceptor&amp;quot;/&amp;gt;
&lt;br /&gt;    &amp;lt;jaxws:endpoint id=&amp;quot;service&amp;quot; implementor=&amp;quot;#serviceImpl&amp;quot;&lt;br /&gt;        implementorClass=&amp;quot;fr.openfarm.wss.ServiceTestImpl&amp;quot;&lt;br /&gt;        address=&amp;quot;/ServiceTest&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;jaxws:inInterceptors&amp;gt;&lt;br /&gt;            &amp;lt;ref bean=&amp;quot;logInTime&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;/jaxws:inInterceptors&amp;gt;&lt;br /&gt;        &amp;lt;jaxws:outInterceptors&amp;gt;&lt;br /&gt;            &amp;lt;ref bean=&amp;quot;logOutTime&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;/jaxws:outInterceptors&amp;gt;&lt;br /&gt;    &amp;lt;/jaxws:endpoint&amp;gt;
&lt;/pre&gt;
&lt;h2&gt;Calcul du temps d'exécution&lt;/h2&gt;
&lt;p&gt;Ce temps d'exécution nous avons pouvoir le calculer grâce à une variable en
ThreadLocal mise dans un singleton... On va stocker un objet Calendar sous la
forme d'un ThreadLocal. Ceci signifie que lorsqu'ExecTimeCalculator est appelé
par un thread, l'objet Calendar sera affecté à ce thread et à lui seul. Chaque
thread garde donc une copie propre de l'objet Calendar par l'intermédiaire du
ThreadLocal. Etant donné que l'input et l'output d'une requête de web service
se fait dans le même thread, on peut alors calculer le temps d'exécution si
l'on stocke la date de démarrage.&lt;/p&gt;
&lt;pre&gt;
import java.text.SimpleDateFormat;&lt;br /&gt;import java.util.Calendar;&lt;br /&gt;import org.apache.log4j.Logger;&lt;br /&gt;&lt;br /&gt;public class ExecTimeCalculator {&lt;br /&gt;    &lt;br /&gt;    private static final Logger logger = Logger.getLogger(ExecTimeCalculator.class);&lt;br /&gt;    private static final SimpleDateFormat sdf = new SimpleDateFormat(&amp;quot;yyyy-MM-dd hh:mm:ss&amp;quot;);&lt;br /&gt;    &lt;br /&gt;    private static ExecTimeCalculator instance;&lt;br /&gt;    private ThreadLocal&amp;lt;Calendar&amp;gt; date;&lt;br /&gt;    &lt;br /&gt;    private ExecTimeCalculator() {&lt;br /&gt;        this.date = new ThreadLocal&amp;lt;Calendar&amp;gt;();&lt;br /&gt;        this.date.set(null);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public static ExecTimeCalculator getInstance() {&lt;br /&gt;        if( instance == null ) instance = new ExecTimeCalculator();&lt;br /&gt;        return instance;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public void start() {&lt;br /&gt;        Calendar now = Calendar.getInstance();&lt;br /&gt;        getInstance().date.set(now);&lt;br /&gt;        logger.debug(&amp;quot;Date début exec : &amp;quot; + sdf.format(now.getTime()) &lt;br /&gt;                + &amp;quot; [ threadId = &amp;quot; + Thread.currentThread().getId() + &amp;quot;]&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public static void getExecTime(String service, String operation) {&lt;br /&gt;        Calendar now = Calendar.getInstance();&lt;br /&gt;        logger.debug(&amp;quot;Date fin exec : &amp;quot; +sdf.format(now.getTime())&lt;br /&gt;                 + &amp;quot; [ threadId = &amp;quot; + Thread.currentThread().getId() + &amp;quot;]&amp;quot;);&lt;br /&gt;        logger.info(service + &amp;quot;.&amp;quot; + operation + &amp;quot; : execution time = &amp;quot;&lt;br /&gt;                + (now.getTimeInMillis() - getInstance().getDate().get().getTimeInMillis())&lt;br /&gt;                + &amp;quot; ms&amp;quot;);&lt;br /&gt;        getInstance().getDate().set(null);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public ThreadLocal&amp;lt;Calendar&amp;gt; getDate() {&lt;br /&gt;        return date;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setDate(ThreadLocal&amp;lt;Calendar&amp;gt; date) {&lt;br /&gt;        this.date = date;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}
&lt;/pre&gt;
&lt;p&gt;A vous de jouer!&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Source&lt;/ins&gt; :&lt;/p&gt;
&lt;p&gt;http://www.jroller.com/gmazza/entry/jaxwshandlers_to_cxfinterceptors&lt;/p&gt;
&lt;p&gt;https://cwiki.apache.org/CXF20DOC/interceptors.html&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/10/04/Impl%C3%A9mentation-interceptor-CXF-pour-logger-temps-ex%C3%A9cution#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/10/04/Impl%C3%A9mentation-interceptor-CXF-pour-logger-temps-ex%C3%A9cution#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/551935</wfw:commentRss>
      </item>
    
  <item>
    <title>Spring AOP advice et pointcut sur Servlet</title>
    <link>http://blog.guillaume-viel.com/post/2010/10/03/Spring-AOP-advice-pointcut-Servlet</link>
    <guid isPermaLink="false">urn:md5:fe08a627ad7a9456a2501eb295069511</guid>
    <pubDate>Sat, 02 Oct 2010 23:37:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>AOP</category><category>java</category><category>jee</category><category>spring</category>    
    <description>&lt;p&gt;La puissance de Spring AOP se limite a priori à son contexte (cf ce post
http://forum.springsource.org/archive/index.php/t-11673.html )... Les servlets
sont hors contexte Spring car gérées par le serveur d'application JEE et
semblent exclues du champ de Spring AOP. Cependant, il est tentant de vouloir
quand même utiliser Spring AOP sur les servlets sans avoir à passer par
d'autres tisseurs d'aspects (comme AspectJ) qui complexifient la configuration
du serveur d'application et le déploiement de l'application. Il s'avère que
c'est possible par un moyen détourné. Il fallait juste y penser.&lt;/p&gt;    &lt;p&gt;Mon besoin initial consistait à calculer le temps d'exécution des servlets
CXF pour des webservices.&lt;/p&gt;
&lt;p&gt;L'astuce consiste à créer un filtre de servlet. Mais les filtres sont aussi
gérés par le conteneur me direz-vous?! Oui mais il est possible de raccrocher
ces filtres au contexte spring de 2 façons :&lt;/p&gt;
&lt;h2&gt;La première solution&lt;/h2&gt;
&lt;p&gt;consiste à raccrocher le filtre au contexte spring lors de l'initialisation
du filtre :&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
public class SpringAwareFilter implements Filter {&lt;br /&gt;@Autowire MyBean myBean;&lt;br /&gt;public void destroy(...) { ... }&lt;br /&gt;public void doFilter(...) {
       ....&lt;br /&gt;        myBean.methodeToIntercept(...);&lt;br /&gt;       ....&lt;br /&gt;}
public void init(FilterConfig filterConfig) throws ServletException {
        ServletContext servletContext = filterConfig.getServletContext();
        WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);      
        AutowireCapableBeanFactory autowireCapableBeanFactory = webApplicationContext.getAutowireCapableBeanFactory();
        autowireCapableBeanFactory.configureBean(this, &amp;quot;myBean&amp;quot;);&lt;br /&gt;}
&lt;/pre&gt;
&lt;p&gt;Une fois le filtre accroché au contexte Spring, il est possible d'ajouter le
pointcut  sur methodToIntercept du bean Spring myBean.&lt;br /&gt;
&lt;br /&gt;
&lt;ins&gt;Source&lt;/ins&gt; : http://forum.springsource.org/showthread.php?t=60983&lt;/p&gt;
&lt;h2&gt;La deuxième solution&lt;/h2&gt;
&lt;p&gt;est d'utiliser directement la classe Spring &lt;a hreflang=&quot;en&quot; href=&quot;http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/filter/DelegatingFilterProxy.html&quot;&gt;
&lt;strong&gt;DelegatingFilterProxy&lt;/strong&gt;&lt;/a&gt; qui fait sensiblement la même
chose.&lt;br /&gt;
&lt;br /&gt;
On crée d'abord un filtre en implémentant Filter de la façon suivante :&lt;/p&gt;
&lt;pre&gt;
package fr.openfarm.aop;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;&lt;br /&gt;import javax.servlet.Filter;&lt;br /&gt;import javax.servlet.FilterChain;&lt;br /&gt;import javax.servlet.FilterConfig;&lt;br /&gt;import javax.servlet.ServletException;&lt;br /&gt;import javax.servlet.ServletRequest;&lt;br /&gt;import javax.servlet.ServletResponse;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class ServletPointcutFilter implements Filter {&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void destroy() {&lt;br /&gt;        // cette partie &amp;quot;lifecycle&amp;quot; du filtre  est normalement prise en charge&lt;br /&gt;        // par la classe org.springframework.web.filter.DelegatingFilterProxy&lt;br /&gt;        // déclarée dans le web.xml&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void doFilter(ServletRequest request, ServletResponse response,&lt;br /&gt;            FilterChain chain) throws IOException, ServletException {&lt;br /&gt;        // filtre identité que ne à rien d'autre que donner la main&lt;br /&gt;        // au filtre de servlet suivant&lt;br /&gt;        // c'est cette méthode publique qui va pouvoir être interceptée&lt;br /&gt;        // et donc utilisée comme pointcut par Spring AOP&lt;br /&gt;        chain.doFilter(request, response);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void init(FilterConfig filterConfig) throws ServletException {&lt;br /&gt;        // cette partie &amp;quot;lifecycle&amp;quot; du filtre  est normalement prise en charge&lt;br /&gt;        // par la classe org.springframework.web.filter.DelegatingFilterProxy&lt;br /&gt;        // déclarée dans le web.xml&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}
&lt;/pre&gt;
&lt;p&gt;Ensuite, il faut déclarer ce filtre comme un bean spring :&lt;/p&gt;
&lt;pre&gt;
&amp;lt;bean id=&amp;quot;&lt;strong&gt;servletPointcutFilter&lt;/strong&gt;&amp;quot; class=&amp;quot;fr.openfarm.aop.ServletPointcutFilter&amp;quot;/&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Visible du contexte Spring, il peut alors être candidat aux advices.&lt;br /&gt;
&lt;br /&gt;
Il faut ensuite déclarer le filtre DelegatingFilterProxy de Spring et son
application dans le fichier web.xml :&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;web-app xmlns=&amp;quot;http://java.sun.com/xml/ns/j2ee&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;    xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&amp;quot;&lt;br /&gt;    version=&amp;quot;2.4&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;display-name&amp;gt;CXF WS-S&amp;lt;/display-name&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;context-param&amp;gt;&lt;br /&gt;        &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;        &amp;lt;param-value&amp;gt;&lt;br /&gt;            classpath:applicationContext.xml&lt;br /&gt;        &amp;lt;/param-value&amp;gt;&lt;br /&gt;    &amp;lt;/context-param&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;listener&amp;gt;&lt;br /&gt;        &amp;lt;listener-class&amp;gt;org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&amp;gt;&lt;br /&gt;    &amp;lt;/listener&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;!-- Il est impossible d'intercepter les servlets par Spring AOP&lt;br /&gt;        car elles sont hors contexte spring&lt;br /&gt;        l'astuce consiste à appliquer un filtre de servlet sur les CXF Servlets&lt;br /&gt;        grâce au filtre DelegatingFilterProxy qui s'enregistre dans le contexte spring&lt;br /&gt;        et qui déléguera au filtre déclaré comme bean servletPointcutFilter &lt;br /&gt;     --&amp;gt;&lt;br /&gt;    &amp;lt;filter&amp;gt;&lt;br /&gt;       &amp;lt;filter-name&amp;gt;&lt;strong&gt;servletPointcutFilter&lt;/strong&gt;&amp;lt;/filter-name&amp;gt;&lt;br /&gt;       &amp;lt;filter-class&amp;gt;&lt;strong&gt;org.springframework.web.filter.DelegatingFilterProxy&lt;/strong&gt;&amp;lt;/filter-class&amp;gt;&lt;br /&gt;    &amp;lt;/filter&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;       &amp;lt;filter-name&amp;gt;servletPointcutFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;       &amp;lt;servlet-name&amp;gt;CXFServlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;    &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;servlet&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;CXFServlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;display-name&amp;gt;CXF Servlet&amp;lt;/display-name&amp;gt;&lt;br /&gt;        &amp;lt;servlet-class&amp;gt;org.apache.cxf.transport.servlet.CXFServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;        &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;    &amp;lt;/servlet&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;CXFServlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;url-pattern&amp;gt;/services/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;welcome-file-list&amp;gt;&lt;br /&gt;        &amp;lt;welcome-file&amp;gt;index.html&amp;lt;/welcome-file&amp;gt;&lt;br /&gt;    &amp;lt;/welcome-file-list&amp;gt;&lt;br /&gt;        &lt;br /&gt;&amp;lt;/web-app&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
Toujours fidèle à la devise &amp;quot;convention over configuration&amp;quot;, il faut utiliser
comme valeur de &amp;lt;filter-name&amp;gt; dans le fichier web.xml l'identifiant du
bean déclaré dans Spring. Le DelegatingFilterProxy s'enregistre auprès du
context Spring et fera office de Filtre proxy en appelant notre
servletPointcutFilter.&lt;br /&gt;
&lt;br /&gt;
Le filtre de servlet d'exécutant systématiquement avec les servlets, on a donc
un moyen de s'insérer dans le fil d'exécution, à défaut d'être au plus près de
la servlet. Comme dans la première méthode, on peut alors appliquer un advice
sur le filtre de servlet avec par exemple l'advice @Around et le pointcut
suivant :&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
@Aspect&lt;br /&gt;public class TimeLoggerAspect {&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;    @Pointcut(&amp;quot;execution(public void fr.openfarm.aop.ServletPointcutFilter.doFilter(..))&amp;quot;)&lt;/strong&gt;&lt;br style=&quot;font-weight: bold;&quot; /&gt;&lt;strong&gt;    public void servlet() {}&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;    @Around(&amp;quot;servlet()&amp;quot;)&lt;br /&gt;    public void logTimeExec() { ... }&lt;br /&gt;&lt;br /&gt;}
&lt;/pre&gt;
&lt;p&gt;&lt;ins&gt;Source&lt;/ins&gt; :&lt;/p&gt;
&lt;p&gt;http://forum.springsource.org/showthread.php?t=58083&lt;/p&gt;
&lt;p&gt;Sinon un très bon article sur AOP &lt;a hreflang=&quot;en&quot; href=&quot;http://www.ibm.com/developerworks/java/library/j-aopwork15/&quot;&gt;AOP : mythes et
réalités&lt;/a&gt; ( &lt;a hreflang=&quot;en&quot; href=&quot;http://www.ibm.com/developerworks/java/library/j-aopwork15/&quot;&gt;http://www.ibm.com/developerworks/java/library/j-aopwork15/&lt;/a&gt;
)&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/10/03/Spring-AOP-advice-pointcut-Servlet#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/10/03/Spring-AOP-advice-pointcut-Servlet#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/551669</wfw:commentRss>
      </item>
    
  <item>
    <title>Spring AOP : trouver le bon pointcut avec la stack trace</title>
    <link>http://blog.guillaume-viel.com/post/2010/10/02/Spring-AOP-trouver-le-bon-pointcut-avec-la-stacktrace</link>
    <guid isPermaLink="false">urn:md5:e850f001ccf3ce011745b193eba37d24</guid>
    <pubDate>Sat, 02 Oct 2010 22:11:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>AOP</category><category>java</category><category>jee</category><category>profiling</category><category>spring</category>    
    <description>    &lt;p&gt;Il est parfois difficile d'identifier le bon endroit pour une &amp;quot;coupe&amp;quot;
(pointcut), et il ne faut pas perdre de vue qu'une méthode protected ne pourra
jamais être interceptée par Spring AOP.&lt;/p&gt;
&lt;p&gt;J'ai donc écris ce bout de code pour me faciliter la tâche et identifier
plus aisément quelle pourrait être la méthode déclarée en public et donc
candidate au pointcut.&lt;/p&gt;
&lt;p&gt;Ce code est à placer dans la méthode qui sera appelée en dernier dans le fil
d'exécution afin d'avoir une liste complète des méthodes pouvant être
interceptée&lt;/p&gt;
&lt;pre&gt;
        // récupération d'une trace de la pile pour notre thread courant&lt;br /&gt;        StackTraceElement[] stack = Thread.getAllStackTraces().get(Thread.currentThread());&lt;br /&gt;        &lt;br /&gt;        for(StackTraceElement ste : stack) { // on parcourt la pile&lt;br /&gt;            // on parcours la liste de toutes les méthodes pour la classe&lt;br /&gt;            // trouvée dans la stack trace et l'on vérifie si la méthode&lt;br /&gt;            // utilisée dans la stacktrace est bien publique&lt;br /&gt;            Method[] methods = Class.forName(ste.getClassName()).getMethods();&lt;br /&gt;            for(Method m : methods) {&lt;br /&gt;                if(m.getName().equals(ste.getMethodName())) {&lt;br /&gt;                    if(Modifier.isPublic(m.getModifiers()) ) {&lt;br /&gt;                        logger.debug( ste.getClassName() + &amp;quot;.&amp;quot; + ste.getMethodName() );&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }
&lt;/pre&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/10/02/Spring-AOP-trouver-le-bon-pointcut-avec-la-stacktrace#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/10/02/Spring-AOP-trouver-le-bon-pointcut-avec-la-stacktrace#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/551183</wfw:commentRss>
      </item>
    
  <item>
    <title>Erreur classique de JAXB : JAXBException nor any of its super class is known to this context</title>
    <link>http://blog.guillaume-viel.com/post/2010/10/01/JAXBException-nor-any-of-its-super-class-is-known-to-this-context</link>
    <guid isPermaLink="false">urn:md5:9be7694557e8a97fe13b8534236ddc97</guid>
    <pubDate>Fri, 01 Oct 2010 22:42:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>java</category><category>JAXB</category><category>JAXWS</category><category>jee</category><category>webservices</category>    
    <description>    &lt;p&gt;Cette exception peut se produire lorsque votre webservice contient des
objets complexes (objets imbriqués) qui ne sont pas forcément visible dans
votre déclaration de service. Pour qu'ils soient pris en compte, la solution
est d'utiliser l'annotation &lt;strong&gt;@XmlSeeAlso(MyObjectFactory.class,
MyOtherObjectFactory.class)&lt;/strong&gt; sur votre webservice JAX-WS en lui
indiquant les fabriques d'objets souhaitées. JAX-B pourra alors fabriquer tous
les objets nécessaire au fonctionnement du webservice.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Source&lt;/ins&gt; : &lt;a hreflang=&quot;en&quot; href=&quot;http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6419632&quot;&gt;http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6419632&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/10/01/JAXBException-nor-any-of-its-super-class-is-known-to-this-context#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/10/01/JAXBException-nor-any-of-its-super-class-is-known-to-this-context#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/550975</wfw:commentRss>
      </item>
    
  <item>
    <title>Web services securisés avec CXF et WSS4J (partie 1)</title>
    <link>http://blog.guillaume-viel.com/post/2010/09/13/Webservices-securis%C3%A9s-WS-Security-CXF-et-WSS4J</link>
    <guid isPermaLink="false">urn:md5:8a45924bdc54c32cdb669a9004d56968</guid>
    <pubDate>Mon, 13 Sep 2010 09:37:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>CXF</category><category>java</category><category>jee</category><category>SOAP</category><category>spring</category><category>webservices</category><category>WS-Security</category><category>WSS4J</category>    
    <description>&lt;p&gt;La sécurisation des webservices devient de plus en plus nécessaire dans le
monde de l'entreprise. Il y a une époque pas si lointaine, les entreprises ne
se souciaient pas trop de la sécurisation de leurs données à l'intérieur de
l'entreprise. Or il s'avère que les risques sécuritaires viennent
majoritairement de l'intérieur!&lt;/p&gt;
&lt;p&gt;Voici donc un tutoriel qui explique comment mettre en place toute
l'infrastructure webservice : serveur et client. Nous utiliserons CXF qui nous
parait être une des solutions les plus efficaces et maniables. CXF allie
performances et simplicité d'intégration avec la plupart des frameworks (Spring
et WSS4J).&lt;/p&gt;    &lt;h1&gt;Etape 1 : création d'un webservice SOAP / HTTP&lt;/h1&gt;
&lt;h2&gt;a) création du projet&lt;/h2&gt;
&lt;p&gt;Le serveur de webservices (WS) sera en fait une webapp qui exposera un
fichier WSDL et qui répondra aux requêtes exprimées en SOAP. Pour un début nous
allons faire dans l'originalité et faire un WS HelloWorld. Dans un deuxième
temps, nous en ferons un plus complexe en terme de structure données.&lt;/p&gt;
&lt;p&gt;On commence par créer un nouveau projet sous eclipse. On utilise maven pour
construire et packager l'application. J'utilise la &lt;a hreflang=&quot;en&quot; href=&quot;http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html&quot;&gt;
structure classique des répertoires de maven&lt;/a&gt; avec src/main/java et
src/main/resources pour les sources et target/ pour les builds.&lt;/p&gt;
&lt;img title=&quot;java-web-services-securises-projet-eclipse.png, sept. 2010&quot; alt=&quot;&quot; src=&quot;http://blog.guillaume-viel.com/public/WS/java-web-services-securises-projet-eclipse.png&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
Dans le fichier pom.xml on y met les dépendances CXF et SL4J :&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;cxf-rt-frontend-jaxws&lt;/li&gt;
&lt;li&gt;cxf-rt-transports-http&lt;/li&gt;
&lt;li&gt;slf4j-api&lt;/li&gt;
&lt;li&gt;slf4j-log4j12&lt;/li&gt;
&lt;/ul&gt;
A l'heure ou j'écris les versions suivantes sont utilisées (à mettre en fin du
pom.xml) :&lt;br /&gt;
    &lt;code&gt;&amp;lt;properties&amp;gt;&lt;br /&gt;
       
&amp;lt;spring.version&amp;gt;2.5.6&amp;lt;/spring.version&amp;gt;&lt;br /&gt;
       
&amp;lt;cxf.version&amp;gt;2.2.9&amp;lt;/cxf.version&amp;gt;&lt;br /&gt;
       
&amp;lt;sl4j.version&amp;gt;1.6.1&amp;lt;/sl4j.version&amp;gt;&lt;br /&gt;
  &amp;lt;/properties&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
La version de spring est donnée juste à titre indicatif car c'est celle
utilisée par CXF (les librairies spring-core, spring-context, spring-beans,
spring-web sont utilisées).&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;b) définition et implémentation du service&lt;/h2&gt;
La définition et création du service est très rapide avec les annotations
JAX-WS. L'interface est la suivante :&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;package fr.openfarm.helloworld.wss;&lt;br /&gt;
&lt;br /&gt;
import javax.jws.WebMethod;&lt;br /&gt;
import javax.jws.WebService;&lt;br /&gt;
import javax.jws.WebParam;&lt;br /&gt;
&lt;br /&gt;
@WebService&lt;br /&gt;
public interface HelloWorldWss {&lt;br /&gt;
    @WebMethod&lt;br /&gt;
    public String sayHi(@WebParam(name=&amp;quot;text&amp;quot;)String
text);&lt;br /&gt;
}&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
L'annotation @WebService est l'annotation minimale. Cependant, pour éviter de
rendre les paramètres anonymes dans la génération à la volée du WSDL, il est
conseillé d'ajouter @WebMethod et @WebParam afin de forcer le nommage.&lt;br /&gt;
L'implémentation est tout aussi rapide :&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;package fr.openfarm.helloworld.wss;&lt;br /&gt;
&lt;br /&gt;
import javax.jws.WebService;&lt;br /&gt;
&lt;br /&gt;
import org.apache.log4j.Logger;&lt;br /&gt;
&lt;br /&gt;
@WebService(endpointInterface =
&amp;quot;fr.openfarm.helloworld.wss.HelloWorldWss&amp;quot;)&lt;br /&gt;
public class HelloWorldWssImpl implements HelloWorldWss {&lt;br /&gt;
   &lt;br /&gt;
    static final Logger logger =
Logger.getLogger(HelloWorldWssImpl.class);&lt;br /&gt;
   &lt;br /&gt;
    public String sayHi(String text) {&lt;br /&gt;
        StringBuilder sb = new
StringBuilder(&amp;quot;Hello&amp;quot;);&lt;br /&gt;
        sb.append(text);&lt;br /&gt;
        logger.debug(sb.toString());&lt;br /&gt;
        return sb.toString();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;c) configuration Spring et CXF&lt;/h2&gt;
Une fois cette (superbe) implémentation réalisée, il faut configurer CXF , le
contexte Spring et le contexte web.&lt;br /&gt;
Voici le contenu du fichier src/main/resources/applicationContext.xml minimal
(dans le cas d'un client comme on le verra plus loin) auquel on aura ajouté un
élément jaxws:endpoint qui définira notre web service.&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
    xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
   
xmlns:http-conf=&amp;quot;http://cxf.apache.org/transports/http/configuration&amp;quot;&lt;br /&gt;
    xmlns:jaxws=&amp;quot;http://cxf.apache.org/jaxws&amp;quot;&lt;br /&gt;
    xsi:schemaLocation=&amp;quot;&lt;br /&gt;
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd&lt;br /&gt;
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&lt;br /&gt;
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd&lt;br /&gt;
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;import resource=&amp;quot;classpath:META-INF/cxf/cxf.xml&amp;quot;
/&amp;gt;&lt;br /&gt;
    &amp;lt;import
resource=&amp;quot;classpath:META-INF/cxf/cxf-extension-soap.xml&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;import resource=&amp;quot;classpath:META-INF/cxf/cxf-servlet.xml&amp;quot;
/&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;jaxws:endpoint id=&amp;quot;helloWorld&amp;quot;&lt;br /&gt;
       
implementor=&amp;quot;fr.openfarm.helloworld.wss.HelloWorldWssImpl&amp;quot;&lt;br /&gt;
        address=&amp;quot;/HelloWorld&amp;quot;&lt;br /&gt;
       
xmlns:e=&amp;quot;http://service.jaxws.cxf.apache.org/endpoint&amp;quot;&lt;br /&gt;
       
xmlns:s=&amp;quot;http://service.jaxws.cxf.apache.org/service&amp;quot;/&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir utiliser cette notation, il est important de bien ajouter les
namespaces xmlns:jaxws et xmlns:http-conf dans l'entête. D'autre part, il ne
faut pas oublier de mettre les XSD de spring 2.5 dans schemaLocation, sinon
vous risquez d'obtenir cette erreur : &lt;q&gt;&lt;strong&gt;The prefix &amp;quot;jaxws&amp;quot; for element
&amp;quot;jaxws:endpoint&amp;quot; is not bound&lt;/strong&gt;&lt;/q&gt;. Elle peut vite arriver si vous vous
fiez à la documentation CXF qui n'est pas toujours à jour.&lt;br /&gt;
Les &lt;q&gt;xmlns:e&lt;/q&gt; et &lt;q&gt;xmlns:s&lt;/q&gt; sont ajoutés pour mémoire au cas où l'on
souhaite personnaliser le nommage du endpoint et du service par l'intermédiare
des attributs &lt;q&gt;endpoint&lt;/q&gt; et &lt;q&gt;service&lt;/q&gt; dans la balise
&amp;lt;jaxws:endpoint&amp;gt;.&lt;br /&gt;
Les trois directives &lt;q&gt;import&lt;/q&gt; chargent les fichiers de configuration CXF
supplémentaires. Pour le moment ces fichiers n'existent pas.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;d) configuration webapp et logs&lt;/h2&gt;
Pour log4j (via API SL4L) il est nécessaire d'ajouter un fichier de
configuration minimum pour les logs dans src/main/resources&lt;br /&gt;
&lt;code&gt;log4j.rootCategory=WARN, CONSOLE&lt;br /&gt;
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender&lt;br /&gt;
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout&lt;br /&gt;
log4j.appender.CONSOLE.layout.ConversionPattern=[%d{ABSOLUTE} %-5p %c{1}]:
%m%n&lt;br /&gt;
log4j.logger.fr.openfarm=DEBUG&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;
Ensuiite le fichier web.xml devra être comme suit :&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;web-app xmlns=&amp;quot;http://java.sun.com/xml/ns/j2ee&amp;quot;
xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
   
xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&amp;quot;&lt;br /&gt;
    version=&amp;quot;2.4&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;display-name&amp;gt;Hello World
WSS&amp;lt;/display-name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;context-param&amp;gt;&lt;br /&gt;
       
&amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;
        &amp;lt;param-value&amp;gt;&lt;br /&gt;
           
classpath:applicationContext.xml&lt;br /&gt;
        &amp;lt;/param-value&amp;gt;&lt;br /&gt;
    &amp;lt;/context-param&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;listener&amp;gt;&lt;br /&gt;
       
&amp;lt;listener-class&amp;gt;org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&amp;gt;&lt;br /&gt;

    &amp;lt;/listener&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;servlet&amp;gt;&lt;br /&gt;
       
&amp;lt;servlet-name&amp;gt;CXFServlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;display-name&amp;gt;CXF
Servlet&amp;lt;/display-name&amp;gt;&lt;br /&gt;
       
&amp;lt;servlet-class&amp;gt;org.apache.cxf.transport.servlet.CXFServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;

       
&amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
       
&amp;lt;servlet-name&amp;gt;CXFServlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
       
&amp;lt;url-pattern&amp;gt;/services/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;welcome-file-list&amp;gt;&lt;br /&gt;
       
&amp;lt;welcome-file&amp;gt;index.html&amp;lt;/welcome-file&amp;gt;&lt;br /&gt;
    &amp;lt;/welcome-file-list&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
&amp;lt;/web-app&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
La première partie permet au contexte Spring d'être chargée grâce au
ContextLoaderListener auquel on indique de charger le fichier
applicationContext.xml.&lt;br /&gt;
On déclare ensuite la servlet CXF qui va permettre d'exposer nos services
derrière le contexte helloworld-wss/services/.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;e) compilation et packaging de l'application avec maven&lt;/h2&gt;
Dans le pom.xml on ajoute le plugin pour compiler le tout en Java 6 :&lt;br /&gt;
&lt;code&gt;&amp;lt;pluginManagement&amp;gt;&lt;br /&gt;
            &amp;lt;plugins&amp;gt;&lt;br /&gt;
               
&amp;lt;plugin&amp;gt;&lt;br /&gt;
               
   
&amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;
               
   
&amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
               
    &amp;lt;configuration&amp;gt;&lt;br /&gt;
               
        &amp;lt;source&amp;gt;1.6&amp;lt;/source&amp;gt;&lt;br /&gt;
               
        &amp;lt;target&amp;gt;1.6&amp;lt;/target&amp;gt;&lt;br /&gt;
               
    &amp;lt;/configuration&amp;gt;&lt;br /&gt;
               
&amp;lt;/plugin&amp;gt;&lt;br /&gt;
            &amp;lt;/plugins&amp;gt;&lt;br /&gt;
&amp;lt;/pluginManagement&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;
ensuite dans le répertoire du projet il suffit pour créer le WAR de
lancer&lt;br /&gt;
&lt;code&gt;$ mvn clean package&lt;/code&gt;&lt;br /&gt;
(ne pas oublier de mettre &lt;code&gt;&amp;lt;packaging&amp;gt;war&amp;lt;/packaging&amp;gt;&lt;/code&gt;
en début du pom.xml)&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;f) déploiement&lt;/h2&gt;
On peut utiliser le plugin maven pour tomcat, ou sinon &lt;a hreflang=&quot;fr&quot; href=&quot;https://blog.gandi.net/post.php?id=513484&quot;&gt;voir cet article&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;g) utilisation du web service&lt;/h2&gt;
Une fois la webapp déployée sous Tomcat, on peut aller à l'URL suivante
http://localhost:8081/helloworld-wss/services/ pour voir ceci :&lt;br /&gt;
&lt;img title=&quot;cxf-available-web-services.png, sept. 2010&quot; alt=&quot;&quot; src=&quot;http://blog.guillaume-viel.com/public/WS/cxf-available-web-services.png&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En cliquant sur le lien, on peut alors accéder au fichier WSDL qui aura
l'allure suivante :&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&amp;lt;?xml version='1.0' encoding='UTF-8'?&amp;gt;&amp;lt;wsdl:definitions
name=&amp;quot;HelloWorldWssImplService&amp;quot;
targetNamespace=&amp;quot;http://wss.helloworld.openfarm.fr/&amp;quot;
xmlns:ns1=&amp;quot;http://cxf.apache.org/bindings/xformat&amp;quot;
xmlns:soap=&amp;quot;http://schemas.xmlsoap.org/wsdl/soap/&amp;quot;
xmlns:tns=&amp;quot;http://wss.helloworld.openfarm.fr/&amp;quot;
xmlns:wsdl=&amp;quot;http://schemas.xmlsoap.org/wsdl/&amp;quot;
xmlns:xsd=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;wsdl:types&amp;gt;&lt;br /&gt;
&amp;lt;xs:schema elementFormDefault=&amp;quot;unqualified&amp;quot;
targetNamespace=&amp;quot;http://wss.helloworld.openfarm.fr/&amp;quot; version=&amp;quot;1.0&amp;quot;
xmlns:tns=&amp;quot;http://wss.helloworld.openfarm.fr/&amp;quot;
xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name=&amp;quot;sayHi&amp;quot; type=&amp;quot;tns:sayHi&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name=&amp;quot;sayHiResponse&amp;quot; type=&amp;quot;tns:sayHiResponse&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;xs:complexType name=&amp;quot;sayHi&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;xs:sequence&amp;gt;&lt;br /&gt;
      &amp;lt;xs:element minOccurs=&amp;quot;0&amp;quot; name=&amp;quot;text&amp;quot;
type=&amp;quot;xs:string&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;/xs:sequence&amp;gt;&lt;br /&gt;
  &amp;lt;/xs:complexType&amp;gt;&lt;br /&gt;
&amp;lt;xs:complexType name=&amp;quot;sayHiResponse&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;xs:sequence&amp;gt;&lt;br /&gt;
      &amp;lt;xs:element minOccurs=&amp;quot;0&amp;quot; name=&amp;quot;return&amp;quot;
type=&amp;quot;xs:string&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;/xs:sequence&amp;gt;&lt;br /&gt;
  &amp;lt;/xs:complexType&amp;gt;&lt;br /&gt;
&amp;lt;/xs:schema&amp;gt;&lt;br /&gt;
  &amp;lt;/wsdl:types&amp;gt;&lt;br /&gt;
  &amp;lt;wsdl:message name=&amp;quot;sayHiResponse&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;wsdl:part element=&amp;quot;tns:sayHiResponse&amp;quot;
name=&amp;quot;parameters&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/wsdl:part&amp;gt;&lt;br /&gt;
  &amp;lt;/wsdl:message&amp;gt;&lt;br /&gt;
  &amp;lt;wsdl:message name=&amp;quot;sayHi&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;wsdl:part element=&amp;quot;tns:sayHi&amp;quot;
name=&amp;quot;parameters&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/wsdl:part&amp;gt;&lt;br /&gt;
  &amp;lt;/wsdl:message&amp;gt;&lt;br /&gt;
  &amp;lt;wsdl:portType name=&amp;quot;HelloWorldWss&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;wsdl:operation name=&amp;quot;sayHi&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;wsdl:input message=&amp;quot;tns:sayHi&amp;quot;
name=&amp;quot;sayHi&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/wsdl:input&amp;gt;&lt;br /&gt;
      &amp;lt;wsdl:output message=&amp;quot;tns:sayHiResponse&amp;quot;
name=&amp;quot;sayHiResponse&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/wsdl:output&amp;gt;&lt;br /&gt;
    &amp;lt;/wsdl:operation&amp;gt;&lt;br /&gt;
  &amp;lt;/wsdl:portType&amp;gt;&lt;br /&gt;
  &amp;lt;wsdl:binding name=&amp;quot;HelloWorldWssImplServiceSoapBinding&amp;quot;
type=&amp;quot;tns:HelloWorldWss&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;soap:binding style=&amp;quot;document&amp;quot;
transport=&amp;quot;http://schemas.xmlsoap.org/soap/http&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;wsdl:operation name=&amp;quot;sayHi&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;soap:operation soapAction=&amp;quot;&amp;quot;
style=&amp;quot;document&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;wsdl:input name=&amp;quot;sayHi&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;soap:body use=&amp;quot;literal&amp;quot;
/&amp;gt;&lt;br /&gt;
      &amp;lt;/wsdl:input&amp;gt;&lt;br /&gt;
      &amp;lt;wsdl:output name=&amp;quot;sayHiResponse&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;soap:body use=&amp;quot;literal&amp;quot;
/&amp;gt;&lt;br /&gt;
      &amp;lt;/wsdl:output&amp;gt;&lt;br /&gt;
    &amp;lt;/wsdl:operation&amp;gt;&lt;br /&gt;
  &amp;lt;/wsdl:binding&amp;gt;&lt;br /&gt;
  &amp;lt;wsdl:service name=&amp;quot;HelloWorldWssImplService&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;wsdl:port
binding=&amp;quot;tns:HelloWorldWssImplServiceSoapBinding&amp;quot;
name=&amp;quot;HelloWorldWssImplPort&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;soap:address
location=&amp;quot;http://localhost:8081/helloworld-wss/services/HelloWorld&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;/wsdl:port&amp;gt;&lt;br /&gt;
  &amp;lt;/wsdl:service&amp;gt;&lt;br /&gt;
&amp;lt;/wsdl:definitions&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
La sécurisation fera l'objet d'un deuxième billet.&lt;br /&gt;
@Bientot&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/09/13/Webservices-securis%C3%A9s-WS-Security-CXF-et-WSS4J#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/09/13/Webservices-securis%C3%A9s-WS-Security-CXF-et-WSS4J#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/545641</wfw:commentRss>
      </item>
    
  <item>
    <title>Activation des traces du driver JDBC Oracle</title>
    <link>http://blog.guillaume-viel.com/post/2010/10/14/Activation-des-traces-du-driver-JDBC-Oracle</link>
    <guid isPermaLink="false">urn:md5:6a4e42bb7b43125a19b61155db025f18</guid>
    <pubDate>Wed, 01 Sep 2010 18:03:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>java</category><category>jdbc</category><category>jee</category><category>logging</category><category>oracle</category>    
    <description>    &lt;p&gt;Il est parfois utile de comprendre ce que fait le driver JDBC Oracle que les
développeurs connaissent sous le nom de ojdbc14.jar. Il existe en fait un autre
driver destiné au debug : ojdbc14_g.jar pour lequel il suffit d'ajouter ceci
dans les JAVA_OPTS pour activer les traces&lt;/p&gt;
&lt;p&gt;JAVA_OPTS=&amp;quot;$JAVA_OPTS -Djava.util.logging.config.file=OracleLog.properties
-Doracle.jdbc.Trace=true&amp;quot;&lt;/p&gt;
&lt;p&gt;Ensuite, un fichier &lt;a href=&quot;http://blog.guillaume-viel.com/public/oracle/OracleLog.properties&quot;&gt;OracleLog.properties&lt;/a&gt; doit être placé
avec le jar pour configurer les traces souhaitées. Il est conseillé de le
modifier sinon vous allez avoir beaucoup de traces...&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/10/14/Activation-des-traces-du-driver-JDBC-Oracle#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/10/14/Activation-des-traces-du-driver-JDBC-Oracle#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/554522</wfw:commentRss>
      </item>
    
  <item>
    <title>Migration des scripts de démarrage de la Debian vers le LSB (Linux Standard Base)</title>
    <link>http://blog.guillaume-viel.com/post/2010/08/24/Migration-init-scripts-Debian-vers-LSB</link>
    <guid isPermaLink="false">urn:md5:99c131902ba7a909b05493ad2eacfcf1</guid>
    <pubDate>Tue, 24 Aug 2010 00:45:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>linux</category>
        <category>debian</category><category>linux</category><category>sysadmin</category>    
    <description>    &lt;p&gt;Récemment j'ai eu la surprise d'avoir cet écran lors d'une mise à jour
Debian :&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.guillaume-viel.com/public/linux/linux-debian-configuration-sysv-rc-LSB.png&quot;&gt;&lt;img title=&quot;linux-debian-configuration-sysv-rc-LSB.png, août 2010&quot; style=&quot;margin: 0 1em 1em 0;&quot; alt=&quot;&quot; src=&quot;http://blog.guillaume-viel.com/public/linux/.linux-debian-configuration-sysv-rc-LSB_m.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Il suffit de suivre les indications... Arf!&lt;/p&gt;
&lt;p&gt;Voici les liens qui pourront vous permettre de réussir votre migration :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://wiki.debian.org/LSBInitScripts/DependencyBasedBoot&quot;&gt;explication de
l'introduction du dependency based boot dans Debian&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://wiki.debian.org/LSBInitScripts&quot;&gt;pour
convertir un script d'init au format LSB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/initscrcomconv.html&quot;&gt;
les spécifications LSB sur les scripts d'init&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dans mon cas la migration a été très simple :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;un nettoyage des packages enlevés mais encore configuré avec &lt;code&gt;dpkg
--purge package&lt;/code&gt; pour enlever les fichiers de configuration (en vérifiant
au préalable la liste des fichiers de configuration et s'il faut conserver
quelque chose)&lt;/li&gt;
&lt;li&gt;une mise à jour de mes scripts maison au format LSB&lt;/li&gt;
&lt;li&gt;la reconfiguration de sysv-rc avec &lt;code&gt;dpkg-reconfigure sysv-rc&lt;/code&gt;
comme l'indique l'écran d'apt-get&lt;/li&gt;
&lt;/ul&gt;
Après ça votre Linux devrait être capable de lancer plusieurs scripts d'init à
la fois en parallèle tout en respectant les dépendances entre scripts.&lt;br /&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/08/24/Migration-init-scripts-Debian-vers-LSB#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/08/24/Migration-init-scripts-Debian-vers-LSB#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/541386</wfw:commentRss>
      </item>
    
  <item>
    <title>Expressions régulières ou regexp en java</title>
    <link>http://blog.guillaume-viel.com/post/2010/08/24/Expressions-r%C3%A9guli%C3%A8res-ou-regexp-en-java</link>
    <guid isPermaLink="false">urn:md5:36ef8bf5fd1080f7247ec34e8028ae3e</guid>
    <pubDate>Tue, 24 Aug 2010 00:11:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>java</category><category>regexp</category>    
    <description>    J'ai souvent cherché sur Internet des ressources claires et précises sur les
expressions régulières en Java. En voici une qui a le mérite d'être claire,
complète, avec des exemples et en français :&lt;br /&gt;
&lt;a hreflang=&quot;fr&quot; href=&quot;http://prevert.upmf-grenoble.fr/Prog/Java/CoursJava/expressionsRegulieres.html&quot;&gt;
http://prevert.upmf-grenoble.fr/Prog/Java/CoursJava/expressionsRegulieres.html&lt;/a&gt;&lt;br /&gt;

&lt;br /&gt;
Il y a bien sûr la documentation SUN (oops... Oracle) sur les &lt;a hreflang=&quot;en&quot; href=&quot;http://download.oracle.com/javase/tutorial/essential/regex/index.html%20&quot;&gt;regexp
en java&lt;/a&gt; mais je la trouve illisible.&lt;br /&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/08/24/Expressions-r%C3%A9guli%C3%A8res-ou-regexp-en-java#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/08/24/Expressions-r%C3%A9guli%C3%A8res-ou-regexp-en-java#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/541381</wfw:commentRss>
      </item>
    
  <item>
    <title>AVWorks , Java et IPv6</title>
    <link>http://blog.guillaume-viel.com/post/2010/07/08/IPv6-java-AVWorks</link>
    <guid isPermaLink="false">urn:md5:e2766cf9a781eedcdc80320a12d7cdb8</guid>
    <pubDate>Thu, 08 Jul 2010 13:18:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>debian</category><category>IPv6</category><category>java</category><category>jvm</category><category>linux</category><category>sysadmin</category>    
    <description>    &lt;p&gt;L'application AVWorks est une application fournie avec les KVM IP d'Avocent
et notamment la série des Autoview. Ces anciens KVM IP ne fonctionnent qu'en
IPv4. AVWorks est réalisée en Java et il semblerait que la façon dont Sun ait
implémenté la dual stack IPv4 / IPv6 dans la JVM est plutôt étrange ( cf.
article suivant sur &lt;a hreflang=&quot;fr&quot; href=&quot;http://www.developpez.net/forums/d880926/java/general-java/apis/io/serversocket-debian-ipv6-only/&quot;&gt;
debian et ipv6&lt;/a&gt; )... Surprise donc lorsqu'en passant en dual stack IPv4 /
IPv6 sur Debian je me retrouve avec l'application AVWorks et toutes les autres
applications java qui ne marchent plus.&lt;/p&gt;
&lt;p&gt;J'ai donc cherché à patcher l'application afin qu'elle refonctionne et c'est
possible. Voici comment faire :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;surtout garder l'ancienne version 2.1 d'AVWorks et ne pas installer la
nouvelle version 3.1 qui contient pas mal de bugs&lt;/li&gt;
&lt;li&gt;dans le fichier AVWORKS_HOME/Avocent_AVWorks.lax il suffit d'y ajouter la
variable d'environnement java &amp;quot;java.net.preferIPv4Stack=true&amp;quot; vers la ligne 68
comme ceci:
&lt;strong&gt;lax.nl.java.option.additional=-Djava.library.path=AVWORKS_HOME/Avocent_AVWorks
-Duser.variant=avct -Djava.net.preferIPv4Stack=true&lt;/strong&gt;&lt;br /&gt;
(avec AVWORKS_HOME qui doit être remplacé par votre répertoire d'installation
d'AVWorks)&lt;/li&gt;
&lt;/ol&gt;
Edit :&lt;br /&gt;
En fait, après enquête, il s'avère que le dysfonctionnement venait d'un
problème plus général lié à la mise à jour de l'OS (i.e. une Debian)... Le
paramètre noyau net.ipv6.bindv6only était à 1 !!! Ceci privilégie IPv6 avant
tout, d'où les problèmes de java qui cherchait à se connecter en IPv6 avec des
adresses IPv4. Pour remédier au problème il suffit de mettre
&lt;code&gt;net.ipv6.bindv6only=0&lt;/code&gt; dans le fichier
&lt;code&gt;/etc/sysctl.d/bindv6only.conf&lt;/code&gt; et de lancer &lt;code&gt;invoke-rc.d
procps restart&lt;/code&gt; pour faire appliquer la nouvelle configuration.&lt;br /&gt;
&lt;br /&gt;
Sources :&lt;br /&gt;
&lt;br /&gt;
&lt;a hreflang=&quot;en&quot; href=&quot;http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=560044&quot;&gt;sun-java6-jre:
net.ipv6.bindv6only=1 breaks java networking&lt;/a&gt;&lt;br /&gt;
&lt;p&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=560056&quot;&gt;net.ipv6.bindv6only=1
breaks java networking&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://groups.google.com/group/google-web-toolkit/browse_thread/thread/41882a250b0d4882/d4b08807efc9fa8d?lnk=raot&amp;amp;pli=1&quot;&gt;
ERROR: transport error 202: connect failed: Connection refused&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/07/08/IPv6-java-AVWorks#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/07/08/IPv6-java-AVWorks#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/532116</wfw:commentRss>
      </item>
    
  <item>
    <title>Chez Openfarm des architectes java certifiés Scrum Master</title>
    <link>http://blog.guillaume-viel.com/post/2010/06/03/openfarm-architectes-java-certifi%C3%A9s-Scrum-Master</link>
    <guid isPermaLink="false">urn:md5:08706580ca98325132ea899113d9a10e</guid>
    <pubDate>Thu, 03 Jun 2010 10:01:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>méthodes agiles</category>
        <category>méthode agiles</category><category>Scrum</category><category>ScrumMaster</category>    
    <description>    &lt;p&gt;Ils l'ont fait!&lt;/p&gt;
&lt;p&gt;Deux architectes java d'Openfarm sont désormais certifiés Scrum Master :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://www.scrumalliance.org/profiles/86807-guillaume-viel&quot;&gt;Guillaume
VIEL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://www.scrumalliance.org/profiles/86820-eric-michel&quot;&gt;Eric MICHEL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://fr.wikipedia.org/wiki/Scrum&quot;&gt;L'explication de
Scrum est ici pour ceux qui ne connaissent pas&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/06/03/openfarm-architectes-java-certifi%C3%A9s-Scrum-Master#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/06/03/openfarm-architectes-java-certifi%C3%A9s-Scrum-Master#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/524117</wfw:commentRss>
      </item>
    
  <item>
    <title>Maven comment créer un jar des sources</title>
    <link>http://blog.guillaume-viel.com/post/2010/04/23/Maven-comment-cr%C3%A9er-un-jar-des-sources</link>
    <guid isPermaLink="false">urn:md5:d9013e932f0be659ca806fb21742ae4a</guid>
    <pubDate>Mon, 03 May 2010 18:29:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>java</category><category>maven</category>    
    <description>    &lt;p&gt;Il peut arriver que l'on ait besoin de naviguer dans les sources d'un jar
fait maison à travers Eclipse. Ce jar fait souvent d'un projet externe au
projet courant, mais vous souhaitez pouvoir naviguer ou débugger dans ce
code.&lt;/p&gt;
Il suffit d'ajouter ceci à votre pom.xml&lt;br /&gt;
&lt;pre&gt;
&lt;code&gt;&amp;lt;project&amp;gt;  ...&lt;br /&gt;
 &amp;lt;build&amp;gt;&lt;br /&gt;
    &amp;lt;plugins&amp;gt;&lt;br /&gt;
      &amp;lt;plugin&amp;gt;&lt;br /&gt;
        &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;
        &amp;lt;artifactId&amp;gt;maven-source-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
        &amp;lt;version&amp;gt;2.1.1&amp;lt;/version&amp;gt;&lt;br /&gt;
        &amp;lt;executions&amp;gt;&lt;br /&gt;
          &amp;lt;execution&amp;gt;&lt;br /&gt;
            &amp;lt;id&amp;gt;attach-sources&amp;lt;/id&amp;gt;&lt;br /&gt;
            &amp;lt;phase&amp;gt;verify&amp;lt;/phase&amp;gt;&lt;br /&gt;
            &amp;lt;goals&amp;gt;&lt;br /&gt;
              &amp;lt;goal&amp;gt;jar-no-fork&amp;lt;/goal&amp;gt;&lt;br /&gt;
            &amp;lt;/goals&amp;gt;&lt;br /&gt;
          &amp;lt;/execution&amp;gt;&lt;br /&gt;
        &amp;lt;/executions&amp;gt;&lt;br /&gt;
      &amp;lt;/plugin&amp;gt;&lt;br /&gt;
    &amp;lt;/plugins&amp;gt;&lt;br /&gt;
  &amp;lt;/build&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&lt;br /&gt;&lt;/code&gt;
&lt;/pre&gt;
Ensuite la commande suivante fera l'affaire&lt;br /&gt;
&lt;code&gt;$ mvn source:jar-no-fork&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
La solution se trouve en fait ici avec plus de détails  : &lt;a hreflang=&quot;en&quot; href=&quot;http://maven.apache.org/plugins/maven-source-plugin/usage.html&quot;&gt;http://maven.apache.org/plugins/maven-source-plugin/usage.html&lt;/a&gt;&lt;br /&gt;

&lt;br /&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/04/23/Maven-comment-cr%C3%A9er-un-jar-des-sources#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/04/23/Maven-comment-cr%C3%A9er-un-jar-des-sources#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/511130</wfw:commentRss>
      </item>
    
  <item>
    <title>Maven optimiser le déploiement avec un WAR éclaté</title>
    <link>http://blog.guillaume-viel.com/post/2010/05/03/Maven-optimiser-le-d%C3%A9ploiement-avec-un-WAR-%C3%A9clat%C3%A9</link>
    <guid isPermaLink="false">urn:md5:76180308f6ab12ff98c5ac7dc5ec0999</guid>
    <pubDate>Mon, 03 May 2010 18:08:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>hudson</category><category>java</category><category>jee</category><category>maven</category><category>rsync</category><category>shell</category><category>tomcat</category>    
    <description>&lt;p&gt;Optimiser le temps de déploiement devient parfois crucial pour éviter de
perdre des heures... Après avoir tenté des plugins maven (comme cargo par
exemple) sans être totalement convaincu par leur efficacité (quand ça marche!),
il m'a semblé plus efficace de recourir au script shell.&lt;/p&gt;
&lt;p&gt;Maven est idéal pour toutes ces tâches mais nécessite parfois un peu de
tuning, notamment lorsqu'on lui demande le packaging de l'application avec le
plugin maven-war-plugin. L'opération est laborieuse et nécessite ensuite le
déploiement d'un WAR ce qui veut dire que (de façon raccourcie car maven fait
plus de choses en réalité) :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;maven compile l'application&lt;/li&gt;
&lt;li&gt;Maven copie les classes compilées et les fichiers de ressource dans une
structure éclaté (dans le répertoire target)&lt;/li&gt;
&lt;li&gt;Maven zippe le tout dans un WAR (et c'est long!)&lt;/li&gt;
&lt;li&gt;ensuite il faut uploader le WAR vers le serveur cible&lt;/li&gt;
&lt;li&gt;Tomcat ou votre serveur d'application java doit ensuite dézipper
l'archive...&lt;/li&gt;
&lt;/ul&gt;
Au final vous avez plusieurs opérations couteuses en temps et en ressource.
Tout doit être fait manuellement.&lt;br /&gt;
&lt;br /&gt;
Comment accélérer le processus ?&lt;br /&gt;
&lt;br /&gt;
Julien DUBOIS propose sur le &lt;a hreflang=&quot;fr&quot; href=&quot;http://www.responcia.fr/blog/&quot;&gt;blog de Responcia&lt;/a&gt; une &lt;a hreflang=&quot;fr&quot; href=&quot;http://www.responcia.fr/blog/2010/02/15/boostez-la-performance-de-vos-developpements/&quot;&gt;
solution intéressante pour optimiser vos développements&lt;/a&gt; avec Jetty. Il
apporte la preuve en vidéo que l'on peut &lt;a hreflang=&quot;fr&quot; href=&quot;http://www.responcia.fr/blog/2010/03/22/productivite-des-developpements-java-le-test-en-video/&quot;&gt;
améliorer les productivité des développements Java&lt;/a&gt; de cette façon. Mais
parfois, il n'est pas possible d'opter pour Jetty...&lt;br /&gt;
&lt;br /&gt;    &lt;h2&gt;Packaging maven rapide&lt;/h2&gt;
&lt;p&gt;on package l'application avec la commande suivante&lt;/p&gt;
&lt;code&gt;$ mvn -Dmaven.test.skip=true clean compiler:compile
war:exploded&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;-Dmaven.test.skip : saute l'exécution des tests&lt;/li&gt;
&lt;li&gt;compiler:compile : compile le projets sans les tests (pour compiler aussi
les tests ajouter compiler:testCompile et pour &amp;quot;tisser&amp;quot; l'AOP avec par exemple
aspectj n'oubliez pas d'ajouter aspectj:compile !!!)&lt;/li&gt;
&lt;li&gt;war:exploded (ou war:inplace) : ceci arrête le packaging de l'application
au WAR éclaté (sans zipper l'arborescence éclatée dans un fichier WAR)&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;h2&gt;Script de déploiement rsync&lt;/h2&gt;
La structure éclatée est ensuite déployée avec rsync. Si vous êtes sous Windows
utilisez Cygwin et lancez votre script avec &amp;gt;sh monScript.sh.&lt;br /&gt;
J'utilise tomcat avec une structure multi-instance avec un déploiement par
fichier de contexte XML à placer généralement dans le répertoire
conf/Catalina/localhost&lt;br /&gt;
Un script s'impose (à adapter et améliorer en fonction des besoins).&lt;br /&gt;
&lt;br /&gt;
Sous linux :&lt;br /&gt;
&lt;code&gt;#!/bin/sh&lt;br /&gt;
JSERVER_USER=tomcat&lt;br /&gt;
HOST_DEPLOY=monserveur.mondomain.com&lt;br /&gt;
proj_name=monprojet&lt;br /&gt;
PROJ_HOME=~/workspace/$proj_name/target/$proj_name&lt;br /&gt;
TC_HOME=/srv/tomcat6&lt;br /&gt;
TC_INSTANCE=instance_monprojet&lt;br /&gt;
ssh ${JSERVER_USER}@${HOST_DEPLOY} &amp;quot;JAVA_HOME=/srv/java/jdk
${TC_HOME}/${TC_INSTANCE}/bin/catalina.sh stop&amp;quot;&lt;br /&gt;
mvn -Dmaven.test.skip=true clean compiler:compile war:exploded&lt;br /&gt;
time rsync -rzvt -e ssh --delete --progress ${PROJ_HOME}/*
tomcat@${HOST_DEPLOY}:${TC_HOME}/webapps/$proj_name/&lt;br /&gt;
ssh ${JSERVER_USER}@${HOST_DEPLOY} &amp;quot;JAVA_HOME=/srv/java/jdk
${TC_HOME}/${TC_INSTANCE}/bin/catalina.sh start&amp;quot;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Evidemment, il faudra copier sa clé publique SSH dans
/home/tomcat/.ssh/authorized_keys pour que les commandes d'arrêt et de
démarrage du serveur Tomcat soient exécutées de façon transparente sans avoir à
entrer les mots de passe à chaque fois. La commande ssh-copy-id (du moins sous
Debian) est appropriée. Sinon faire la copie à la main de votre clé publique
dans l'authorized_keys du serveur.&lt;br /&gt;
&lt;br /&gt;
Sous windows, si votre disque est par exemple D:,remplacez la ligne PROJ_HOME
par&lt;br /&gt;
&lt;code&gt;PROJ_HOME=/cygdrive/d/workspace/$proj_name/target/$proj_name&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Que fait ce script de déploiement ?&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;il arrête le serveur d'application distant grâce à SSH&lt;/li&gt;
&lt;li&gt;il compile et package l'appli avec Maven (sur le poste de
développement)&lt;/li&gt;
&lt;li&gt;il synchronise l'arborescence éclatée avec l'arborescence distante de
l'application; l'option --delete de rsync est importante car elle permet
d'éliminer les fichiers sur le serveur distant qui ont pu être supprimés lors
des modifications précédentes sur le code (suppressions de classe, de librairie
etc.)&lt;/li&gt;
&lt;li&gt;il redémarre le serveur d'application&lt;/li&gt;
&lt;/ol&gt;
Cette méthode présente plusieurs avantages :&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;si vous êtes derrière une ligne ADSL pour déployer vers un serveur distant,
vous gagnerez un temps précieux pour uploader votre application (upload parfois
100 fois supérieur puisque rsync ne transfère que les modifications entre
fichiers); en effet, vos librairies JAR ne changent pas beaucoup une fois le
projet initié et rsync verra qu'il n'y a pas besoin de les redéployer...
évidemment pour chaque nouveau fichier, le premier upload sera coûteux...&lt;/li&gt;
&lt;li&gt;le déploiement est propre car ceci arrête le serveur avant le déploiement;
le déploiement à chaud sur Tomcat entraîne généralement le bien connu
&amp;quot;OutOfMemoryError : PermGen Space&amp;quot;; certains diront que cette erreur peut être
évitée ( &lt;a hreflang=&quot;en&quot; href=&quot;http://jroller.com/agileanswers/entry/preventing_java_s_java_lang&quot;&gt;http://jroller.com/agileanswers/entry/preventing_java_s_java_lang&lt;/a&gt;
) mais parfois, on a pas le choix...&lt;/li&gt;
&lt;li&gt;les tâches sont toutes automatisées et le temps de déploiement est
sérieusement optimisé : -30% sur le packaging (x5 s'il n'y a pas à faire de
clean sur le projet), x10 à x100 sur le déploiement et votre serveur n'a pas
besoin de dézipper le WAR (en prime vous gagnez de l'espace puisque vous n'avez
plus de WAR sur le serveur cible)...&lt;/li&gt;
&lt;li&gt;le scripting apporte une flexibilité accrue notamment si vous avez à
déployer sur plusieurs instances et/ou serveurs à la fois dans le cadre d'un
cluster. Les options rsync permettent aussi d'exclure des fichiers que vous ne
voulez pas ou plus déployer, mais attention : ceci peut être dangereux pour
votre application si vous excluez des fichiers et que vous oubliez ensuite
qu'il faille les déployer de nouveau...&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
Dans cet exemple le déploiement est fait directement entre le poste de
développement et le serveur. Il se peut qu'en entreprise lorsque vous
travaillez à plusieurs sur le serveur distant, que ce dernier ait accès à un
repository Subversion ou GIT. Dans ce cas il suffit d'adapter le script pour
qu'il se trouve sur le serveur et que ce soit lui qui récupère des sources par
SVN (qui fonctionne par différence tout comme rsync!). Le script récupère alors
les sources, construit le projet, arrête le serveur d'appli (ou l'application),
déploie, redémarre le serveur d'appli (ou l'application).&lt;br /&gt;
Si l'on est dans un process d'intégration continue, on peut par exemple
utiliser &lt;a hreflang=&quot;en&quot; href=&quot;http://hudson-ci.org/&quot;&gt;Hudson&lt;/a&gt; auquel on
fournira un script shell réduit au déploiement (installer un plugin d'opération
post-build), le build étant gérée par &lt;a hreflang=&quot;en&quot; href=&quot;http://hudson-ci.org/&quot;&gt;Hudson&lt;/a&gt; en lui fournissant les options maven.&lt;br /&gt;
&lt;br /&gt;
Pour plus d'infos : &lt;a hreflang=&quot;en&quot; href=&quot;http://maven.apache.org/plugins/maven-war-plugin/&quot;&gt;http://maven.apache.org/plugins/maven-war-plugin/&lt;/a&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/05/03/Maven-optimiser-le-d%C3%A9ploiement-avec-un-WAR-%C3%A9clat%C3%A9#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/05/03/Maven-optimiser-le-d%C3%A9ploiement-avec-un-WAR-%C3%A9clat%C3%A9#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/513484</wfw:commentRss>
      </item>
    
  <item>
    <title>Comment mettre à jour une vieille Debian Sarge ?</title>
    <link>http://blog.guillaume-viel.com/post/2010/04/06/comment-mettre-%C3%A0-jour-une-vieille-Debian-Sarge</link>
    <guid isPermaLink="false">urn:md5:de32ed14a65faedae3372aeac91ad95a</guid>
    <pubDate>Tue, 06 Apr 2010 16:53:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>linux</category>
        <category>debian</category><category>linux</category>    
    <description>    &lt;p&gt;Souvent, lorsque ça marche bien, on ne touche à rien... Et puis le temps
passe, et la distribution Debian vieillit...&lt;/p&gt;
&lt;p&gt;Pour pouvoir mettre à jour une sarge il faut mettre comme nom de repository
&lt;strong&gt;archive.debian.org&lt;/strong&gt; au lieu de
&lt;strong&gt;ftp.debian.org&lt;/strong&gt;&lt;br /&gt;
(pour security je ne sais pas)&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/04/06/comment-mettre-%C3%A0-jour-une-vieille-Debian-Sarge#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/04/06/comment-mettre-%C3%A0-jour-une-vieille-Debian-Sarge#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/506525</wfw:commentRss>
      </item>
    
  <item>
    <title>Oracle native JDBC connection extractor</title>
    <link>http://blog.guillaume-viel.com/post/2010/04/01/Oracle-native-JDBC-connection-extractor</link>
    <guid isPermaLink="false">urn:md5:a0db00fc9747d8b75d8611f12c96ab9b</guid>
    <pubDate>Thu, 01 Apr 2010 20:00:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>java</category><category>jdbc</category><category>jee</category><category>oracle</category><category>Oracle Spatial</category><category>spring</category>    
    <description>&lt;p&gt;L'utilisation d'API Oracle Java, comme par exemple la SDO API (sdoapi.jar)
ou Oracle Network Modeling (sdonm.jar) pour gérer les graphes, nécessite
d'avoir une connexion native Oracle. Or les applications sont souvent
configurées avec un pool de connexions gérées par le conteneur JEE. Ceci pose
alors problème pour les opérations spécifiques qui nécessitent d'avoir une
connexion de type oracle.jdbc.OracleConnection et non une connexion de type
java.sql.Connection. Cette dernière ne pourra en effet pas être utilisée avec
les méthodes des API Oracle en Java.&lt;/p&gt;
&lt;p&gt;Il faut alors extraire la connexion native sous-jacente à la connexion du
pool de connexions.&lt;/p&gt;    &lt;h2&gt;Extraction d'une connexion native JDBC&lt;/h2&gt;
&lt;h3&gt;1) avec Spring&lt;/h3&gt;
Ceux qui utilisent Spring connaissent probablement le package
org.springframework.jdbc.support.nativejdbc qui contient des extracteurs de
connexion.&lt;br /&gt;
Voici par exemple comment récupérer une connexion native sous-jacente avec un
extracteur Spring :&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;import javax.sql.DataSource;&lt;br /&gt;
import java.sql.Connection;&lt;br /&gt;
import org.springframework.jdbc.datasource.DataSourceUtils;&lt;br /&gt;
import
org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor;&lt;br /&gt;
&lt;br /&gt;
DataSource dataSource = ... // récupération par JNDI par exemple et/ou injecté
par Spring&lt;br /&gt;
Connection conn = DataSourceUtils.getConnection(dataSource);&lt;br /&gt;
SimpleNativeJdbcExtractor extractor = new SimpleNativeJdbcExtractor();&lt;br /&gt;
OracleConnection oraConn = (OracleConnection)
extractor.getNativeConnection(conn);&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Généralement les applications conçues avec Spring gère généralement les
ressources base de données à haut niveau (niveau DataSource). La classe
utilitaire DataSourceUtils de Spring permet notamment de récupérer la connexion
sous-jacente à la DataSource. Ensuite, le SimpleNativeJdbcExtractor permet
d'extraire la connexion native en réalisant un &lt;q&gt;unwrap&lt;/q&gt; de la connexion du
pool. D'autres extracteurs existent dans ce package utilitaire de Spring, mais
malheureusement, cela ne fonctionne pas toujours.&lt;br /&gt;
&lt;h3&gt;2) sans Spring&lt;/h3&gt;
En effet, si vous avez un pool de connexion &lt;q&gt;fait maison&lt;/q&gt; il sera alors
beaucoup plus difficile d'utiliser les classes utilitaires Spring. Un autre cas
de figure est lorsque l'application doit pouvoir être déployée sur différents
conteneurs JEE, dont certains non identifiés par les outils Spring.&lt;br /&gt;
Dans certains cas, la méthode getMetadata() de l'objet Connection peut-être
utilisé directement pour récupérer la connexions native. Dans d'autres cas, il
faut utiliser la méthode getUnderlyingConnection() (pas toujours présente) pour
récupérer la connexion native (comme c'est le cas pour le wrapper JBoss).&lt;br /&gt;
Voici la classe utilitaire permettant de récupérer une connexion native Oracle
quelque soit le conteneur (pas testé partout) :&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;&lt;code&gt;package com.openfarm.util;&lt;br /&gt;
&lt;br /&gt;
import java.lang.reflect.Method;&lt;br /&gt;
import java.sql.Connection;&lt;br /&gt;
import java.sql.SQLException;&lt;br /&gt;
&lt;br /&gt;
import oracle.jdbc.OracleConnection;&lt;br /&gt;
&lt;br /&gt;
import org.apache.log4j.Logger;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Classe statique réalisant quasiment la même chose que la classe spring
suivante&lt;br /&gt;
 *
org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor&lt;br /&gt;
 * c'est à dire extraire la connection native sous-jacente d'un pool de
connexion.&lt;br /&gt;
 * La récupération à travers les metadata fonctionne avec la plupart des
pools de&lt;br /&gt;
 * connexion (JBoss 3.x, DBCP 1.x, Resin, etc.)&lt;br /&gt;
 * La récupération de la connexion native est parfois nécessaire notamment
pour&lt;br /&gt;
 * l'utilisation de l'API Network Data Model d'Oracle.&lt;br /&gt;
 * &lt;br /&gt;
 * @author guillaume viel at openfarm dot fr&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
public class OracleNativeJdbcExtractor {&lt;br /&gt;
   &lt;br /&gt;
    private static final Logger logger =
Logger.getLogger(OracleNativeJdbcExtractor.class);&lt;br /&gt;
   &lt;br /&gt;
    /**&lt;br /&gt;
     * Retourne la connexion native sous-jacente au pool de
connexion&lt;br /&gt;
     * @param poolConn La connexion du pool&lt;br /&gt;
     * @return Connection La connexion native&lt;br /&gt;
     * @throws SQLException&lt;br /&gt;
     */&lt;br /&gt;
    public static Connection getNativeConnection(Connection
poolConn) throws SQLException {&lt;br /&gt;
        Connection nativeConn = poolConn;&lt;br /&gt;
        if(poolConn != null) {&lt;br /&gt;
            nativeConn =
poolConn.getMetaData().getConnection();&lt;br /&gt;
            logger.info(poolConn +
&amp;quot; encapsulates [&amp;quot;+nativeConn+&amp;quot;]&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        return nativeConn;&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
    /**&lt;br /&gt;
     * Retourne la connexion native Oracle sous-jacente au
pool de connexion&lt;br /&gt;
     * @param poolConn La connexion du pool&lt;br /&gt;
     * @return OracleConnection La connexion Oracle
sous-jacente au pool&lt;br /&gt;
     * @throws SQLException&lt;br /&gt;
     */&lt;br /&gt;
    public static OracleConnection
getNativeOracleConnection(Connection poolConn) throws SQLException {&lt;br /&gt;
        OracleConnection oraConn = null;&lt;br /&gt;
        if(poolConn != null) {&lt;br /&gt;
            logger.debug(
poolConn.getClass().getName() ); // permet d'identifier le nom du wrapper&lt;br /&gt;
           &lt;br /&gt;
            try {&lt;br /&gt;
               
oraConn = (OracleConnection)poolConn.getMetaData().getConnection();&lt;br /&gt;
               
logger.info(poolConn + &amp;quot; wraps [&amp;quot; + oraConn + &amp;quot;]&amp;quot;);&lt;br /&gt;
            }
catch(ClassCastException e) {&lt;br /&gt;
                //
fonctionne par exemple avec le wrapper JBoss qui supporte la methode
getUnderlyingConnection&lt;br /&gt;
                try
{&lt;br /&gt;
               
    Method method =
poolConn.getClass().getDeclaredMethod(&amp;quot;getUnderlyingConnection&amp;quot;,
(Class[])null);&lt;br /&gt;
               
    if(method != null) {&lt;br /&gt;
               
        oraConn =
(OracleConnection)method.invoke(poolConn, (Object[])null);&lt;br /&gt;
               
        logger.info(poolConn + &amp;quot; encapsulates
[&amp;quot;+oraConn+&amp;quot;]&amp;quot;);&lt;br /&gt;
               
    }&lt;br /&gt;
                }
catch (Exception e1) {&lt;br /&gt;
               
    e1.printStackTrace();&lt;br /&gt;
               
}&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return oraConn;&lt;br /&gt;
    }&lt;br /&gt;
   &lt;br /&gt;
}&lt;/code&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/04/01/Oracle-native-JDBC-connection-extractor#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/04/01/Oracle-native-JDBC-connection-extractor#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/505192</wfw:commentRss>
      </item>
    
  <item>
    <title>ORA-04061 ô désespoir, ô variable ennemie</title>
    <link>http://blog.guillaume-viel.com/post/2010/03/30/Oracle-ora-04061-plsql-package</link>
    <guid isPermaLink="false">urn:md5:8d593e115959e401546b98baf7186935</guid>
    <pubDate>Tue, 30 Mar 2010 15:59:00 +0200</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>oracle</category>
        <category>database</category><category>oracle</category>    
    <description>&lt;p&gt;Que signifie l'exception ORACLE ORA-04061 ?&lt;/p&gt;
&lt;p&gt;Souhaitant rationaliser un projet de plusieurs milliers de lignes de PL/SQL,
j'ai rencontré cette exception lorsque nous avons mis en package les procédures
et fonctions. L'exception se présente comme suit :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ORA-04061: existing state of package &amp;quot;SCHEMA_REF.MON_PACKAGE&amp;quot; has been
invalidated&lt;br /&gt;
ORA-04065: not executed, altered or dropped package
&amp;quot;SCHEMA_REF.MON_PACKAGE&amp;quot;&lt;br /&gt;
ORA-06508: PL/SQL: could not find program unit being called:
&amp;quot;SCHEMA_REF.MON_PACKAGE&amp;quot;&lt;br /&gt;
ORA-04088: error during execution of trigger
'MON_SCHEMA.MON_TRIGGER'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;L'erreur est déroutante au premier abord car le package MON_PACKAGE, une
fois compilé, est tout à fait valide et il n 'y a a priori aucune erreur à la
compilation d'après ORACLE. Ce n'est qu'à la deuxième exécution (par un tiers)
que les problèmes surviennent. Alors que se passe-t-il exactement?&lt;/p&gt;    &lt;p&gt;Les packages peuvent être invalidés pour plusieurs raisons :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lorsque la spécification d'un package (une &amp;quot;spéc&amp;quot; de package correspond à
une interface en java) dont ils dépendent change ou a été supprimée&lt;/li&gt;
&lt;li&gt;lorsque la spécification du package dépend d'une table qui a été modifiée
ou supprimée&lt;/li&gt;
&lt;li&gt;lorsqu'il contient des variables globales de package&lt;/li&gt;
&lt;li&gt;lorsqu'il contient des exceptions au niveau du package&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il est donc dangereux en production de modifier des spécifications de
package, à moins de pouvoir &lt;a hreflang=&quot;en&quot; href=&quot;http://www.oracle-base.com/articles/misc/RecompilingInvalidSchemaObjects.php&quot;&gt;recompiler
en masse tous les packages&lt;/a&gt; impliqués. Cela peut suffire pour les 2
premières causes d'invalidation du package. Mais les deux dernières causes sont
plus problématiques.&lt;/p&gt;
&lt;p&gt;Voici les spécs de notre package avec notamment une constante, une variable
globale et une exception.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CREATE OR REPLACE PACKAGE SCHEMA_REF.MON_PACKAGE AS&lt;br /&gt;
--&lt;br /&gt;
RAD_TO_DEG    CONSTANT NUMBER := 180 / ( ATAN(1) * 4 );&lt;br /&gt;
MA_VARIABLE_GLOBALE      NUMBER := 0;&lt;br /&gt;
EXCEPTION e_mon_exception;&lt;br /&gt;
--&lt;br /&gt;
FUNCTION MA_FONCTION_RIGHT(vString VARCHAR2, vLength NUMBER) RETURN
VARCHAR2;&lt;br /&gt;
PROCEDURE MA_PROC();&lt;br /&gt;
END;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Cette spécification de package provoquera immanquablement l'erreur ORA-04061
car les variables et constantes au niveau package font partie de l'ETAT du
package. Si cet état change, comme par exemple la modification de la valeur de
MA_VARIABLE_GLOBALE par une procédure ou fonction, Oracle considère que les
spécifications du package sont changées! Ce qui est normal car si 2
utilisateurs créent 2 sessions en parallèle : on a une concurrence potentielle
au niveau des variables d'état du package. Oracle met alors le package en
statut invalide.&lt;br /&gt;
Le problème est le même pour les exceptions qui sont en fait des objets
potentiellement modifiables au cours de la session d'un utilisateur, provoquant
ainsi l'invalidation d'un package.&lt;/p&gt;
&lt;p&gt;Pour mieux structurer un projet PL/SQL, la seule option est de placer toutes
les constantes dans un package ne contenant que des spécifications de
constantes. Il est impossible d'isoler et regrouper les exceptions dans un
package de spécifications, ni dans l'entête d'un package : toutes les
exceptions doivent être gérées à l'intérieur des fonctions et procédures, ce
qui représente un travail d'uniformisation et normalisation important. C'est un
point faible pour maintenir convenablement des applications PL/SQL.&lt;br /&gt;
&lt;br /&gt;
Ces deux articles expliquent bien le problème (mis à part qu'il ne parlent pas
du cas des EXCEPTION) :&lt;/p&gt;
&lt;p&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://kr.forums.oracle.com/forums/thread.jspa?threadID=903490&quot;&gt;http://kr.forums.oracle.com/forums/thread.jspa?threadID=903490&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://oraclequirks.blogspot.com/2007/03/ora-04061-existing-state-of-package-has.html&quot;&gt;
http://oraclequirks.blogspot.com/2007/03/ora-04061-existing-state-of-package-has.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ce dernier article explique comment recompiler en masse ou
programmatiquement des objets dans Oracle :&lt;/p&gt;
&lt;p&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://www.oracle-base.com/articles/misc/RecompilingInvalidSchemaObjects.php&quot;&gt;http://www.oracle-base.com/articles/misc/RecompilingInvalidSchemaObjects.php&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/03/30/Oracle-ora-04061-plsql-package#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/03/30/Oracle-ora-04061-plsql-package#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/504175</wfw:commentRss>
      </item>
    
  <item>
    <title>FreeNAS Cannot dump. No dump device defined</title>
    <link>http://blog.guillaume-viel.com/post/2010/03/27/FreeNAS-Cannot-dump-No-dump-device-defined</link>
    <guid isPermaLink="false">urn:md5:f09f9c68bcbd199dc58745e641d67faa</guid>
    <pubDate>Sat, 27 Mar 2010 15:47:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>FreeNAS</category>
        <category>FreeNAS</category><category>sysadmin</category>    
    <description>&lt;p&gt;Lors de la réinstallation de FreeNAS 0.69.2 (downgrade depuis la version
0.7.1) sur carte flash j'obtiens ça :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Cannot dump. No dump device defined.&lt;br /&gt;
Automatic reboot in 15 seconds - press a key on the console to abort&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Beuh... En fait il s'avère qu'il faille démarrer en mode &lt;q&gt;no ACPI&lt;/q&gt; sur
le premier menu de démarrage. Le problème est : comment automatiser le
démarrage pour que ce soit toujours l'option 2 du boot qui soit prise en
compte?&lt;/p&gt;    Le premier élément de réponse est le suivant :&lt;br /&gt;
&lt;dl class=&quot;codebox&quot;&gt;
&lt;dd&gt;&lt;code&gt;hint.acpi.0.disabled=&amp;quot;1&amp;quot;&lt;/code&gt;&lt;/dd&gt;
&lt;/dl&gt;
serait à mettre dans le fichier /cf/boot/loader.conf&lt;br /&gt;
Qu'à cela ne tienne, me voilà déjà parti pour modifier le fameux fichier...
mais...&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;/cf/boot/loader.conf: Read-only file system.&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Eh oui! La carte flash est montée en read-only comme le montre la fstab&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
freenas:~# cat /etc/fstab&lt;br /&gt;
/dev/ad4a /cf ufs ro 1 1&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Il suffit donc de :&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;remonter la partition en rw avec mount :&lt;br /&gt;
&lt;code&gt;mount -u -o rw /dev/ad4a /cf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dans /cf/boot/loader.conf ajouter la ligne&lt;br /&gt;
&lt;code&gt;hint.acpi.0.disabled=&amp;quot;1&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;rebooter pour vérifier que tout est OK&lt;/li&gt;
&lt;/ul&gt;
Normalement, le serveur devrait booter correctement sans aucune intervention
manuelle pour désactiver l'ACPI.&lt;br /&gt;
&lt;br /&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/03/27/FreeNAS-Cannot-dump-No-dump-device-defined#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/03/27/FreeNAS-Cannot-dump-No-dump-device-defined#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/502997</wfw:commentRss>
      </item>
    
  <item>
    <title>FreeNAS versions 0.7 et 0.7.1 : impossible de monter un volume NFS</title>
    <link>http://blog.guillaume-viel.com/post/2010/03/26/FreeNAS-versions-0.7-et-0.7.1-%3A-impossible-de-monter-un-volume-NFS</link>
    <guid isPermaLink="false">urn:md5:12529e48fe6ead209433793837439c26</guid>
    <pubDate>Fri, 26 Mar 2010 23:15:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>FreeNAS</category>
        <category>debian</category><category>FreeNAS</category><category>sysadmin</category>    
    <description>    &lt;p&gt;Décidément, pas de chance en ce moment... Cascade de bugs... Faut dire que
je le cherche un peu, en étant sous Debian SID. Mais là, c'est pas Debian! Nous
avons mis à jour notre serveur NAS avec la dernière version de FreeNAS et
apparemment quelques soucis sur les montages NFS. En effet, une tentative de
connexion donne le message suivant :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mount.nfs: mount to NFS server failed: timed out, giving up&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Yuk! Après avoir vérifié le ping, que tous les ports étaient ouverts, une
petite trace avec wireshark m'a permis de constater qu'un échange avait bien
lieu mais que la connexion entre le client et le serveur n'aboutissait pas. Et
il semblerait que je ne sois pas le seul à avoir ce problème vu ce bug sur le
bug tracker de FreeNAS&lt;/p&gt;
&lt;p&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://sourceforge.net/tracker/?func=detail&amp;amp;aid=2812161&amp;amp;group_id=151951&amp;amp;atid=782616&quot;&gt;
http://sourceforge.net/tracker/?func=detail&amp;amp;aid=2812161&amp;amp;group_id=151951&amp;amp;atid=782616&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;La meilleure parade est de revenir à la version 0.69.2 en attendant
mieux.&lt;/strong&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/03/26/FreeNAS-versions-0.7-et-0.7.1-%3A-impossible-de-monter-un-volume-NFS#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/03/26/FreeNAS-versions-0.7-et-0.7.1-%3A-impossible-de-monter-un-volume-NFS#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/502861</wfw:commentRss>
      </item>
    
  <item>
    <title>rsnapshot : module Lchown manquant</title>
    <link>http://blog.guillaume-viel.com/post/2010/03/25/module-Lchown-manquant-pour-rsnapshot</link>
    <guid isPermaLink="false">urn:md5:589b67a30158642747473243f64f229f</guid>
    <pubDate>Thu, 25 Mar 2010 23:37:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>linux</category>
        <category>debian</category><category>linux</category>    
    <description>&lt;p&gt;Nous utilisons rsnapshot pour réaliser nos sauvegardes. En le résinstallant
sur une machine je remarque sur le log de sauvegarde le message suivant :&lt;/p&gt;
&lt;code&gt;require Lchown&lt;br /&gt;
Lchown module not found&lt;/code&gt;    &lt;p&gt;En fait il manque tout simplement le module PERL Lchown (avec il manque
YAML)!&lt;/p&gt;
&lt;p&gt;Pour l'importer, taper ceci (connexion internet obligatoire) :&lt;/p&gt;
&lt;code&gt;perl -MCPAN -e 'install qw(YAML)'&lt;br /&gt;
perl -MCPAN -e 'install qw(Lchown)'&lt;/code&gt;
&lt;p&gt;Une fois ces librairies PERL installées, rsnapshot ne se plaint plus sur les
&lt;q&gt;chown&lt;/q&gt;.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/03/25/module-Lchown-manquant-pour-rsnapshot#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/03/25/module-Lchown-manquant-pour-rsnapshot#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/502628</wfw:commentRss>
      </item>
    
  <item>
    <title>linux debian squeeze : bug sur la configuration PAM pour CRON</title>
    <link>http://blog.guillaume-viel.com/post/2010/03/25/debian-squeeze-%3A-bug-sur-la-configuration-PAM-pour-CRON</link>
    <guid isPermaLink="false">urn:md5:bc55b1a599c3c1742cee4a457656bf51</guid>
    <pubDate>Thu, 25 Mar 2010 00:37:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>linux</category>
        <category>debian</category><category>linux</category><category>sysadmin</category>    
    <description>&lt;p&gt;La programmation de tâches par CRON peut se faire de différentes façon, et
notamment par l'intermédiaire de fichiers de configuration situés dans
/etc/cron.d&lt;/p&gt;
&lt;p&gt;En voulant programmer des tâches de sauvegarde rsnapshot avec cron, je
constate l'erreur suivante dans mon /var/log/syslog&lt;/p&gt;
&lt;p&gt;Mar 24 23:04:01 myhost CRON[8435]: Erreur critique - abandon immédiat&lt;br /&gt;
Mar 24 23:04:01 myhost CRON[8435]: PAM pam_end: NULL pam handle passed&lt;/p&gt;
&lt;p&gt;ou pour la version originale&lt;/p&gt;
&lt;p&gt;Mar 24 23:04:01 myhost CRON[8435]: Critical error - immediate abort&lt;br /&gt;
Mar 24 23:04:01 myhost CRON[8435]: PAM pam_end: NULL pam handle passed&lt;/p&gt;
&lt;p&gt;Que se passe-t-il ?&lt;/p&gt;    &lt;p&gt;Le problème vient de la configuration de la librairie PAM qui sert
d'interface entre les applications et le système pour la gestion des
authentifications / autorisations.&lt;/p&gt;
&lt;p&gt;Mais celui ne correspond pas à ce que j'ai dans ma debian squeeze. Voici le
contenu du fichier /etc/pam.d/cron :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;#&lt;br /&gt;
# The PAM configuration file for the cron daemon&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
@include common-auth&lt;br /&gt;
session       required  
pam_env.so&lt;br /&gt;
@include common-account&lt;br /&gt;
@include common-session-noninteractive&lt;br /&gt;
# Sets up user limits, please define limits for cron tasks&lt;br /&gt;
# through /etc/security/limits.conf&lt;br /&gt;
session    required   pam_limits.so&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;En analysant chaque ligne d'@include qui correspond à l‘inclusion d'un
fichier dans /etc/pam.d on constate que le fichier
/etc/pam.d/common-session-noninteractive n'existe pas! Seul le fichier
common-session est présent. J'ai donc remplacé comme suit et tout fonctionne
:&lt;/p&gt;
&lt;code&gt;&lt;code&gt;&lt;strong&gt;@include common-session&lt;/strong&gt;&lt;/code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Je ne sais pas si c'est la bonne solution, mais ça a le mérite de refaire
fonctionner cron!&lt;br /&gt;
&lt;br /&gt;
Le rapport de bug est ici :&lt;br /&gt;
&lt;a hreflang=&quot;en&quot; href=&quot;http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=575342&quot;&gt;http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=575342&lt;/a&gt;&lt;br /&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/03/25/debian-squeeze-%3A-bug-sur-la-configuration-PAM-pour-CRON#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/03/25/debian-squeeze-%3A-bug-sur-la-configuration-PAM-pour-CRON#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/502354</wfw:commentRss>
      </item>
    
  <item>
    <title>Configuration d'un pool de connexions JDBC avec Oracle RAC</title>
    <link>http://blog.guillaume-viel.com/post/2010/03/24/Configuration-d-un-pool-de-connexion-JDBC-avec-Oracle-RAC</link>
    <guid isPermaLink="false">urn:md5:b137f866fa0cdda9dca066557ce11825</guid>
    <pubDate>Wed, 24 Mar 2010 18:37:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>java</category><category>jdbc</category><category>jee</category><category>Oracle RAC</category><category>tomcat</category>    
    <description>    &lt;p&gt;La documentation &lt;a hreflang=&quot;en&quot; href=&quot;http://download.oracle.com/docs/cd/B19306_01/java.102/b14355/fstconfo.htm&quot;&gt;Oracle
FCF (Fast Connection Failover)&lt;/a&gt; pour configurer un pool de connexion JDBC
avec un cluster Oracle RAC 10g est plutôt obscure et manque d'exemple...&lt;/p&gt;
&lt;p&gt;Après quelques tâtonnements et en fouillant un peu, voici une configuration
sous Tomcat à mettre dans le context.xml de l'application web ou dans
server.xml (déconseillé sauf en ressource globale) qui semble plaire à Oracle
:&lt;/p&gt;
&lt;p&gt;    &lt;code&gt;&amp;lt;Resource name=&amp;quot;jdbc/myRacDb&amp;quot;
auth=&amp;quot;Container&amp;quot;&lt;br /&gt;
           
type=&amp;quot;oracle.jdbc.pool.OracleDataSource&amp;quot;&lt;br /&gt;
           
factory=&amp;quot;oracle.jdbc.pool.OracleDataSourceFactory&amp;quot;&lt;br /&gt;
           
description=&amp;quot;My Oracle RAC DB&amp;quot;&lt;br /&gt;
           
user=&amp;quot;myschema&amp;quot; password=&amp;quot;mypass&amp;quot;&lt;br /&gt;
           
url=&amp;quot;jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=rac1.mydomain.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=rac2.mydomain.com)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=myservice.mydomain.com)))&amp;quot;&lt;br /&gt;

           
driverClassName=&amp;quot;oracle.jdbc.OracleDriver&amp;quot;&lt;br /&gt;
           
maxActive=&amp;quot;10&amp;quot;&lt;br /&gt;
           
maxIdle=&amp;quot;5&amp;quot;&lt;br /&gt;
           
minIdle=&amp;quot;2&amp;quot;&lt;br /&gt;
           
maxWait=&amp;quot;5000&amp;quot;&lt;br /&gt;
           
connectionCacheName=&amp;quot;myCache&amp;quot;&lt;br /&gt;
           
connectionCachingEnabled=&amp;quot;true&amp;quot;&lt;br /&gt;
           
fastConnectionFailoverEnabled=&amp;quot;true&amp;quot;&lt;br /&gt;
           
onsConfigStr=&amp;quot;nodes=rac1.mydomain.com:4200,rac2.mydomain.com:4200&amp;quot;&lt;br /&gt;
           
connectionProperties=&amp;quot;oracle.jdbc.ReadTimeout=30000&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Cette datasource est accessible via le JNDI sous le nom
&lt;code&gt;java:comp/env/jdbc/myRacDb&lt;/code&gt; (sous Tomcat).&lt;/p&gt;
&lt;p&gt;Le cluster Oracle RAC est ici composé de 2 noeuds rac1.mydomain.com et
rac2.mydomain.com. On travaille avec un driver Oracle &lt;q&gt;thin&lt;/q&gt;.&lt;/p&gt;
&lt;p&gt;Sous tomcat, il faut mettre la &lt;a hreflang=&quot;en&quot; href=&quot;http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc_10201.html&quot;&gt;
librairie Oracle JDBC ons.jar (Oracle Notification Services)&lt;/a&gt; dans le
common/lib (du moins sous tomcat 5) avec les autres librairies Oracle
(ojdbc14.jar et orai18n.jar notamment).&lt;/p&gt;
&lt;p&gt;Afin de ne pas avoir d'ennuis, il est obligatoire de mettre l'attribut nodes
dans l'onsConfigString et préférable qu'il soit à l'identique de la
configuration Oracle (pour cela une bonne communication avec votre DBA est
nécessaire).&lt;/p&gt;
&lt;p&gt;Nous avons surtout tâtonné pour trouver le type et la factory car la
documentation n'est pas orienté tomcat mais plutôt grand serveurs
d'applications commerciaux (je vous laisse deviner lesquels!).&lt;/p&gt;
&lt;p&gt;Si vous faites des déploiements à chaud sur Tomcat (déconseillé) il est
préférable d'enlever le &lt;q&gt;connectionCacheName&lt;/q&gt; pour éviter que Tomcat se
plaigne de l'existence d'un cache portant le même nom (apparemment pas de
nettoyage à chaud!) : vous serez alors obligé de redémarrer votre serveur
Tomcat.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/03/24/Configuration-d-un-pool-de-connexion-JDBC-avec-Oracle-RAC#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/03/24/Configuration-d-un-pool-de-connexion-JDBC-avec-Oracle-RAC#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/502162</wfw:commentRss>
      </item>
    
  <item>
    <title>Git : un SCM (Source Code Management) qui vaut le détour</title>
    <link>http://blog.guillaume-viel.com/post/2010/03/15/Git-%3A-un-SCM-%28Source-Code-Management%29-qui-vaut-le-d%C3%A9tour</link>
    <guid isPermaLink="false">urn:md5:60715218b8b7ae5874f9d4bcc9036d83</guid>
    <pubDate>Mon, 15 Mar 2010 14:39:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>java / j2ee</category>
        <category>git</category><category>linux</category><category>SCM</category>    
    <description>    &lt;p&gt;Un peu déçu par SVN, nous nous sommes mis à la recherche d'un nouveau
système &lt;a hreflang=&quot;en&quot; href=&quot;http://en.wikipedia.org/wiki/Source_Code_Management&quot;&gt;SCM&lt;/a&gt; ou de
&lt;a hreflang=&quot;fr&quot; href=&quot;http://fr.wikipedia.org/wiki/Gestion_de_versions&quot;&gt;Gestion de Version&lt;/a&gt; .
Notre futur &lt;a hreflang=&quot;en&quot; href=&quot;http://en.wikipedia.org/wiki/Source_Code_Management&quot;&gt;SCM&lt;/a&gt; sera très
probablement &lt;a hreflang=&quot;fr&quot; href=&quot;http://fr.wikipedia.org/wiki/Git&quot;&gt;GIT&lt;/a&gt;.
L'article suivant permet de bien débuter sur &lt;a hreflang=&quot;en&quot; href=&quot;http://en.wikipedia.org/wiki/Git_%28software%29&quot;&gt;GIT&lt;/a&gt; : &lt;a hreflang=&quot;fr&quot; href=&quot;http://www.unixgarden.com/index.php/administration-systeme/git-it&quot;&gt;http://www.unixgarden.com/index.php/administration-systeme/git-it&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/03/15/Git-%3A-un-SCM-%28Source-Code-Management%29-qui-vaut-le-d%C3%A9tour#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/03/15/Git-%3A-un-SCM-%28Source-Code-Management%29-qui-vaut-le-d%C3%A9tour#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/499545</wfw:commentRss>
      </item>
    
  <item>
    <title>Comment changer une extension de fichier en bash (utilisation des substitutions en bash)</title>
    <link>http://blog.guillaume-viel.com/post/2010/03/15/Comment-changer-une-extension-de-fichier-en-bash-%28utilisation-des-substitutions-en-bash%29</link>
    <guid isPermaLink="false">urn:md5:c1883c31f53a5f922449df8bb98f7685</guid>
    <pubDate>Mon, 15 Mar 2010 14:31:00 +0100</pubDate>
    <dc:creator>guillaume</dc:creator>
        <category>linux</category>
            
    <description>    &lt;p&gt;Pour éviter des sed dans tous les sens, on oublie souvent les substitutions
qui couvrent un majorité des besoins pour traiter les noms de fichier :&lt;br /&gt;
&lt;a hreflang=&quot;fr&quot; href=&quot;http://djmathos2.free.fr/joomla/index.php/astuceslinux/67-changer-lextension-dun-fichier-en-shell-bash&quot;&gt;
http://djmathos2.free.fr/joomla/index.php/astuceslinux/67-changer-lextension-dun-fichier-en-shell-bash&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.guillaume-viel.com/post/2010/03/15/Comment-changer-une-extension-de-fichier-en-bash-%28utilisation-des-substitutions-en-bash%29#comment-form</comments>
      <wfw:comment>http://blog.guillaume-viel.com/post/2010/03/15/Comment-changer-une-extension-de-fichier-en-bash-%28utilisation-des-substitutions-en-bash%29#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.guillaume-viel.com/feed/atom/comments/499536</wfw:commentRss>
      </item>
    
</channel>
</rss>
