<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
<channel>
  <title>viv's blog</title>
  <link>http://blog.aperigeek.com/viv/</link>
      
    <description />
  <language>en-us</language>
  <copyright>Copyright 2009</copyright>
  <lastBuildDate>Tue, 20 Oct 2009 12:12:33 +0100</lastBuildDate>
  <generator>Apache Roller (incubating) 4.0 (20071120033321:dave)</generator>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/vivblog" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/charger_partiellement_une_entit%C3%A9_en</guid>
    <title>Charger partiellement une entité avec JPA</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/hRfDWPKCiBw/charger_partiellement_une_entit%C3%A9_en</link>
        <pubDate>Fri, 21 Aug 2009 17:24:13 +0100</pubDate>
    <category>Java</category>
    <category>javaee</category>
    <category>jpaql</category>
    <category>ejb</category>
    <category>jpa</category>
    <category>ejbql</category>
    <category>java</category>
            <description>Il est intéressant, dans nombre de cas, de ne charger que partiellement une entité en JPA. Prennons l'exemple de &lt;a href="http://jtentative.kenai.com/"&gt;JTentative&lt;/a&gt;, un agrégateur de flux RSS. Il est souhaitable de charger la liste des entrées appartenant à un flux, mais sans forcément charger l'intégralité de chaque entité (contenu et description sont des champs lourds et souvent inutilisés).&lt;br /&gt;
&lt;br /&gt;

Plusieurs solutions existent pour charger partiellement une entité, de ne sélectionner que certains champs à charger depuis la base de données.&lt;br /&gt;
&lt;br /&gt;

&lt;h2&gt;Première solution : &lt;code&gt;FetchType.LAZY&lt;/code&gt;&lt;/h2&gt;

La première solution consiste à définir certains champs de notre entité avec un attribut &lt;code&gt;fetch&lt;/code&gt; à &lt;code&gt;LAZY&lt;/code&gt;. Cela permet de spécifier que ces champs ne sont pas chargés lors du chargement de l'entité, mais uniquement lors du premier accès à ce champ.&lt;br /&gt;
&lt;br /&gt;

L'annotation &lt;code&gt;@Basic&lt;/code&gt; nous permet de spécifier ce lazy-loading.&lt;br /&gt;
&lt;br /&gt;

Voici un exemple de code mettant en avant cette annotation. Le code de l'entité à été réduit pour plus de lisibilité :&lt;br /&gt;
&lt;pre name="code" class="java"&gt;
@Entity
public class Entry implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String title;

    private String author;

    @Lob
    @Basic(fetch=FetchType.LAZY)
    private String description;

    @Lob
    @Basic(fetch=FetchType.LAZY)
    private String content;

    /* Getters, Setters... */
}
&lt;/pre&gt;
&lt;br /&gt;

Cette solution présente cependant un inconvénient majeur : si elle fonctionne correctement lorsque l'on charge une entité via l'&lt;code&gt;EntityManager&lt;/code&gt;, elle est complètement inefficace lors de la sélection de données via une requête JPA-QL.

&lt;h2&gt;Seconde solution : Sélectionner uniquement les champs dont on a besoin&lt;/h2&gt;

Une seconde solution peut-être mise en place dans une requête JPA-QL. Cependant, elle ne fonctionnera paslors de la sélection lors d'un appel à la méthode &lt;code&gt;find()&lt;/code&gt; de l'&lt;code&gt;EntityManager&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;

Cette solution est basée sur un opérateur méconnu du langage JPA-QL, &lt;code&gt;new&lt;/code&gt;. L'opérateur &lt;code&gt;new&lt;/code&gt; permet d'intancier des objets au sein d'une requête JPA-QL. Il s'agit donc d'instancier un objet, en fournissant au constructeur uniquement les champs que nous souhaitons récupérer.&lt;br /&gt;
&lt;br /&gt;

Voici un autre exemple, le code de l'entité a là aussi été réduit :
&lt;pre name="code" class="java"&gt;
@Entity
@NamedQuery(name="Entry.findAll", query="SELECT new Entry(e.id, e.title, e.author) FROM Entry AS e")
public class Entry implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String title;

    private String author;

    @Lob
    @Basic(fetch=FetchType.LAZY)
    private String description;

    @Lob
    @Basic(fetch=FetchType.LAZY)
    private String content;

    public Entry() {
    }

    public Entry(Long id, String title, String author) {
        this.id = id;
        this.title = title;
        this.author = author;
    }

    /* Getters, Setters... */
}
&lt;/pre&gt;
&lt;br /&gt;

Quelques précisions cependant :
&lt;ul&gt;
    &lt;li&gt;Il faut préciser la classe &lt;em&gt;complète&lt;/em&gt; de l'entité dans la requête, incluant le nom du package&lt;/li&gt;
    &lt;li&gt;Le constructeur que l'on souhaite invoquer doit exister&lt;/li&gt;
    &lt;li&gt;Prennez garde avec vos entités chargées de cette manière : certaines propriétés sont absentes, une mise à jour dans la base de données avec une entité chargée partiellement risque d'effacer certaines valeurs&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;

Le code complet de l'entité utilisée pour cette exemple est disponible sur le &lt;a href="http://kenai.com/projects/jtentative/sources/main/content/trunk/jtentative/jtentative-ejb/src/main/java/com/aperigeek/jtentative/entity/Entry.java?rev=23"&gt;dépôt SVN de JTentative&lt;/a&gt;.</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/charger_partiellement_une_entit%C3%A9_en</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/aperiquiz_4_integer_equals_integer</guid>
    <title>Aperiquiz #4 : Integer equals Integer</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/Ls_ItkdL15c/aperiquiz_4_integer_equals_integer</link>
        <pubDate>Tue, 21 Jul 2009 21:04:06 +0100</pubDate>
    <category>Java</category>
    <category>integer</category>
    <category>equals</category>
    <category>java</category>
    <category>aperiquiz</category>
            <description>Soit le code suivant :&lt;br /&gt;
&lt;textarea name="code" class="java"&gt;
public class Main {

    public static void main(String[] args) {
        Integer a = new Integer(1024);
        Integer b = new Integer(1024);
        boolean c = a &lt; b || a == b || a &gt; b;
        System.out.println(c);
    }

}
&lt;/textarea&gt;&lt;br /&gt;
&lt;br /&gt;

Quel est la valeur de &lt;code&gt;c&lt;/code&gt; ?
&lt;ul&gt;
    &lt;li&gt;&lt;code&gt;true&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;false&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;Erreur de compilation&lt;/li&gt;
    &lt;li&gt;Une exception est levée lors de l'exécution&lt;/li&gt;
&lt;/ul&gt;

Réponse : (&lt;a href="#aperiquiz-answer4" name="aperiquiz-answer4" onclick="document.getElementById('aperiquiz-answer4').style.display='block';"&gt;cliquez pour afficher&lt;/a&gt;)
&lt;blockquote id="aperiquiz-answer4" style="border: 1px solid black; display: none;"&gt;
En utilisant Java 5 : &lt;code&gt;false&lt;/code&gt;.&lt;br /&gt;
En utilisant Java 1.4 : Erreur de compilation.&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Explication :&lt;/h3&gt;
Le cas de Java 1.4 est certainement le plus simple à expliquer : nous avons deux objets de type Integer, et il est impossible de comparer des objets avec les opérateurs &lt;code&gt;&amp;lt;&lt;/code&gt; et &lt;code&gt;&amp;gt;&lt;/code&gt;. En Java 1.4, l'autoboxing n'existe pas.&lt;br /&gt;
&lt;br /&gt;

Concernant Java 5, l'explication est plus profonde. Nos objets de type Integer sont automatiquement transformés en &lt;code&gt;int&lt;/code&gt; dès que nécessaire. C'est le cas lors des comparaisons en utilisant les opérateurs &lt;code&gt;&amp;lt;&lt;/code&gt; et &lt;code&gt;&amp;gt;&lt;/code&gt;. Ces deux comparaisons renvoient donc &lt;code&gt;false&lt;/code&gt;. Cependant, lors de la comparaison avec l'opérateur &lt;code&gt;==&lt;/code&gt;, nos objets ne sont pas convertis en &lt;code&gt;int&lt;/code&gt;, mais leur &lt;strong&gt;références&lt;/strong&gt; sont comparées. &lt;code&gt;a&lt;/code&gt; et &lt;code&gt;b&lt;/code&gt; étant deux objets distincts, la comparaison avec &lt;code&gt;==&lt;/code&gt; renvoie &lt;code&gt;false&lt;/code&gt;. D'où la valeur de &lt;code&gt;c&lt;/code&gt;.

&lt;/blockquote&gt;</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/aperiquiz_4_integer_equals_integer</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/types_primitifs_pi%C3%A8ges_courants</guid>
    <title>Types primitifs : pièges courants</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/Mxa3l_jEeUY/types_primitifs_pi%C3%A8ges_courants</link>
        <pubDate>Wed, 8 Jul 2009 20:21:48 +0100</pubDate>
    <category>Java</category>
    <category>piege</category>
    <category>type</category>
    <category>primitif</category>
    <category>java</category>
            <description>&lt;em&gt;It's a trap&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;

Je viens de tomber dans la soirée sur deux pièges, non triviaux, mais facile à éviter pour peu de les connaître...&lt;br /&gt;
&lt;br /&gt;

&lt;h2&gt;27/10 != 2.7&lt;/h2&gt;

Le premier bout de code ressemblait à celui-ci :
&lt;pre name="code" class="java"&gt;
public class Main {

    public static void main(String... args) {
        float price = 27/10;
        System.out.println("Price: " + price);
    }

}
&lt;/pre&gt;
&lt;br /&gt;

Alors qu'il est facile de penser que le code suivant va afficher "Price: 2.70" lors de l'exécution, la réalité est tout autre. Effectivement, le résultat une fois ce code compilé / exécuté est "Price: 2.00".&lt;br /&gt;
&lt;br /&gt;

Le piège est le suivant :
&lt;ul&gt;
    &lt;li&gt;27 est, en Java, un entier&lt;/li&gt;
    &lt;li&gt;10 est, toujours en Java, un entier&lt;/li&gt;
    &lt;li&gt;L'opération 27/10 est la division de deux entiers. Pour la JVM, le résultat est donc un entier. Donc 2.&lt;/li&gt;
    &lt;li&gt;La valeur 2 est assignée à une variagle de type &lt;code&gt;float&lt;/code&gt;, la valeur 2 est transformée en 2.00&lt;/li&gt;
    &lt;li&gt;La valeur 2.00 est affichée dans la console.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

Il est facile de contourner ce problème : transformer notre division d'entier en division de nombre flottants :
&lt;pre name="code" class="java"&gt;
public class Main {

    public static void main(String... args) {
        float price = 27.0/10.0;
        System.out.println("Price: " + price);
    }

}
&lt;/pre&gt;
&lt;br /&gt;

Dans ce bloc de code, 27.0 et 10.0 sont des nombres à virgule flottante. La division des deux donne une nombre à virgule flottante, donc 2.7. Et le résultat est donc celui attendu.

&lt;h2&gt;&lt;code&gt;return (int) 2.7 - 2.4;&lt;/code&gt;&lt;/h2&gt;

Le second bloc de code piégé consistait à comparer deux entiers :
&lt;pre name="code" class="java"&gt;
public class FloatComparator implements Comparator&amp;eacute;Float&gt; {

    public int compare(Float f1, Float f2) {
        return (int) (f2 - f1);
    }

}
&lt;/pre&gt;
&lt;br /&gt;

A première vue, ce code semble lui aussi entièrement correct. Le raisonnement suivi est celui-ci :
&lt;ul&gt;
    &lt;li&gt;Si je renvoie le résultat de &lt;code&gt;f2 - f1&lt;/code&gt;, mon objet triera des nombres par ordre croissant&lt;/li&gt;
    &lt;li&gt;La méthode &lt;code&gt;compare&lt;/code&gt; doit renvoyer un entier&lt;/li&gt;
    &lt;li&gt;Je caste le résultat de ma soustraction (un &lt;code&gt;float&lt;/code&gt;) en &lt;code&gt;int&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

Ce code fonctionne &lt;strong&gt;presque&lt;/strong&gt; tout le temps. Le problème tiens dans le presque... Pour comprendre où est le problème, rien ne vaut une simulation :
&lt;ul&gt;
    &lt;li&gt;Je souhaite comparer 2.7 et 2.8&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;2.8 - 2.7&lt;/code&gt; renvoie 0.1, un nombre positif, donc je respecte le contrat de la méthode &lt;code&gt;compare&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;0.1 est casté en &lt;code&gt;int&lt;/code&gt;, le résultat est 0 alors que f2 est suppérieur a f1, je ne respecte plus le contrat de ma méthode&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

L'erreur se trouve dans le cast. Il faut donc effectuer un changement dans notre méthode pour renvoyer un nombre positif dans tous les cas où &lt;code&gt;f2&lt;/code&gt; est suppérieur à &lt;code&gt;f1&lt;/code&gt;. Par exemple :
&lt;pre name="code" class="java"&gt;
public class FloatComparator implements Comparator&amp;eacute;Float&gt; {

    public int compare(Float f1, Float f2) {
        if (f2 &gt; f1) {
            return 1;
        }
        if (f1 &lt; f2) {
            return -1;
        }
        return 0;
    }

}
&lt;/pre&gt;

&lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Comparator.html#compare(T,%20T)"&gt;Le contrat&lt;/a&gt; de &lt;code&gt;Comparator&lt;/code&gt; est maintenant respecté.</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/types_primitifs_pi%C3%A8ges_courants</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/aperiquiz_3_param%C3%A8tres_de_m%C3%A9thodes</guid>
    <title>Aperiquiz #3 : Paramètres de méthodes</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/uEj7Gst4d2U/aperiquiz_3_param%C3%A8tres_de_m%C3%A9thodes</link>
        <pubDate>Tue, 17 Feb 2009 14:10:33 +0100</pubDate>
    <category>Aperiquiz</category>
    <category>parameter</category>
    <category>aperiquiz</category>
    <category>method</category>
    <category>java</category>
            <description>Quel est le nombre maximum de paramètres pour une méthode ?&lt;br /&gt;
&lt;br /&gt;

&lt;ul&gt;
    &lt;li&gt;127&lt;/li&gt;
    &lt;li&gt;255&lt;/li&gt;
    &lt;li&gt;256&lt;/li&gt;
    &lt;li&gt;Il n'y a pas de limites&lt;/li&gt;
    &lt;li&gt;Cela dépends du compilateur&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

Réponse : (&lt;a href="#aperiquiz-answer3" name="aperiquiz-answer3" onclick="document.getElementById('aperiquiz-answer3').style.display='block';"&gt;cliquez pour afficher&lt;/a&gt;)
&lt;blockquote id="aperiquiz-answer3" style="border: 1px solid black; display: none;"&gt;
255&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Explication :&lt;/h3&gt;
Je n'ai malheureusement trouvé aucune référence à cette limite dans la JLS, mais cette limite a été révélée par un test avec le compilateur du JDK de Sun :
&lt;blockquote&gt;
&lt;pre&gt;
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) Server VM (build 11.0-b15, mixed mode)
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;br /&gt;

J'ai également testé avec gcj (Ubuntu 4.3.2-1ubuntu2) 4.3.2. La sortie est un petit peu plus explicite :
&lt;blockquote&gt;
&lt;pre&gt;
Main.java:518: error: Too many parameters, parameter param255 is exceeding the limit of 255 words eligible for method parameters
	String param255
	       ^^^^^^^^
1 problem (1 error)
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;br /&gt;

&lt;/blockquote&gt;</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/aperiquiz_3_param%C3%A8tres_de_m%C3%A9thodes</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/netbeans_tip_replier_un_bloc</guid>
    <title>NetBeans tip : replier un bloc de code</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/YG8Jx8cWhIs/netbeans_tip_replier_un_bloc</link>
        <pubDate>Wed, 11 Feb 2009 17:05:33 +0100</pubDate>
    <category>NetBeans</category>
    <category>netbeans</category>
    <category>collapse</category>
    <category>tip</category>
    <category>editor-fold</category>
            <description>Question assez récurente lorsque des utilisateurs venant d'environnement .NET découvrent NetBeans :
&lt;blockquote&gt;
Est-ce qu'il est possible de réduire un bloc de code dans une classe, comme le fait Visual Studio avec ses régions ?
&lt;/blockquote&gt;
&lt;br /&gt;

&lt;center&gt;&lt;img src="http://blog.aperigeek.com/viv/resource/NetBeans/editor-fold.png" style="border: 1px solid black;" /&gt;&lt;/center&gt;&lt;br /&gt;

La réponse est oui. cette fonctionnalité de NetBeans est basée sur une balise XML placée dans des commentaires, la balise &lt;code&gt;&amp;lt;editor-fold&amp;gt;&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;

Petit exemple :
&lt;textarea name="code" class="java"&gt;
public class Main {

    // &lt;editor-fold&gt;

    public static void main(String... args) {
        System.out.println("This is my program!");
    }

    // &lt;/editor-fold&gt;

}
&lt;/textarea&gt;
&lt;br /&gt;

Il est maintenant possible de replier ce bout de code sur lui même, et il sera remplacé par le texte &lt;code&gt;...&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;

Il est possible de configurer le texte qui sera affiché lorsque le bloc de code sera replié (au lieu de &lt;code&gt;...&lt;/code&gt;). Pour cela, il suffit de spécifier l'attribut &lt;code&gt;desc&lt;/code&gt; dans la balise &lt;code&gt;&amp;lt;editor-fold&amp;gt;&lt;/code&gt; :
&lt;textarea name="code" class="java"&gt;
public class Main {

    // &lt;editor-fold desc="This is my main method"&gt;

    public static void main(String... args) {
        System.out.println("This is my program!");
    }

    // &lt;/editor-fold&gt;

}
&lt;/textarea&gt;</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/netbeans_tip_replier_un_bloc</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/aperiquiz_2_exception_g%C3%A9n%C3%A9rique</guid>
    <title>Aperiquiz #2 : Exception générique</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/k2vPT9gXsaw/aperiquiz_2_exception_g%C3%A9n%C3%A9rique</link>
        <pubDate>Mon, 2 Feb 2009 18:44:21 +0100</pubDate>
    <category>Aperiquiz</category>
    <category>generics</category>
    <category>exception</category>
    <category>aperiquiz</category>
            <description>Est-ce que le code suivant compile ?
&lt;textarea name="code" class="java" style="display: block;"&gt;
public class MyException&lt;T&gt; extends Exception {

}
&lt;/textarea&gt;

Réponse : (&lt;a href="#aperiquiz-answer2" name="aperiquiz-answer2" onclick="document.getElementById('aperiquiz-answer2').style.display='block';"&gt;cliquez pour afficher&lt;/a&gt;)
&lt;blockquote id="aperiquiz-answer2" style="border: 1px solid black; display: none;"&gt;
Non.&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;Explication :&lt;/h3&gt;
La spécification du langage précise explicitement : "It is a compile-time error if a generic class is a direct or indirect subclass of Throwable." (Traduction : "C'est une erreur de compilation si une classe générique hérite directement ou indirectement de Throwable").&lt;br /&gt;
&lt;br /&gt;

En effet, le mécanisme de &lt;code&gt;catch&lt;/code&gt; des exceptions en Java ne fonctionne qu'avec des classes non génériques. C'est pour cela que les classes héritant de &lt;code&gt;Throwable&lt;/code&gt; ne peuvent pas être typées avec des generics.
&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;

Sources :
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/"&gt;Java Language Specification&lt;/a&gt;, &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.2"&gt;§8.1.2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/aperiquiz_2_exception_g%C3%A9n%C3%A9rique</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/aperiquiz_1_finally_returns</guid>
    <title>Aperiquiz #1 : Finally returns</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/2-sCRp8N3zM/aperiquiz_1_finally_returns</link>
        <pubDate>Mon, 26 Jan 2009 14:06:29 +0100</pubDate>
    <category>Aperiquiz</category>
    <category>finally</category>
    <category>aperiquiz</category>
    <category>return</category>
            <description>Ceci est le premier post d'une longue (j'espère) série de questions : l'Aperiquiz.&lt;br /&gt;
&lt;br /&gt;

Le principe est simple : mettre en évidence un point précis de la spécification Java en se basant sur un exemple de code inhabituel, une question tordue ou une particularité peu connue du langage.&lt;br /&gt;
&lt;br /&gt;

Prêts ? C'est parti !&lt;br /&gt;
&lt;br /&gt;

Considérant le code suivant :
&lt;pre name="code" class="java"&gt;
public class Main {

    public static String myMethod() {
        try {
            return "try";
        } catch (Exception e) {
            return "catch";
        } finally {
            return "finally";
        }
    }

    public static void main(String[] args) {
        System.out.println(myMethod());
    }

}
&lt;/pre&gt;
Quel est le résultat ?
&lt;ul&gt;
    &lt;li&gt;try&lt;/li&gt;
    &lt;li&gt;catch&lt;/li&gt;
    &lt;li&gt;finally&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

Réponse : (&lt;a href="#aperiquiz-answer1" name="aperiquiz-answer1" onclick="document.getElementById('aperiquiz-answer1').style.display='block';"&gt;cliquez pour afficher&lt;/a&gt;)
&lt;blockquote id="aperiquiz-answer1" style="border: 1px solid black; display: none;"&gt;
&lt;code&gt;finally&lt;/code&gt;
&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;

Sources :
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://stackoverflow.com/questions/479112/questions-to-indicate-competency-in-java"&gt;Stack Overflow : Questions to indicate competency in Java&lt;/a&gt; (merci à &lt;a href="http://twitter.com/nitramf/status/1148734995"&gt;Martin&lt;/a&gt; pour le lien)&lt;/li&gt;
&lt;/ul&gt;</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/aperiquiz_1_finally_returns</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/comment_se_d%C3%A9barasser_de_code</guid>
    <title>Comment se débarasser de com.sun.messaging.jmq.io.Packet cannot be cast to com.sun.messaging.jms.ra.DirectPacket ?</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/hqphLghKT78/comment_se_d%C3%A9barasser_de_code</link>
        <pubDate>Fri, 16 Jan 2009 16:51:31 +0100</pubDate>
    <category>GlassFish</category>
    <category>jms</category>
    <category>glassfish</category>
            <description>Avec une installation par défaut de GlassFish, l'utilisation de JMS au sein du serveur d'application amène souvent à l'erreur suivante :
&lt;br /&gt;&lt;code&gt;
DirectConsumer:Caught Exception delivering messagecom.sun.messaging.jmq.io.Packet cannot be cast to com.sun.messaging.jms.ra.DirectPacket
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;

Cette erreur n'est pas fatale, l'application est tout de même déployée et les différents messages sont envoyés et reçus. Cependant, cette erreur est générée à chaque envoi de message, ce qui peut rapidement devenir encombrant dans les fichiers de log de GlassFish.&lt;br /&gt;
&lt;br /&gt;

Cette exception viens du mode de configuration utilisé pour le lancement du service JMS dans GlassFish. Par défaut, le service est lancé en mode &lt;code&gt;EMBEDDED&lt;/code&gt;. Le service JMS tourne dans le même processus que le serveur GlassFish, ce qui provoque ce genre d'erreurs.&lt;br /&gt;
&lt;br /&gt;

Il est possible de changer ce mode de lancement du service JMS. Il suffit de lancer ce même service en mode &lt;code&gt;LOCAL&lt;/code&gt; pour que le service tourne dans un processus séparé du serveur GlassFish (mais toujours sur la même machine). Le service JMS sera toujours contrôlé par GlassFish (lancement simultanés entre autre). Changer ce mode de fonctionnement du service JMS permet de résoudre ce problème de cast de messages.&lt;br /&gt;
&lt;br /&gt;

Pour effectuer ce changement, il faut se rendre dans la console d'administration de GlassFish :
&lt;ul&gt;
    &lt;li&gt;Accéder à l'adresse http://localhost:4848/&lt;/li&gt;
    &lt;li&gt;Se connecter avec les identifiants d'administration de GlassFish (par défaut : admin /// adminadmin)&lt;/li&gt;
    &lt;li&gt;Cliquer sur "Configuration" -&gt; "Java Message Service" dans le menu de navigation de gauche&lt;/li&gt;
    &lt;li&gt;Modifier la propriété "Type" et lui donner la valeur de "LOCAL"&lt;/li&gt;
&lt;/ul&gt;</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/comment_se_d%C3%A9barasser_de_code</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/richfaces_filtrer_et_trier_une</guid>
    <title>RichFaces : Filtrer et trier une DataTable</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/fRu6W81HSiY/richfaces_filtrer_et_trier_une</link>
        <pubDate>Sat, 29 Nov 2008 17:18:40 +0100</pubDate>
    <category>Java</category>
    <category>java</category>
    <category>datatable</category>
    <category>jsf</category>
    <category>richfaces</category>
    <category>javaee</category>
            <description>Après avoir installé &lt;a href="http://blog.aperigeek.com/viv/entry/richfaces"&gt;RichFaces&lt;/a&gt;, je me suis lancé dans la rédaction d'une page d'exemple, histoire d'apprendre le fonctionnement de cette librairie qui semble bien intéressante.&lt;br /&gt;
&lt;br /&gt;

&lt;div align="center"&gt;
    &lt;img src="http://blog.aperigeek.com/viv/resource/RichFaces/DataTable-FilterSort.png" /&gt;
&lt;/div&gt;

Le but de cette page d'exemple est de mettre en place une DataTable, avec fonctionnalités de tri et de filtres. Toutes ces fonctionnalités utiliseront de l'Ajax, et il ne sera donc pas nécéssaire de recharger la page afin de voir les changements.&lt;br /&gt;
&lt;br /&gt;

Les contacts contenus dans notre DataTable devront être triés par nom de famille par défaut. Il sera également possible pour l'utilisateur de changer l'ordre de tri (croissant, décroissant), ainsi que la propriété servant à effectuer ce tri (prénom, nom, ou adresse mail).&lt;br /&gt;
&lt;br /&gt;

Enfin, pour le filtre, nous aurons un champ de texte qui limitera la liste aux contacts :
&lt;ul&gt;
    &lt;li&gt;Dont le nom commence par la requête&lt;/li&gt;
    &lt;li&gt;Dont le prénom commence par la requête&lt;/li&gt;
    &lt;li&gt;Dont l'adresse mail contient la requête&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Mise en place d'une Rich DataTable&lt;/h2&gt;

Afin de commencer notre page d'exemple, nous allons créer une classe &lt;code&gt;Contact&lt;/code&gt;, qui aura pour vocation de contenir les données. Cette classe est un JavaBean, et possède donc les caractérisques suivantes :
&lt;ul&gt;
    &lt;li&gt;Les propriétés doivent être privées&lt;/li&gt;
    &lt;li&gt;Chaque propriété doit avoir des accésseurs (getters et setters) publics&lt;/li&gt;
    &lt;li&gt;La classe doit avoir un constructeur par défaut&lt;/li&gt;
    &lt;li&gt;La classe doit implémenter &lt;code&gt;Serializable&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;

Nous allons donc créer notre classe &lt;code&gt;Contact&lt;/code&gt; avec les propriétés &lt;code&gt;firstName&lt;/code&gt;, &lt;code&gt;lastName&lt;/code&gt; et &lt;code&gt;mailAddress&lt;/code&gt; :
&lt;textarea name="code" class="java"&gt;
public class Contact implements java.io.Serializable {

    private String firstName;

    private String lastName;

    private String mailAddress;

    public Contact() {
    }

    public Contact(String firstName, String lastName, String mailAddress) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.mailAddress = mailAddress;
    }

    // Getters and setters

}
&lt;/textarea&gt;&lt;br /&gt;
&lt;br /&gt;

La seconde étape sera de créer un managed bean JSF, qui nous renvera une liste de contacts d'exemple :
&lt;textarea name="code" class="java"&gt;
public class DataTableManager {

    // Returns sample data
    public DataModel getSampleModel() {
        List&lt;Contact&gt; contacts = new ArrayList&lt;Contact&gt;();
        contacts.add(new Contact("Toto", "Tata", "toto@tata.com"));
        contacts.add(new Contact("John", "Doe", "john@doe.com"));
        contacts.add(new Contact("Alan", "Smithee", "alan@smithee.com"));
        contacts.add(new Contact("Vivien", "Barousse", "barousse.vivien@gmail.com"));
        contacts.add(new Contact("Titi", "Tata", "titi@tata.com"));
        contacts.add(new Contact("Foo", "Bar", "foo.bar@provider.com"));
        contacts.add(new Contact("Bar", "Baz", "bar.baz@provider.com"));
        contacts.add(new Contact("Gloubi", "Boulga", "gloubi@goulba.com"));
        return (new ListDataModel(contacts));
    }
}
&lt;/textarea&gt;&lt;br /&gt;
&lt;br /&gt;

Et enfin, dernière étape, nous allons créer notre Rich DataTable, basique pour l'instant, capable d'afficher ces données :
&lt;textarea name="code" class="xml"&gt;
&lt;rich:dataTable value="#{DataTableManager.sampleModel}" var="contact"&gt;
    &lt;f:facet name="header"&gt;
        &lt;h:outputText value="Sorting &amp; Filter exemple" /&gt;
    &lt;/f:facet&gt;
    &lt;rich:column&gt;
        &lt;f:facet name="header"&gt;
            &lt;h:outputText value="First name" /&gt;
        &lt;/f:facet&gt;
        &lt;h:outputText value="#{contact.firstName}" /&gt;
    &lt;/rich:column&gt;
    &lt;rich:column&gt;
        &lt;f:facet name="header"&gt;
            &lt;h:outputText value="Last name" /&gt;
        &lt;/f:facet&gt;
        &lt;h:outputText value="#{contact.lastName}" /&gt;
    &lt;/rich:column&gt;
    &lt;rich:column&gt;
        &lt;f:facet name="header"&gt;
            &lt;h:outputText value="Mail address" /&gt;
        &lt;/f:facet&gt;
        &lt;h:outputText value="#{contact.mailAddress}" /&gt;
    &lt;/rich:column&gt;
&lt;/rich:dataTable&gt;
&lt;/textarea&gt;&lt;br /&gt;
&lt;br /&gt;

Nous avons dans l'exemple de code précédent créé une Rich DataTable. Le code ressemble à celui d'une DataTable classique, la seule différence étant l'utilisation de la taglib RichFaces au lieu de la taglib standard.

&lt;h2&gt;Rajout des fonctionnalités de tri&lt;/h2&gt;

L'ajout du tri dans une Rich DataTable est très facile. La balise &lt;code&gt;&amp;lt;rich:column /&amp;gt;&lt;/code&gt; possède un attribut &lt;code&gt;sortBy&lt;/code&gt;, qui permet de spécifier la propriété qui sera utilisée pour trier la colonne concernée.&lt;br /&gt;
&lt;br /&gt;

Notre code précédent ressemble donc désormais à ceci :
&lt;textarea name="code" class="xml"&gt;
&lt;rich:dataTable value="#{DataTableManager.sampleModel}" var="contact"&gt;
    &lt;f:facet name="header"&gt;
        &lt;h:outputText value="Sorting &amp; Filter exemple" /&gt;
    &lt;/f:facet&gt;
    &lt;rich:column sortBy="#{contact.firstName}"&gt;
        &lt;f:facet name="header"&gt;
            &lt;h:outputText value="First name" /&gt;
        &lt;/f:facet&gt;
        &lt;h:outputText value="#{contact.firstName}" /&gt;
    &lt;/rich:column&gt;
    &lt;rich:column sortBy="#{contact.lastName}"&gt;
        &lt;f:facet name="header"&gt;
            &lt;h:outputText value="Last name" /&gt;
        &lt;/f:facet&gt;
        &lt;h:outputText value="#{contact.lastName}" /&gt;
    &lt;/rich:column&gt;
    &lt;rich:column sortBy="#{contact.mailAddress}"&gt;
        &lt;f:facet name="header"&gt;
            &lt;h:outputText value="Mail address" /&gt;
        &lt;/f:facet&gt;
        &lt;h:outputText value="#{contact.mailAddress}" /&gt;
    &lt;/rich:column&gt;
&lt;/rich:dataTable&gt;
&lt;/textarea&gt;
&lt;br /&gt;

L'exécution de ce code nous montre que sur chaque colonne, RichFaces a rajouté des boutons permettant à l'utilisateur de choisir quelle colonne sera utilisée pour trier les données, et de choisir l'ordre de tri.&lt;br /&gt;
&lt;br /&gt;

Il est également possible de donner un ordre de tri par défaut à notre DataTable. Pour celà, nous allons utiliser l'attribut &lt;code&gt;sortOrder&lt;/code&gt; de notre balise &lt;code&gt;&amp;lt;rich:column /&amp;gt;&lt;/code&gt; :
&lt;textarea name="code" class="xml"&gt;
&lt;rich:column sortBy="#{contact.lastName}"
             sortOrder="ASCENDING"&gt;
    &lt;f:facet name="header"&gt;
        &lt;h:outputText value="Last name" /&gt;
    &lt;/f:facet&gt;
    &lt;h:outputText value="#{contact.lastName}" /&gt;
&lt;/rich:column&gt;
&lt;/textarea&gt;
&lt;br /&gt;

Ainsi, au lancement de la page, les contacts seront triés par ordre alphabétique en fonction de leur nom de famille. Il sera également possible pour l'utilisateur de changer la propriété servant à faire le tri (et de choisir le prénom, ou l'adresse mail). L'utilisateur aura également la possibilité de changer l'ordre de tri (croissant, décroissant).&lt;br /&gt;

&lt;h2&gt;Filtrer les données&lt;/h2&gt;

Le filtrage des données à l'intérieur d'une DataTable passe par plusieurs étapes :
&lt;ul&gt;
    &lt;li&gt;Il faut commencer par créer un champ de texte, permettant à l'utilisateur de rentrer la requête sur laquelle nous allons nous baser pour filtrer les entrées&lt;/li&gt;
    &lt;li&gt;Il faudra ensuite créer une méthode permettant de filter chacune de nos entrées. Cette méthode prends en paramètre l'objet à filter, et renvoie un booléen indiquant si l'objet doit être affiché&lt;/li&gt;
    &lt;li&gt;Enfin, il faudra que notre DataTable soit mise à jour à chaque modification de la requête&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

La première étape est donc de créer notre champ de texte. Il s'agit d'un simple champ de texte JSF (&lt;code&gt;&amp;lt;h:inputText /&amp;gt;&lt;/code&gt;) que nous allons lier à une propriété d'un managed bean :
&lt;textarea name="code" class="java"&gt;
public class DataTableManager {

    // [...]

    // Filtering

    private String filterValue;

    public String getFilterValue() {
        return filterValue;
    }

    public void setFilterValue(String filterValue) {
        this.filterValue = filterValue;
    }

}
&lt;/textarea&gt;
Puis le code JSP correspondant :
&lt;textarea name="code" class="xml"&gt;
&lt;h:inputText value="#{DataTableManager.filterValue}"
             id="lastNameFilterText"&gt;
&lt;/h:inputText&gt;
&lt;/textarea&gt;
&lt;br /&gt;

Seconde étape, toujours dans notre managed bean, nous allons créer une méthode filtrant les objets de type &lt;code&gt;Contact&lt;/code&gt; en fonction de la requête qui nous est envoyée par le champ de saisie. Dans l'exemple ci dessous, la méthode &lt;code&gt;doFilter&lt;/code&gt; prends en paramètre l'objet que nous allons devoir filtrer (dans notre cas, on objet de type &lt;code&gt;Contact&lt;/code&gt;), et dois renvoyer &lt;code&gt;true&lt;/code&gt; si le contact doit être affiché, &lt;code&gt;false&lt;/code&gt; sinon :
&lt;textarea name="code" class="java"&gt;
public class DataTableManager {

    // [...]

    public boolean doFilter(Object value) {
        if (filterValue == null) {
            return (true);
        }
        Contact contact = (Contact) value;
        if (contact.getFirstName().toLowerCase()
                .startsWith(filterValue.toLowerCase())) {
            return (true);
        }
        if (contact.getLastName().toLowerCase()
                .startsWith(filterValue.toLowerCase())) {
            return (true);
        }
        if (contact.getMailAddress().toLowerCase()
                .contains(filterValue.toLowerCase())) {
            return (true);
        }
        return (false);
    }

}
&lt;/textarea&gt;
Nous allons également dire à notre DataTable d'utiliser cette méthode afin de filtrer les entrées à afficher :
&lt;textarea name="code" class="xml"&gt;
&lt;rich:column sortBy="#{contact.firstName}"
             filterMethod="#{DataTableManager.doFilter}"&gt;
    &lt;f:facet name="header"&gt;
        &lt;h:outputText value="First name" /&gt;
    &lt;/f:facet&gt;
    &lt;h:outputText value="#{contact.firstName}" /&gt;
&lt;/rich:column&gt;
&lt;/textarea&gt;
&lt;br /&gt;

Enfin, dernière étape, nous allons préciser à RichFaces que notre champ de texte doit automatiquement rafraîchir, en Ajax, notre DataTable afin que les données soient de nouveau filtrées, avec la nouvelle requête :
&lt;textarea name="code" class="xml"&gt;
&lt;h:inputText value="#{DataTableManager.filterValue}"
             id="lastNameFilterText"&gt;
    &lt;a4j:support event="onkeyup"
                 reRender="dataTable"
                 requestDelay="500" /&gt;
&lt;/h:inputText&gt;
&lt;/textarea&gt;
La balise &lt;code&gt;&amp;lt;a4j:support /&amp;gt;&lt;/code&gt; permet, entre autres, de mettre rafraîchir un composant. Elle prends 3 paramètres :
&lt;ul&gt;
    &lt;li&gt;&lt;code&gt;event&lt;/code&gt; : l'évènement JavaScript qui devra déclencher le rafraîchissement&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;reRender&lt;/code&gt; : le composant à rafraîchir&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;requestDelay&lt;/code&gt; : permet de spécifier un délai entre la requête et le refraîchissement du composant&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

A chaque fois que la valeur du champ de texte est modifiée, la nouvelle valeur est envoyé dans notre managed bean, et notre DataTable est raffraîchie. Ainsi, le tableau va de nouveau être filtré, et notre méthode va permettre d'éliminer certains résultats de notre tableau.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;

Nous avons donc vu un premier exemple de fonctionnalité Ajax qu'il est possible de réaliser grâce à RichFaces. Une DataTable avec fonctionnalités de tri et de filtre, qui se rafraîchit sans recharger la page.&lt;br /&gt;
&lt;br /&gt;

Les sources du projet NetBeans de cet article sont disponnibles &lt;a href="http://blog.aperigeek.com/viv/resource/RichFaces/DataTable-FilterSort.zip"&gt;ici&lt;/a&gt;.</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/richfaces_filtrer_et_trier_une</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/richfaces</guid>
    <title>RichFaces</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/CStsrnNC60A/richfaces</link>
        <pubDate>Wed, 26 Nov 2008 19:12:04 +0100</pubDate>
    <category>Java</category>
    <category>richfaces</category>
    <category>java</category>
    <category>jsf</category>
    <category>javaee</category>
            <description>Je continue dans ma recherche de librairie de composants pour JSF. J'avais déjà testé &lt;a href="http://blog.aperigeek.com/viv/tags/icefaces"&gt;ICEFaces&lt;/a&gt;, mais elle ne me satisfaisait pas. Trop de changement au niveau du cycle de vie de JSF à mon goût.&lt;br /&gt;
&lt;br /&gt;

J'ai testé aujourd'hui une nouvelle librairie, qui à l'air de s'intégrer parfaitement à JSF. Très peu de changements dans le cycle de vie JSF, &lt;a href="http://livedemo.exadel.com/richfaces-demo/index.jsp"&gt;beaucoup de composants&lt;/a&gt;, &lt;a href="http://www.jsfmatrix.net/"&gt;dont la plupart en Ajax&lt;/a&gt;. Il s'agit de &lt;a href="http://www.jboss.org/jbossrichfaces/"&gt;RichFaces&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;

L'installation, comparée à &lt;a href="http://blog.aperigeek.com/viv/entry/installer_icefaces_pour_les_nuls"&gt;celle de ICEFaces&lt;/a&gt;, est très simple. Quelques &lt;a href="http://www.jboss.org/jbossrichfaces/downloads/"&gt;librairies&lt;/a&gt;, quelques dépendances (&lt;a href="http://commons.apache.org/beanutils/"&gt;BeanUtils&lt;/a&gt;, &lt;a href="http://commons.apache.org/collections/"&gt;Collections&lt;/a&gt;, &lt;a href="http://commons.apache.org/digester/"&gt;Digester&lt;/a&gt;, &lt;a href="http://commons.apache.org/logging/"&gt;Commons Log&lt;/a&gt;). La seule configuration nécessaire est la déclaration d'un filtre dans le fichier &lt;code&gt;web.xml&lt;/code&gt; :
&lt;textarea name="code" class="xml"&gt;
&lt;filter&gt;
    &lt;display-name&gt;RichFaces Filter&lt;/display-name&gt;
    &lt;filter-name&gt;richfaces&lt;/filter-name&gt;
    &lt;filter-class&gt;org.ajax4jsf.Filter&lt;/filter-class&gt;
&lt;/filter&gt;

&lt;filter-mapping&gt;
    &lt;filter-name&gt;richfaces&lt;/filter-name&gt;
    &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
    &lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
    &lt;dispatcher&gt;FORWARD&lt;/dispatcher&gt;
    &lt;dispatcher&gt;INCLUDE&lt;/dispatcher&gt;
&lt;/filter-mapping&gt;
&lt;/textarea&gt;
&lt;br /&gt;

Il ne reste plus qu'à tester la liste assez imposante de composants proposés :)</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/richfaces</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/netbeans_6_5_est_parmis</guid>
    <title>NetBeans 6.5 est parmis nous</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/uLEPSGOShCQ/netbeans_6_5_est_parmis</link>
        <pubDate>Wed, 19 Nov 2008 18:29:12 +0100</pubDate>
    <category>NetBeans</category>
    <category>netbeans</category>
    <category>final</category>
    <category>6.5</category>
            <description>La version &lt;a href="http://www.netbeans.org/community/releases/65/"&gt;6.5&lt;/a&gt; de l'IDE &lt;a href="http://www.netbeans.org/"&gt;NetBeans&lt;/a&gt; viens de sortir, en version finale.&lt;br /&gt;
&lt;br /&gt;

Après téléchargement et installation, la première impression est assez marquante. Le lancement est encore plus rapide, et l'interface encore plus fluide (comparé à la version 6.1).&lt;br /&gt;
&lt;br /&gt;

Au niveau des nouvelles fonctionnalités, quelques nouveautés assez importantes :
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://php.netbeans.org/"&gt;Environnement de développement PHP&lt;/a&gt; (et une distribution de NetBeans spécialisée)&lt;/li&gt;
    &lt;li&gt;Amélioration du support Java EE (notamment JSF et JPA)&lt;/li&gt;
    &lt;li&gt;Éditeur Java FX&lt;/li&gt;
    &lt;li&gt;Support de &lt;a href="https://glassfish.dev.java.net/"&gt;GlassFish&lt;/a&gt; &lt;a href="https://glassfish.dev.java.net/downloads/v3-prelude.html"&gt;v3 prelude&lt;/a&gt;, uniquement pour de développement Web&lt;/li&gt;
    &lt;li&gt;Amélioration de l'éditeur Java&lt;/li&gt;
    &lt;li&gt;Nouvelles fonctionnalités dans l'IDE de base&lt;/li&gt;
    &lt;ul&gt;
        &lt;li&gt;Compile on save / Deploy on save&lt;/li&gt;
        &lt;li&gt;Modification des préférences d'indentation par projet&lt;/li&gt;
        &lt;li&gt;Barre de recherche rapide&lt;/li&gt;
    &lt;/ul&gt;
&lt;/ul&gt;
La liste complète est disponible &lt;a href="http://www.netbeans.org/community/releases/65/"&gt;ici&lt;/a&gt;.
&lt;br /&gt;
&lt;br /&gt;

Parmis ces fonctionnalités, certaines me plaisent déjà, dont :
&lt;ul&gt;
    &lt;li&gt;Le "compile/deploy on save" qui recompile et/ou redéploie un projet dès qu'un changement est fait dans un fichier&lt;/li&gt;
    &lt;li&gt;Le support de GlassFish v3 prelude (que j'aime déjà, pour sa rapidité, et ses derniers frameworks [EJB 3.1, JSF 2.0])&lt;/li&gt;
    &lt;li&gt;Les préférences d'indentation spécifique à chaque projet. Finies les guerres d'indentation sur les dépots !&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

Il y a aussi quelques fonctionnalités qui restent à tester et qui semblent intéressantes, comme le support amélioré de JSF et de JPA.&lt;br /&gt;
&lt;br /&gt;

Pour les téléchargements, c'est directement &lt;a href="http://www.netbeans.org/downloads/index.html"&gt;ici&lt;/a&gt;.</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/netbeans_6_5_est_parmis</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/ejb_3_1_on_y</guid>
    <title>EJB 3.1, on y arrive !</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/XRa342u01BY/ejb_3_1_on_y</link>
        <pubDate>Tue, 11 Nov 2008 16:34:36 +0100</pubDate>
    <category>Java</category>
    <category>java</category>
    <category>javaee</category>
    <category>ejb</category>
            <description>Cela va mainteant faire 4 jours que &lt;a href="https://glassfish.dev.java.net/"&gt;GlassFish&lt;/a&gt; &lt;a href="https://glassfish.dev.java.net/downloads/v3-prelude.html"&gt;v3 prelude&lt;/a&gt; est sorti. Pour accompagner sa sortie, &lt;a href=""&gt;une vingtaine de présentations&lt;/a&gt; ont été faites sur GlassFish (via la chaine &lt;a href="http://www.ustream.tv/channel/theaquarium"&gt;TheAquarium&lt;/a&gt;, sur &lt;a href="http://www.ustream.tv/"&gt;Ustream.TV&lt;/a&gt;), mais aussi sur Java EE 6 et NetBeans 6.5.&lt;br /&gt;
&lt;br /&gt;

Je viens d'en regarder quelques unes, et celle qui a le plus retenu mon attention est sans aucun doute la présentation des EJB 3.1, qui vient avec son lot d'améliorations et de nouvelles fonctionnalités qui méritent de s'y attarder :-)&lt;br /&gt;
&lt;br /&gt;

On retrouve parmis ces fonctionnalités :
&lt;ul&gt;
    &lt;li&gt;Les singletons&lt;/li&gt;
    &lt;li&gt;Une meilleure gestion des timers&lt;/li&gt;
    &lt;li&gt;Les noms JNDI globaux&lt;/li&gt;
    &lt;li&gt;Les Session Beans "sans interface"&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Les singletons&lt;/h2&gt;

Les &lt;a href="http://fr.wikipedia.org/wiki/Singleton_(patron_de_conception)"&gt;singletons&lt;/a&gt; sont des beans qui ont la particularité de n'être instanciés qu'une seule et unique fois tout au long de la vie de notre application. Cette instance sera ensuite partagée entre les différents clients l'utilisant.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="java"&gt;
@Singleton
public class MySingleton {

    private int sharedValue;

    public int getSharedValue() {
        return (sharedValue);
    }

}
&lt;/pre&gt;
&lt;br /&gt;

Dans cet exemple de code, notre bean &lt;code&gt;MySingleton&lt;/code&gt; sera instancié une seule et unique fois, et chaque appel de méthode fera appel à la même instance, ce qui nous permettra, par exemple, de partager des données (comme la variable &lt;code&gt;sharedValue&lt;/code&gt; de notre exemple).

&lt;h2&gt;Une meilleure gestion des timers&lt;/h2&gt;

EJB 3.1 introduit également une nouvelle gestion des timers, qui se rapproche de la gestions des &lt;a href="http://fr.wikipedia.org/wiki/Cron"&gt;crons&lt;/a&gt; Unix : on peut spécifier des tâches à exécuter de manière très précise. Ces timers seront alors automatiquement créés et démarrés.&lt;br /&gt;
&lt;br /&gt;

Voici un exemple, lançant une tâche tous les jours à 8 heures :
&lt;pre name="code" class="java"&gt;
@Stateless
public class MyBean implements MyInterface {

    @Schedule(hour="8")
    void myTask() {
    }

}
&lt;/pre&gt;

&lt;h2&gt;Les noms JNDI globaux&lt;/h2&gt;

Il s'agit sûrement d'une des plus grosses lacunes de la spécification EJB 3 qui se trouve ici comblée : l'absence de standardisation des noms JNDI associés aux Session Bean, ce qui entraînait des pertes de portabilité entre les différents serveurs d'application.&lt;br /&gt;
&lt;br /&gt;

Par exemple, sous GlassFish, le nom par défaut d'un Session Bean est le nom complet de l'interface métier de notre bean (&lt;code&gt;&lt;b&gt;com.aperigeek.ejb.MyInterface&lt;/b&gt;&lt;/code&gt;). Sous JBoss, le nom est &lt;code&gt;&lt;b&gt;&amp;lt;nom du jar&amp;gt;/&amp;lt;nom du bean&amp;gt;/&amp;lt;visibilité&amp;gt;&lt;/b&gt;&lt;/code&gt;, ce qui donnerais par exemple &lt;code&gt;&lt;b&gt;aperigeek/MyBean/remote&lt;/b&gt;&lt;/code&gt;. Les noms sont donc très dépendants du serveur d'application.&lt;br /&gt;
&lt;br /&gt;

La nouvelle spécification EJB 3.1 spécifie des noms standards à respecter lors du binding des beans : &lt;code&gt;&lt;b&gt;java:global[/&amp;lt;app-name&amp;gt;]/&amp;lt;module-name&amp;gt;/&amp;lt;ejb-name&amp;gt;&lt;/b&gt;&lt;/code&gt;, ce qui pourrait donner : &lt;code&gt;&lt;b&gt;java:global/aperigeek/aperigeek-ejb/MyBean&lt;/b&gt;&lt;/code&gt;. Cette fonctionnalité permet d'assurer la portabilité d'une application entre différents serveurs d'applications.

&lt;h2&gt;Les Session Beans "sans interface"&lt;/h2&gt;

Dernière fonctionnalité dans la série des simplifications de la spécification : la possibilité de définir un Session Bean dans une seule classe, sans passer par une interface métier exposant les différentes méthodes.&lt;br /&gt;
&lt;br /&gt;

&lt;pre name="code" class="java"&gt;
@Stateless
public class MyBean {

    public void myMethod() {
    }

}
&lt;/pre&gt;
&lt;br /&gt;

Dans ce cas de figure, toutes les méthodes publiques deviennent visibles.
&lt;pre name="code" class="java"&gt;
@Stateless
public class MyOtherBean {

    @EJB
    private MyBean myBean;

    public void myOtherMethod() {
        myBean.myMethod();
    }

}
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;

La nouvelle version des EJB, la version 3.1, apporte encore quelques améliorations à la version 3.0. L'optique de cette nouvelle version reste essentiellement la même : simplifier l'utilisation des EJBs. On retrouve quand même quelques nouvelles fonctionnalités intéressantes, comme les singletons ou les timers.&lt;br /&gt;
&lt;br /&gt;

Toutes ces nouvelles fonctionnalités sont d'ores et déjà testables grâce à &lt;a href="https://glassfish.dev.java.net/downloads/v3-prelude.html"&gt;GlassFish v3 prelude&lt;/a&gt;, qui sert d'implémentation de référence à cette spécification.</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/ejb_3_1_on_y</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/java_c_sockets</guid>
    <title>Java/C : Sockets</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/hKbOSv_2mfA/java_c_sockets</link>
        <pubDate>Fri, 3 Oct 2008 08:28:09 +0100</pubDate>
    <category>C/C++</category>
    <category>socket</category>
    <category>java</category>
    <category>c</category>
            <description>&lt;div style="width: 48%; float: left"&gt;
&lt;textarea name="code" class="java"&gt;
public class Main {

    public static void main(String[] args) {
        try {
            ServerSocket serv = new ServerSocket(8080);
            for (int i = 0; i &lt; 3; i++) {
                Socket client = serv.accept();
                OutputStream out = client.getOutputStream();
                out.write("Toto\n".getBytes());
                out.close();
                client.close();
            }
            serv.close();
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }
    }
}
&lt;/textarea&gt;
&lt;/div&gt;
&lt;div style="width: 48%; float: left"&gt;
&lt;textarea name="code" class="c"&gt;
int main(int argc, char** argv) {
    
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    
    struct sockaddr_in* sin = malloc (sizeof (struct sockaddr_in));
    sin-&gt;sin_family = AF_INET;
    sin-&gt;sin_port = htons(8080);
    sin-&gt;sin_addr.s_addr = htonl(INADDR_ANY);
    
    if (bind (sock, (struct sockaddr*) sin, sizeof (struct sockaddr_in)) &lt; 0) {
        printf("Error while binding...\n");
        return(EXIT_FAILURE);
    }
    
    if (listen(sock, 5) &lt; 0) {
        printf("Error while listening...\n");
        return(EXIT_FAILURE);
    }
    
    int i;
    for (i = 0; i &lt; 3; i++) {
        
        int client = accept(sock, 0, 0);
        if (client &lt; 0) {
            printf("Error accepting!\n");
            break;
        }
        
        write(client, "Toto\n", 5);
        
        close(client);
    }
    close(sock);
    
    return (EXIT_SUCCESS);
}
&lt;/textarea&gt;
&lt;/div&gt;
&lt;br style="clear: both;" /&gt;

J'ai refait un peu de C hier, "pour le plaisir"... Je pense que les deux bouts de code au dessus parlent pour moi :-)&lt;br /&gt;
&lt;br /&gt;

Juste, en passant, le plugin C/C++ de NetBeans est tout simplement... bien. Toutes les fonctionnalités que l'on attend d'un IDE sont là (autocomplétion, affichage des paramètres des fonctions, ...). Moi qui n'aimais pas les IDE pour le C, j'ai été plutôt surpris. Dans le bon sens :-)</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/java_c_sockets</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/java_net_op%C3%A9rateurs</guid>
    <title>Java/.NET : Opérateurs</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/Ed_c90Okvao/java_net_op%C3%A9rateurs</link>
        <pubDate>Thu, 2 Oct 2008 12:43:46 +0100</pubDate>
    <category>.NET</category>
    <category>.net</category>
    <category>surcharge</category>
    <category>java</category>
    <category>operateur</category>
    <category>indexeur</category>
            <description>Dans ce billet, nous allons parler des opérateurs. Les opérateurs existants en Java existent également en C#, et les différences entre les deux sont quasi-inexistantes.&lt;br /&gt;
&lt;br /&gt;

Nous allons donc parler de deux fonctionnalités, présentes en C#, qui n'existent pas en Java :
&lt;ul&gt;
    &lt;li&gt;La surcharge des opérateurs&lt;/li&gt;
    &lt;li&gt;Les indexeurs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Surcharge des opérateurs&lt;/h2&gt;

Le langage C#, contrairement au langage Java, implémente la surcharge des opérateurs. Les principes sont inspirés du C++.&lt;br /&gt;
&lt;br /&gt;

Voici un exemple de surcharge des opérateurs en C# :
&lt;pre name="code" class="c-sharp"&gt;
class Program
{
    static void Main(string[] args)
    {
        MyString s1 = new MyString("Hello ");
        MyString s2 = new MyString("World!");
        MyString s = s1 + s2;
    }
}

class MyString
{
    private string _value;
    public MyString(string _value)
    {
        this._value = _value;
    }
    public static MyString operator + (MyString a, MyString b)
    {
        return (new MyString(a._value + b._value));
    }
}
&lt;/pre&gt;
&lt;br /&gt;

Il n'existe aucun équivalent à la surcharge des opérateurs en Java.

&lt;h2&gt;Indexeurs&lt;/h2&gt;

Le langage C# introduit un nouveau concept, les indexeurs. Un indexeur est semblable à un opérateur, et il permet d'accéder à un index donné d'un objet, comme par exemple un tableau. Cet index peut être de type &lt;code&gt;int&lt;/code&gt;, mais aussi de n'importe quel autre type, valeur ou référence.&lt;br /&gt;
&lt;br /&gt;

Voici un exemple de code mettant en oeuvre un indexeur :
&lt;pre name="code" class="c-sharp"&gt;
class Program
{
    static void Main(string[] args)
    {
        MyIndex i = new MyIndex();
        Console.WriteLine(i[12]);
    }
}

class MyIndex
{
    public string this [int index]
    {
        get
        {
            return ("Index " + index);
        }
    }
}
&lt;/pre&gt;
&lt;br /&gt;

Il n'existe aucun équivalent aux indexeurs en Java.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;

En ce qui concerne les opérateurs en C#, nous avons vu deux fonctionnalités intéressantes qui n'existent malheureusement pas en Java.&lt;br /&gt;
&lt;br /&gt;

Beaucoup de personnes ont espéré voir la surcharge des opérateurs arriver dans Java 7. Cependant, cette fonctionnalités est assez controversée, et il y a peu de chances de la voir arriver dans le langage (de même que les indexeurs).</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/java_net_op%C3%A9rateurs</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/neal_gafter_quitte_google_pour</guid>
    <title>Neal Gafter quitte Google... Pour Microsoft</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/1Aor6Szh4M4/neal_gafter_quitte_google_pour</link>
        <pubDate>Tue, 30 Sep 2008 09:40:25 +0100</pubDate>
    <category>Actualités</category>
    <category>google</category>
    <category>microsoft</category>
    <category>gafter</category>
            <description>Les rumeurs courent depuis plusieurs jours maintenant, et c'est maintenant certain. &lt;a href="http://gafter.com/~neal/"&gt;Neal Gafter&lt;/a&gt;, un des "grands" du monde Java, viens de quitter Google pour aller travailler chez Microsoft.&lt;br /&gt;
&lt;br /&gt;

Neal Gafter travaille depuis longtemps pour le monde Java. Il a notamment dirigé les évolutions du langages et des outils (java, javac, javah et javap) de la version 1.3.1 à la version 1.5.0 du JDK. Plus récemment, il a également contribué à Java 7, et fait entre autres partie de l'équipe à l'origine des &lt;a href="http://www.javac.info"&gt;closures BGGA&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;

Maintenant chez Microsoft, il travaille sur les langages de la plate-forme .NET, et en particulier le langage C#.&lt;br /&gt;
&lt;br /&gt;

&lt;a href="http://blog.refactor.se/2008/09/29/gafter-to-microsoft/"&gt;Beaucoup&lt;/a&gt; &lt;a href="http://kohlerm.blogspot.com/2008/09/it-official-neal-gafter-works-for.html"&gt;en&lt;/a&gt; &lt;a href="http://prashantjalasutram.blogspot.com/2008/09/confirmed-news-neal-gafter-joins.html"&gt;parlent&lt;/a&gt; comme d'une mauvaise nouvelle pour le monde Java, il reste à voir ce que ce changement va nous apporter...</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/neal_gafter_quitte_google_pour</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/java_net_types_de_donn%C3%A9es</guid>
    <title>Java/.NET : Types de données</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/fkE-vFFNm70/java_net_types_de_donn%C3%A9es</link>
        <pubDate>Mon, 29 Sep 2008 06:55:15 +0100</pubDate>
    <category>.NET</category>
    <category>package</category>
    <category>namespace</category>
    <category>struct</category>
    <category>types</category>
    <category>java</category>
    <category>generics</category>
    <category>enum</category>
    <category>.net</category>
            <description>Dans ce second billet de la série "Java/.NET", nous allons parler de toutes les différences touchant aux types de données.

&lt;h2&gt;Fichiers sources&lt;/h2&gt;

En Java, le compilateur n’autorise qu’une seule et unique classe publique par fichier source. De plus, la classe publique d’un fichier source doit posséder exactement le même nom que le fichier dans lequel elle se trouve.&lt;br /&gt;
&lt;br /&gt;

En C#, les restrictions comme celles-ci n’existent pas. Il est possible de déclarer plusieurs classes publiques au sein du même fichier, et aucune vérification n’est faite quand au nom du fichier contenant les classes.

&lt;h2&gt;Types primitifs - types valeurs&lt;/h2&gt;

En Java comme en C#, il existe un type de données particulier : leur valeur est directement stocké dans une zone mémoire appelée la pile. De plus, ces différents types de données sont directement passés par valeur.&lt;br /&gt;
&lt;br /&gt;

Ils peuvent représenter une valeur "basique", à savoir :
&lt;ul&gt;
    &lt;li&gt;Un nombre (entier ou à virgule flottante)&lt;/li&gt;
    &lt;li&gt;Un caractère&lt;/li&gt;
    &lt;li&gt;Un booléen&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

En Java, ces types de données qui sont appelés des types primitifs. Il s’agit des seuls types de données qui ne sont pas des objets, c'est-à-dire qu’ils ne possèdent aucune méthode. Pour palier à cet inconvénient, il existe des types dits wrappers, qui sont des équivalents objets de ces types primitifs.&lt;br /&gt;
&lt;br /&gt;

En C#, ces types sont appelés les types valeurs. Ils résident également sur la pile, mais ce sont cependant des objets. Chaque type valeur possède un alias, qui permet de faciliter l’appel de ces types dans le code. Par exemple, le type valeur &lt;code&gt;Int32&lt;/code&gt; possède un alias &lt;code&gt;int&lt;/code&gt;. Ces alias seront convertis au moment de la compilation.&lt;br /&gt;
&lt;br /&gt;

A noter également qu’en C#, les chaînes de caractères et les énumérations ont la particularité d’être des types valeur. Au contraire, les chaînes de caractères et les énumérations en Java sont des objets, et résident sur le tas.

&lt;h2&gt;Types références&lt;/h2&gt;

Chacun des deux langages définit un autre type de variables : les types références.&lt;br /&gt;
&lt;br /&gt;

Contrairement aux types primitifs (ou types valeurs), ils sont passés par référence lors des différents appels de méthodes. Ils représentent en général des types complexes, que nous allons définir nous même. De plus, la valeur de ces types de données est stockée sur le tas, et la pile ne contient qu’une référence vers ces objets.&lt;br /&gt;
&lt;br /&gt;

En Java, chaque type primitif possède un équivalent en type référence. Ce sont les types wrappers. Ces objets
sont des objets comme tous les autres objets Java. Leur valeur réside sur le tas et ils sont passés par référence lors des différents appels de méthodes. Depuis Java 1.5, la conversion entre les types primitifs et types wrapper est automatique.&lt;br /&gt;
&lt;br /&gt;

En C# comme en Java, les classes sont des types références.

&lt;h2&gt;Structures&lt;/h2&gt;

Le langage C# introduit un type de données qui n’existe pas en Java : le type structure. Les structures sont un type de données semblable aux classes, sauf qu’elles sont de types valeur, et non de type référence.&lt;br /&gt;
&lt;br /&gt;

Cette différence implique que les structures sont stockées sur la pile (et non sur le tas, contrairement aux
objets), et qu’elles sont passées par valeur en paramètre aux méthodes.&lt;br /&gt;
&lt;br /&gt;

De par leur statut particulier, les structures ont cependant quelques fonctionnalités en moins par rapport aux classes. Il est impossible par exemple d’hériter d’une structure en C#.

&lt;h2&gt;Enumérations&lt;/h2&gt;

En Java, les énumérations sont des objets. Comme pour les objets, il est possible de leur définir des attributs, des méthodes, et même des constructeurs.&lt;br /&gt;
&lt;br /&gt;

Contrairement à cela, en C#, les énumérations sont de type valeur. Les énumérations correspondent à des
entiers codés sur 8, 16, 32 ou 64 bits. Il est également possible d’assigner n’importe quelle valeur numérique à une énumération (y compris des valeurs non définies dans l’énumération), ainsi que de combiner plusieurs valeurs pour une même énumération grâce à l’opérateur | (bitwise or).

&lt;h2&gt;Espaces de nommages&lt;/h2&gt;

Lors du développement d’applications, il arrive que plusieurs structures de données (classes, interfaces,
énumérations...) possèdent le même nom. Afin d’éviter les collisions de noms ainsi générées, chaque langage à
mis en place sa propre solution : les espaces de nommages.&lt;br /&gt;
&lt;br /&gt;

En Java, un espace de nommage s’appelle un package. Un package doit être déclaré en début de tout fichier
source grâce au mot clé &lt;code&gt;package&lt;/code&gt; suivi du nom du package, et s’applique à tout le fichier. Il est possible d’accéder à des classes appartenant à d’autres packages grâce au mot clé &lt;code&gt;import&lt;/code&gt;, suivi du nom de la classe à importer. Il est également possible d’importer toutes les classes d’un package en utilisant l’étoile (*).&lt;br /&gt;
&lt;br /&gt;

En C#, un espace de nommage s’appelle un namespace. Un namespace est un bloc de code, noté grâce au mot
clé &lt;code&gt;namespace&lt;/code&gt;, suivi du nom du namespace. Il est possible d’utiliser des classes appartenant à d’autres espaces de noms grâce au mot clé &lt;code&gt;using&lt;/code&gt;, suivi du nom de l’espace de nom à utiliser.&lt;br /&gt;
&lt;br /&gt;

Voici par exemple la déclaration de deux classes dans un espace de nommage, en Java (à gauche) et en C# (à droite) :
&lt;div style="float: left; width: 48%;"&gt;
&lt;pre name="code" class="java"&gt;
package ns;

class Toto {
}

class Tata {
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;

&lt;div style="float: right; width: 48%;"&gt;
&lt;pre name="code" class="c-sharp"&gt;
namespace Ns
{
    class Toto
    {
    }
    class Tata
    {
    }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;br style="clear: both;" /&gt;

&lt;h2&gt;Types génériques&lt;/h2&gt;

Java et C# implémentent tous les deux les types génériques. Si l’utilisation est similaire dans les deux langages, leurs implémentations sont cependant très différentes.&lt;br /&gt;
&lt;br /&gt;

Premier point, les types génériques en Java n’acceptent pas les types primitifs, alors que l’implémentation en C# accepte les types valeurs.&lt;br /&gt;
&lt;br /&gt;

Second point, les génériques en Java sont implémentés selon une technique dite du type erasure. Derrière ce
nom effrayant se cache un concept simple : les génériques en Java sont évalués à la compilation, toute trace de type générique n’existe plus à l’exécution. C’est le compilateur qui va se charger de transformer les types génériques en leurs opérations équivalentes (principalement du transtypage et des vérifications de types), et supprimer toute trace de leur passage.&lt;br /&gt;
&lt;br /&gt;

Contrairement à cela, les génériques en C# persistent à l’exécution, et sont interprétés par l’environnement
d’exécution. Il est donc possible de connaître le type générique d’une classe ou d’une méthode lors de
l’exécution.&lt;br /&gt;
&lt;br /&gt;

Les conséquences sont alors multiples. Par exemple, en C#, il est possible de créer une instance d’un type
générique, et des tableaux de types génériques, choses qui sont impossibles à faire en Java, principalement à
cause du type erasure.&lt;br /&gt;
&lt;br /&gt;

Autre différence importante, il est possible d’effectuer des vérifications plus poussées sur les types utilisés en tant que types génériques dans le langage C#. Par exemple, en C#, il est possible de définir une contrainte « Cette classe utilise un type T, qui doit posséder un constructeur par défaut », contrainte qui est impossible en Java.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;

Voilà donc la fin de cette liste de différences entre Java et C# en ce qui concerne les types de données.&lt;br /&gt;
&lt;br /&gt;

Le prochain billet portera sur les opérateurs, et devrait parler de deux fonctionnalités présentes en C# et inexistantes en Java : la surcharge des opérateurs et les indexeurs.&lt;br /&gt;
&lt;br /&gt;

PS : Ceci était de &lt;a href="http://fr.wikipedia.org/wiki/La_Grande_Question_sur_la_Vie,_l%27Univers_et_le_Reste"&gt;42&lt;/a&gt;ème billet de ce blog ;-)</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/java_net_types_de_donn%C3%A9es</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/java_net_concepts_%C3%A9l%C3%A9mentaires</guid>
    <title>Java/.NET : Concepts élémentaires</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/zXQFQHZuoUs/java_net_concepts_%C3%A9l%C3%A9mentaires</link>
        <pubDate>Mon, 22 Sep 2008 08:33:23 +0100</pubDate>
    <category>.NET</category>
    <category>.net</category>
    <category>execution</category>
    <category>compilation</category>
    <category>java</category>
            <description>Dans ce premier billet de la série consacrée aux différences entre Java et .NET, nous allons voir les concepts élémentaires des deux plateformes.&lt;br /&gt;
&lt;br /&gt;

Les concepts élémentaires au niveau des deux technologies sont très similaires. Les deux s’appuient sur le même principe : la compilation est effectuée vers un langage intermédiaire. Ce langage intermédiaire est proche du langage machine, mais indépendant de l’architecture et du système. Il sera ensuite exécuté par une machine virtuelle au moment de l’exécution du programme. Ce principe permet d’assurer une certaine portabilité entre les différents systèmes d’exploitation et les différentes architectures matérielles.

&lt;h2&gt;Compilation&lt;/h2&gt;

Le compilateur C# s’appelle CSC (C-Sharp Compiler). Il est chargé de traduire le code source C# en code MSIL
(Microsoft Intermediate Language), un langage intermédiaire qui sera ensuite exécuté par l’environnement
d’exécution de la plateforme .NET.&lt;br /&gt;
&lt;br /&gt;

Le compilateur Java est appelé Javac (Java Compiler), et son rôle est de transformer le code source Java en ByteCode, qui est le langage intermédiaire de la plateforme Java.&lt;br /&gt;
&lt;br /&gt;

Les deux compilateurs comportent également des fonctionnalités plus poussées. Chacun des compilateurs est
capable, par exemple, d’optimiser le code source au moment de la compilation afin d’en améliorer les performances. Il n’y a pas de différence majeure à ce niveau là.

&lt;h2&gt;Environnement d'exécution&lt;/h2&gt;

L’environnement d’exécution .NET est construit autour de la CLR (Common Language Runtime). Il s’agit de la
machine virtuelle chargée d’exécuter le code MSIL généré par le compilateur.&lt;br /&gt;
&lt;br /&gt;

De son coté, l’environnement d’exécution Java tourne autour de la JVM (Java Virtual Machine). Son rôle sera
d’exécuter le ByteCode, afin de permettre l’exécution de nos programmes.&lt;br /&gt;
&lt;br /&gt;

Les deux machines virtuelles sont très proches, et sont conçues de manière semblable. Les deux embarquent un
chargeur de classe (Class Loader), un compilateur JIT (Just In Time) qui transforme le code intermédiaire en code natif afin d’accélérer l’exécution, d’un ramasse miettes (Garbage Collector) qui libère la mémoire qui n’est plus utilisée par le programme, ainsi que d’autres composants permettant d’assurer le bon fonctionnement de nos logiciels (sécurité des applications, interaction avec le système, ...).&lt;br /&gt;
&lt;br /&gt;

La principale différence au niveau de l’environnement d’exécution est la portabilité de celui-ci. Alors qu’il existe une machine virtuelle Java pour la plupart des systèmes d’exploitation du marché, la CLR de Microsoft est développée uniquement pour Windows. Même si Microsoft à fait des efforts ces derniers temps pour porter la CLR vers d’autres systèmes (notamment grâce au projet Mono), la plateforme .NET est loin de posséder la même portabilité que la plateforme Java.

&lt;h2&gt;Bibliothèques de base&lt;/h2&gt;

Chacun des deux environnements embarque une bibliothèque de base. Ces bibliothèques sont des ensembles
de composants prêts à l’emploi, qui permettent de faciliter le développement d’applications. Sur les deux
plateformes, nous retrouvons des composants semblables : interfaces graphiques, gestions des entrées-sorties, gestion de l’accès aux données (bases de données, annuaires LDAP, ...), gestion des processus...&lt;br /&gt;
&lt;br /&gt;

Les principales différences entre les deux ensembles de bibliothèques embarquées se trouvent dans les noms
attribués aux classes et aux méthodes, la plupart des composants présents dans l’une trouvant son équivalent
dans l’autre.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;

Ainsi s'achève ce premier billet portant sur les concepts élémentaires de chacune des plateforme. Comme nous l'avons vu, les différences sont assez minimes, et les principes globaux sont communs aux deux environnements.&lt;br /&gt;
&lt;br /&gt;

Dans le prochain billet, nous aborderont les différences qui touchent aux types de données (types primitifs/valeurs, types références, énumérations, ...).</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/java_net_concepts_%C3%A9l%C3%A9mentaires</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/java_net_introduction</guid>
    <title>Java/.NET : Introduction</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/Hbp7IKuCN1A/java_net_introduction</link>
        <pubDate>Fri, 12 Sep 2008 18:22:29 +0100</pubDate>
    <category>.NET</category>
    <category>.net</category>
    <category>java</category>
            <description>Ça y est !&lt;br /&gt;
&lt;br /&gt;

Je viens de finir une (longue) période de formation. J'ai été invité à suivre une formation de trois semaines, qui s'est terminée aujourd'hui, au &lt;a href="http://www.supinfo-training.com/"&gt;SUPINFO Training Center&lt;/a&gt;, portant sur les technologies .NET, et en particulier :
&lt;ul&gt;
    &lt;li&gt;Framework .NET 2.0, base du développement d’application&lt;/li&gt;
    &lt;li&gt;Windows Forms, Accés aux données avec Visual Studio 2005&lt;/li&gt;
    &lt;li&gt;Création et programmation d’une application Web ASP.NET 2.0&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

Étant formateur Sun (et donc, Java), le but de cette formation était de comparer les deux technologies. Loin de moi l'idée d'abandonner le Java pour me mettre au .NET (j'ai déjà vendu mon âme :P). Il s'agissait là d'une ouverture d'esprit, de la découverte d'une autre technologie afin de mieux pouvoir défendre la sienne.&lt;br /&gt;
&lt;br /&gt;

La formation en elle-même était très intéressante. Les deux premières semaines (Framework 2.0 et Windows Forms) furent dispensées par &lt;a href="http://www.juliencorioland.net/"&gt;Julien Corioland&lt;/a&gt;, la dernière par Maxime Schneider (je tiens à les remercier tous les deux). Le seul point noir que j'aurais à souligner concerne le cursus en lui même, qui portait sur le framework 2.0 alors que la version la plus récente est la 3.5, et que les changement entre les deux versions sont importants (&lt;a href="http://fr.wikipedia.org/wiki/Windows_Presentation_Foundation"&gt;WPF&lt;/a&gt;, &lt;a href="http://fr.wikipedia.org/wiki/Windows_Communication_Foundation"&gt;WCF&lt;/a&gt;, &lt;a href="http://fr.wikipedia.org/wiki/LINQ"&gt;Linq&lt;/a&gt;, ...).&lt;br /&gt;
&lt;br /&gt;

J'ai déjà fait un petit résumé de cette formation en 140 caractères (&lt;a href="http://twitter.com/Onejjy/statuses/918802404"&gt;à la demande&lt;/a&gt; de &lt;a href="http://webd.fr/"&gt;Julien Quéré&lt;/a&gt;) :
&lt;blockquote&gt;
Il y a quelques fonctionnalités interessantes (properties, delegates, ...), mais mon coeur reste chez Java :-)
&lt;/blockquote&gt;
&lt;br /&gt;

Je pense que cette citation est celle qui résume le mieux ce que je pense de ces trois dernières semaines.&lt;br /&gt;
&lt;br /&gt;

Je vais maintenant entamer (continuer serait plus exact, j'ai déjà un peu commencé :P) un gros feedback sur ce que j'ai retenu de cette formation : les principales différences entre Java et .NET.&lt;br /&gt;
&lt;br /&gt;

Ceux qui me connaissent le savent, je suis un excellent trolleur. Et ils n'ont pas complètement tort. Je vais cependant essayer d'être le plus objectif possible :-)&lt;br /&gt;
&lt;br /&gt;

Ce billet est donc le premier d'une série qui relatera les différences que j'ai constaté, retenu, et qui ont, à mon avis, leur importance, pour le développeur qui souhaite comparer les deux plateformes de développement.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;

Petite remarque au passage : Ce billet était aussi le billet de la rentrée. En effet, je n'avais pas publié de billets, pour des raisons diverses et variées, depuis environ deux mois. La rentrée étant arrivée, mon rythme de publication devrait redevenir un peu plus... soutenu :-)</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/java_net_introduction</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/r%C3%A9daction_estivale</guid>
    <title>Rédaction estivale</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/S4Z_6295NUw/r%C3%A9daction_estivale</link>
        <pubDate>Tue, 15 Jul 2008 02:34:49 +0100</pubDate>
    <category>General</category>
    <category>blog</category>
            <description>Une fois n'est pas coutume, je vais parler de moi.&lt;br /&gt;
&lt;br /&gt;

Comme ceux qui me suivent fréquemment ont pu le constater, mon rythme de rédaction s'est énormément ralenti ces derniers temps, principalement depuis le début du mois de juin. Je vais essayer d'en expliquer les raisons et de rassurer certains de mes lecteurs pour la suite. La raison pour laquelle je ne blogue plus beaucoup ces derniers temps est presque évidente.&lt;br /&gt;
&lt;br /&gt;

C'est la fin de l'année scolaire&lt;br /&gt;
&lt;br /&gt;

Les étudiants sont partis en stage, alors que le mien ne commence que début août. Je suis en quelque sorte en vacances. Mon blog est nourri principalement d'échanges avec les gens que je côtoie tous les jours à SUPINFO, avec les élèves. Depuis la fin du mois de juin, le nombre de personnes avec lesquelles je discute "Java" à fortement diminué. D'où une baisse des questions qui nécessitent une réponse. D'où une baisse du nombre d'articles sur ce blog.&lt;br /&gt;
&lt;br /&gt;

Mon stage commence précisément le 4 août. Mon rôle sera de préparer les PEFF (Peut-être futurs formateurs, comme dirait &lt;a href="http://madd0.com/"&gt;Mauricio&lt;/a&gt;) afin qu'ils soient capables de dispenser des cours dès le mois d'octobre. Ce "stage" s'est révélé très intéressant l'an dernier, notamment grâce à une intervention de &lt;a href="http://blogs.sun.com/alexismp/"&gt;Alexis Moussine-Pouchkine&lt;/a&gt; sur &lt;a href="http://glassfish.org/"&gt;GlassFish&lt;/a&gt;. J'espère que celui de cette année le sera tout autant. Entouré de geeks du Java, de geeks tout court, j'espère pouvoir reprendre mes échanges sur le monde Java, pouvoir reprendre plus activement la rédaction de ce blog.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;

En attendant le début du mois d'août, d'ici deux semaines, je ne bloguerais quasiment pas. Pour ceux qui cherchent désespérément de la lecture, je peux vous conseiller pour l'été :
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://dunod.com/pages/ouvrages/ficheouvrage.asp?id=51831"&gt;"EJB 3 - Des concepts à l'écriture du code. Guide du développeur"&lt;/a&gt;, écrit par le &lt;a href="http://dunod.com/pages/ouvrages/ficheouvrage.asp?id=51831"&gt;laboratoire Sun&lt;/a&gt; (et auquel j'ai participé), chez &lt;a href="http://dunod.com/"&gt;Dunod&lt;/a&gt;. La seconde édition est sortie il y a à peine quelques jours. Je n'en avais pas encore parlé, voilà qui est chose faite.&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://javablogs.com/"&gt;Java.Blogs&lt;/a&gt;. À mon avis un des meilleurs agrégateurs de blogs Java, très utile pour se tenir au courant des tendances actuelles.&lt;/li&gt;
&lt;/ul&gt;</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/r%C3%A9daction_estivale</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/netbeans_6_5_en_approche</guid>
    <title>NetBeans 6.5 en approche</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/CSXzT7lVJ0w/netbeans_6_5_en_approche</link>
        <pubDate>Tue, 8 Jul 2008 10:03:03 +0100</pubDate>
    <category>NetBeans</category>
    <category>6.5m1</category>
    <category>sortie</category>
    <category>6.5</category>
    <category>netbeans</category>
            <description>La blogosphère en parle beaucoup depuis ce matin (&lt;a href="http://blogs.sun.com/nbprofiler/entry/netbeans_ide_6_5_milestone"&gt;ici&lt;/a&gt;, &lt;a href="http://cld.blog-city.com/netbeans_65_milestone_1_available___new_features_and_more.htm"&gt;là&lt;/a&gt;, ou encore &lt;a href="http://blogs.sun.com/theaquarium/entry/netbeans_6_5_m1_now"&gt;là&lt;/a&gt;), la première milestone de NetBeans 6.5 est sortie.&lt;br /&gt;
&lt;br /&gt;

L'&lt;a href="http://www.netbeans.org/servlets/NewsItemView?newsItemID=1254"&gt;annonce officielle&lt;/a&gt; nous propose un petit aperçu des nouvelles fonctionnalités.&lt;br /&gt;
&lt;br /&gt;

La nouveauté majeure de cette version 6.5 semble l'apparition de l'éditeur PHP (&lt;a href="http://wiki.netbeans.org/NewAndNoteWorthyMilestone1NB65#section-NewAndNoteWorthyMilestone1NB65-PHP"&gt;présentation des fonctionnalités&lt;/a&gt;, &lt;a href="http://www.netbeans.org/kb/docs/php/php-editor-screencast.html"&gt;screencast&lt;/a&gt;, &lt;a href="http://www.netbeans.org/kb/trails/php.html"&gt;tutorial&lt;/a&gt;). Le blog &lt;a href="http://blogs.sun.com/netbeansphp/"&gt;NetBeans for PHP&lt;/a&gt; à également fait son apparition récemment.&lt;br /&gt;
&lt;br /&gt;

D'autres améliorations sont également au programme, notamment en ce qui concerne les éditeurs JavaScript (Ajax), Groovy et Java.&lt;br /&gt;
&lt;br /&gt;

Le meilleur moyen de se faire une idée reste encore et toujours de la tester par soi même. Téléchargement &lt;a href="http://bits.netbeans.org/netbeans/6.5/m1/"&gt;ici&lt;/a&gt;.</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/netbeans_6_5_en_approche</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/changement_de_serveur</guid>
    <title>Changement de serveur</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/aqqZS5QRJYY/changement_de_serveur</link>
        <pubDate>Wed, 2 Jul 2008 23:49:40 +0100</pubDate>
    <category>General</category>
    <category>changement</category>
    <category>glassfish</category>
    <category>serveur</category>
    <category>blog</category>
            <description>Si vous lisez ces quelques lignes, c'est que je ne me serais planté nulle part. Ou du moins que mes erreurs ne sont pas critiques.&lt;br /&gt;
&lt;br /&gt;

La résiliation de l'abonnement Internet étant en cours, mon blog, qui était jusqu'à présent hébergé chez moi, avait devant lui des jours qui lui étaient comptés.&lt;br /&gt;
&lt;br /&gt;

C'est pour cela que j'ai migré mon installation de Roller vers un nouveau serveur, loué pour l'été (voire plus...) chez &lt;a href="http://www.ovh.com/"&gt;OVH&lt;/a&gt; (un &lt;a href="http://www.ovh.com/fr/particulier/produits/kimsufi08.xml"&gt;Kimsufi&lt;/a&gt;, qui me suffit pour l'instant).&lt;br /&gt;
&lt;br /&gt;

A première vue tout marche, j'essayerais de réparer les éventuels défauts dans les jours à venir... En attendant, bonne lecture :)</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/changement_de_serveur</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/astuce_java_6_enum_et</guid>
    <title>Astuce Java #6 : Enum et toString</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/bDh2ndEDfU0/astuce_java_6_enum_et</link>
        <pubDate>Fri, 20 Jun 2008 17:01:03 +0100</pubDate>
    <category>Java</category>
    <category>astuce</category>
    <category>tostring</category>
    <category>java</category>
    <category>enum</category>
            <description>Depuis Java 5, le langage Java dispose d'une nouvelle fonctionnalité : les énumérations.&lt;br /&gt;
&lt;br /&gt;

Les énumérations sont des structures permettant de représenter une variable ayant un nombre fini de valeurs, comme par exemple le sexe d'une personne, qui sera soit "homme", soit "femme".&lt;br /&gt;
&lt;br /&gt;

Les énumérations sont mises en place de la manière suivante :
&lt;pre name="code" class="java"&gt;
enum Sex {
    MALE,
    FEMALE;
}
&lt;/pre&gt;
&lt;br /&gt;

Il est ensuite possible de créer des variables du type de l'énumération, et de les utiliser :
&lt;pre name="code" class="java"&gt;
Sex sex = Sex.MALE;
System.out.println(sex);
&lt;/pre&gt;
&lt;br /&gt;

Et c'est là qu'apparaît notre problème : la console nous affiche "MALE". Certes, il s'agit de la bonne valeur, mais la présentation n'est pas très esthétique. Heureusement pour nous, en Java une énumération est également un objet. Il nous est possible de définir nos propres méthodes, et aussi de récrire certaines méthodes de la classe &lt;code&gt;Object&lt;/code&gt;. Ainsi, on peut avoir le code suivant :
&lt;pre name="code" class="java"&gt;
enum Sex {
    MALE,
    FEMALE;
    
    @Override
    public String toString() {
        switch (this) {
            case MALE:
                return ("Male");
            case FEMALE:
                return ("Female");
        }
        throw new RuntimeException("Invalid value for this");
    }
}
&lt;/pre&gt;
&lt;br /&gt;

L'exécution du même code nous donne ainsi "Male" au lieu de "MALE". On obtient le résultat souhaité, à savoir une chaîne de caractères plus facilement lisible par l'utilisateur.&lt;br /&gt;
&lt;br /&gt;

Le soucis que l'on rencontre maintenant viens du &lt;code&gt;switch&lt;/code&gt; dans la méthode &lt;code&gt;toString&lt;/code&gt;. Nous devons gérer toutes les valeurs possible dans cette méthode, sous peine de lancer une &lt;code&gt;RuntimeException&lt;/code&gt;.
Une des solutions possibles (que j'ai trouvé dans &lt;a href="http://javahowto.blogspot.com/2006/10/custom-string-values-for-enum.html?showComment=1181494800000#c7079865162172472427"&gt;un commentaire&lt;/a&gt; d'un (très) vieux &lt;a href="http://javahowto.blogspot.com/2006/10/custom-string-values-for-enum.html"&gt;billet de blog&lt;/a&gt;), et que je trouve de loin ma préférée, est de fournir un constructeur à notre énumération. Ce constructeur prend en paramètre une chaîne de caractères qui sera utilisée en tant que valeur de retour de la méthode &lt;code&gt;toString&lt;/code&gt; :
&lt;pre name="code" class="java"&gt;
enum Sex {
    MALE("Male"),
    FEMALE("Female");
    
    private String value;
    
    private Sex(String value) {
        this.value = value;
    }
    
    @Override
    public String toString() {
        return (value);
    }
}
&lt;/pre&gt;
&lt;br /&gt;

Ainsi, nous obtenons on comportement optimal :
&lt;ul&gt;
    &lt;li&gt;Chaque valeur de l'énumération renverra une chaîne de caractères "esthétique" représentant sa valeur&lt;/li&gt;
    &lt;li&gt;Chaque valeur &lt;b&gt;devra&lt;/b&gt; posséder une chaîne de caractères (au risque de générer une erreur de compilation)&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

Le problème majeur qui est ainsi rencontré concerne la conversion énumération -&gt; chaîne de caractères -&gt; énumération. La chaîne de caractères renvoyait de base par &lt;code&gt;toString&lt;/code&gt; était le nom de la constante dans l'énumération (MALE ou FEMALE dans notre cas), qui pouvait ensuite être reconverti en énumération via la méthode &lt;code&gt;valueOf&lt;/code&gt;. Dans notre cas, la conversion ne se ferra plus puisque &lt;code&gt;toString&lt;/code&gt; ne renverra plus une valeur compréhensible par &lt;code&gt;valueOf&lt;/code&gt;. Cependant, la méthode &lt;code&gt;name&lt;/code&gt;, définie dans toute énumération, renvoie toujours le nom de la constante tel que définit dans le code.</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/astuce_java_6_enum_et</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/syst%C3%A8me_d_inclusion_en_jsf</guid>
    <title>Système d'inclusion en JSF</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/c2ILv3phL8s/syst%C3%A8me_d_inclusion_en_jsf</link>
        <pubDate>Fri, 6 Jun 2008 14:55:25 +0100</pubDate>
    <category>Java</category>
    <category>java</category>
    <category>jsf</category>
    <category>javaee</category>
            <description>Pour éviter les erreurs, voici un rapide rappel pour faire de l'inclusion de pages en JSF. Cet article contient un exemple de code classique, puis quelques points à ne pas oublier pour que tout se passe bien.&lt;br /&gt;
&lt;br /&gt;

Le but de cet exemple sera d'avoir une page &lt;code&gt;index.jsp&lt;/code&gt; qui inclue une page &lt;code&gt;content.jsp&lt;/code&gt;.

&lt;h2&gt;&lt;code&gt;index.jsp&lt;/code&gt;&lt;/h2&gt;
&lt;pre name="code" class="xml"&gt;
&amp;lt;%@page contentType="text/html"%&gt;
&amp;lt;%@page pageEncoding="UTF-8"%&gt;

&amp;lt;%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%&gt;
&amp;lt;%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%&gt;

&amp;lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd"&gt;

&amp;lt;html&gt;
    &amp;lt;head&gt;
        &amp;lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;
        &amp;lt;title&gt;JSP Page&amp;lt;/title&gt;
    &amp;lt;/head&gt;
    &amp;lt;body&gt;
        &amp;lt;f:view&gt;
            &amp;lt;f:subview id="content"&gt;
                &amp;lt;jsp:include page="content.jsp" flush="false" /&gt;
            &amp;lt;/f:subview&gt;
        &amp;lt;/f:view&gt;
    &amp;lt;/body&gt;
&amp;lt;/html&gt;
&lt;/pre&gt;

&lt;h2&gt;&lt;code&gt;content.jsp&lt;/code&gt;&lt;/h2&gt;

&lt;pre name="code" class="xml"&gt;
&amp;lt;%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%&gt;
&amp;lt;%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%&gt;

&amp;lt;h:outputText value="Ceci est le contenu !" /&gt;
&lt;/pre&gt;

&lt;h2&gt;Points importants&lt;/h2&gt;

Il existe quelques règles assez importantes pour que ce système d'inclusion de page marche correctement :
&lt;ul&gt;
    &lt;li&gt;Dans la page de base, entourer l'inclusion avec une balise &lt;code&gt;&amp;lt;f:subview /&gt;&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;Lors de l'inclusion, penser à mettre l'attribut &lt;code&gt;flush&lt;/code&gt; à &lt;code&gt;false&lt;/code&gt;. Cet attribut existe sur la plupart des balises permettant l'inclusion de pages.&lt;/li&gt;
    &lt;li&gt;Dans la page de destination, réutiliser les composants JSF directement, sans remettre de balise &lt;code&gt;&amp;lt;f:view /&gt;&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;Les taglibs doivent quand à elles être réimportées.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

Et voilà le résultat (en HTML) :
&lt;pre name="code" class="xml"&gt;
&amp;lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd"&gt;

&amp;lt;html&gt;
    &amp;lt;head&gt;
        &amp;lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;
        &amp;lt;title&gt;JSP Page&amp;lt;/title&gt;
    &amp;lt;/head&gt;

    &amp;lt;body&gt;
        Ceci est le contenu !
    &amp;lt;/body&gt;
&amp;lt;/html&gt;
&lt;/pre&gt;
&lt;br /&gt;

&lt;a href="http://martin.filliau.com/blog/"&gt;Martin&lt;/a&gt; en &lt;a href="http://martin.filliau.com/blog/2008/06/06/inserer-une-page-jsf-dans-une-autre-page-jsf/"&gt;parle également&lt;/a&gt;.
</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/syst%C3%A8me_d_inclusion_en_jsf</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/optimisation_utilisation_d_un_pool</guid>
    <title>Optimisation : Utilisation d'un pool d'objets</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/9jRtLctSiJ0/optimisation_utilisation_d_un_pool</link>
        <pubDate>Sat, 31 May 2008 20:30:11 +0100</pubDate>
    <category>Java</category>
    <category>optimisation</category>
    <category>pool</category>
    <category>java</category>
            <description>J'ai lu récemment une série d'articles&lt;sup&gt;&lt;a href="http://javabyexample.wisdomplug.com/java-concepts/51-make-your-java-applications-run-faster-part-1-compiler-optimizations.html"&gt;1&lt;/a&gt; &lt;a href="http://javabyexample.wisdomplug.com/java-concepts/34-core-java/52-make-your-java-applications-run-faster-part-2-general-optimization-techniques.html"&gt;2&lt;/a&gt; &lt;a href="http://javabyexample.wisdomplug.com/java-concepts/34-core-java/53-make-your-java-applications-run-faster-part-3-variables-and-arrays.html"&gt;3&lt;/a&gt; &lt;a href="http://javabyexample.wisdomplug.com/java-concepts/34-core-java/54-make-your-java-applications-run-faster-part-4-methods-synchronization-instantiation-casting-exceptions-and-threads.html"&gt;4&lt;/a&gt;&lt;/sup&gt; très intéressants ayant pour sujet l'optimisation des programmes Java. La &lt;a href="http://javabyexample.wisdomplug.com/java-concepts/34-core-java/54-make-your-java-applications-run-faster-part-4-methods-synchronization-instantiation-casting-exceptions-and-threads.html"&gt;dernière partie&lt;/a&gt; parlait de la réutilisation des objets. Un exemple montrait qu'il était plus performant de vider un &lt;code&gt;ArrayList&lt;/code&gt; que de créer une nouvelle instance :&lt;br /&gt;
&lt;br /&gt;

&lt;div style="float: left; width: 48%;"&gt;
&lt;pre name="code" class="java"&gt;
for (int i = 0; i &lt; 10; i++) {
    ArrayList list = new ArrayList();
    // Do some stuff...
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="float: right; width: 48%;"&gt;
&lt;pre name="code" class="java"&gt;
ArrayList list = new ArrayList();
for (int i = 0; i &lt; 10; i++) {
    // Do some stuff...
    list.clear();
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;br style="clear: both;" /&gt;

Dans notre cas, appeler un constructeur est plus coûteux en temps processeur que de simplement supprimer tous les éléments de notre liste (la raison &lt;a href="http://groups.google.com/group/comp.lang.java.programmer/browse_thread/thread/dc794c1cf33cda1b#"&gt;a été discutée&lt;/a&gt; sur &lt;a href="http://groups.google.com/group/comp.lang.java.programmer/topics"&gt;comp.lang.java.programmer&lt;/a&gt;). Le code de droite est donc plus rapide à l'exécution.&lt;br /&gt;
&lt;br /&gt;

J'ai alors eu l'idée de me lancer dans la création d'un pool d'objets. Dans le cas des &lt;code&gt;ArrayList&lt;/code&gt;, le but serait de vider notre instance et de la conserver en attendant de la réutiliser plus tard.&lt;br /&gt;
&lt;br /&gt;

J'ai donc testé le code suivant :
&lt;pre name="code" class="java"&gt;
public class ArrayListPool&amp;lt;T&gt; {

    private Queue&amp;lt;ArrayList&amp;lt;T&gt;&gt; pool;
    
    public ArrayListPool() {
        pool = new LinkedList&amp;lt;ArrayList&amp;lt;T&gt;&gt;();
    }
    
    public ArrayList&amp;lt;T&gt; getArrayList() {
        synchronized (pool) {
            if (!pool.isEmpty()) {
                return (pool.poll());
            }
        }
        return (new ArrayList&amp;lt;T&gt;());
    }
    
    public void releaseArrayList(ArrayList&amp;lt;T&gt; list) {
        list.clear();
        synchronized (pool) {
            pool.offer(list);
        }
    }
    
    public void clear() {
        synchronized (pool) {
            pool.clear();
        }
    }
}
&lt;/pre&gt;
&lt;br /&gt;

Le but est d'appeler &lt;code&gt;getArrayList&lt;/code&gt; pour obtenir une instance d'un &lt;code&gt;ArrayList&lt;/code&gt;, et de la passer en paramètre à la méthode &lt;code&gt;releaseArrayList&lt;/code&gt; pour la remettre dans le pool et la réutiliser au besoin.&lt;br /&gt;
&lt;br /&gt;

Concernant les détails de fonctionnement, je me suis servi d'une &lt;code&gt;LinkedList&lt;/code&gt; pour stocker les objets à réutiliser. Cette implémentation de &lt;code&gt;Queue&lt;/code&gt; est basée sur une liste chaînée, ainsi les insertion et les suppressions d'éléments dans le pool sont très rapides.&lt;br /&gt;
&lt;br /&gt;

Enfin, l'utilisation de ce pool. À gauche, le code de base, qui servira de benchmark par la suite. À droite, le code modifié pour utiliser le pool.

&lt;div style="float: left; width: 48%;"&gt;
&lt;pre name="code" class="java"&gt;
ThreadGroup group2 = new ThreadGroup("Group 2");
for (int i = 0; i &lt; threadCount; i++) {
    Thread t = new Thread(group2, "Thread " + i) {
        @Override
        public void run() {
            for (int i = 0; i &lt; listCount; i++) {
                ArrayList&amp;lt;Object&gt; list = new ArrayList&amp;lt;Object&gt;();
                for (int j = 0; j &lt; objectCount; j++) {
                    list.add(new Object());
                }
            }
        }
    };
    t.start();
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="float: right; width: 48%;"&gt;
&lt;pre name="code" class="java"&gt;
final ArrayListPool&amp;lt;Object&gt; pool = new ArrayListPool&amp;lt;Object&gt;();
ThreadGroup group1 = new ThreadGroup("Group 1");
for (int i = 0; i &lt; threadCount; i++) {
    Thread t = new Thread(group1, "Thread " + i) {
        @Override
        public void run() {
            for (int i = 0; i &lt; listCount; i++) {
                ArrayList&amp;lt;Object&gt; list = pool.getArrayList();
                for (int j = 0; j &lt; objectCount; j++) {
                    list.add(new Object());
                }
                pool.releaseArrayList(list);
            }
        }
    };
    t.start();
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;br style="clear: both;" /&gt;

Après exécution de ce code en tant que benchmark, voici les résultats :&lt;br /&gt;&lt;br /&gt;
&lt;center&gt;
&lt;table border="1" style="border-collapse: collapse; font-size: 1em;"&gt;
    &lt;tr&gt;
        &lt;td&gt;threadCount&lt;/td&gt;
        &lt;td&gt;listCount&lt;/td&gt;
        &lt;td&gt;objectCount&lt;/td&gt;
        &lt;td&gt;Temps avec pool (ms)&lt;/td&gt;
        &lt;td&gt;Temps sans pool (ms)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;100&lt;/td&gt;
        &lt;td&gt;100&lt;/td&gt;
        &lt;td&gt;100&lt;/td&gt;
        &lt;td&gt;65&lt;/td&gt;
        &lt;td&gt;82&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;10&lt;/td&gt;
        &lt;td&gt;100000&lt;/td&gt;
        &lt;td&gt;100&lt;/td&gt;
        &lt;td&gt;1961&lt;/td&gt;
        &lt;td&gt;2051&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;100&lt;/td&gt;
        &lt;td&gt;100000&lt;/td&gt;
        &lt;td&gt;100&lt;/td&gt;
        &lt;td&gt;17484&lt;/td&gt;
        &lt;td&gt;24950&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;/center&gt;
&lt;br /&gt;
&lt;br /&gt;

Le temps d'exécution est légèrement réduit. En contrepartie, après analyse de l'application de test grâce au Profiler de NetBeans, la consommation mémoire est d'environ 2 Mo supplémentaires pour 100 objets en attente dans le pool. Cette solution est donc intéressante à mettre en place pour des objets dont l'instanciation est très fréquente. Dans le cas où les instanciations se font plus rares, le gain en temps CPU est négligeable, et la consommation mémoire est plus étalée dans le temps.</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/optimisation_utilisation_d_un_pool</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/glassfish_v3tp2</guid>
    <title>GlassFish v3tp2</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/GlELZuVXPBA/glassfish_v3tp2</link>
        <pubDate>Fri, 30 May 2008 18:06:10 +0100</pubDate>
    <category>GlassFish</category>
    <category>glassfish</category>
            <description>Je sais que &lt;a href="http://glassfish.dev.java.net/"&gt;GlassFish&lt;/a&gt; &lt;a href="https://glassfish.dev.java.net/downloads/install/v3-preview2.html"&gt;v3tp2&lt;/a&gt; est sorti depuis un petit bout de temps, mais je viens juste de le télécharger...&lt;br /&gt;
&lt;br /&gt;

Ma première impression ?&lt;br /&gt;
&lt;br /&gt;

Ça fait vraiment très bizarre :
&lt;pre&gt;
viv@Eudoxe:~/Programs/glassfish-v3tp2$ time ./bin/asadmin start-domain
Command start-domain executed successfully.

real	0m0.976s
user	0m0.720s
sys	0m0.056s
viv@Eudoxe:~/Programs/glassfish-v3tp2$ time ./bin/asadmin stop-domain
Command stop-domain executed successfully.

real	0m0.553s
user	0m0.640s
sys	0m0.056s
&lt;/pre&gt;
&lt;br /&gt;

Temps de démarrage de moins de une seconde, temps d'arrêt d'environ une demi seconde...&lt;br /&gt;
&lt;br /&gt;

Sinon, les premières choses qui changent :
&lt;ul&gt;
    &lt;li&gt;L'URL de l'interface d'administration. Ça paraît bête, mais j'ai mit bien 5 minutes à trouver la nouvelle (&lt;a href="http://localhost:8080/admin"&gt;&lt;code&gt;http://localhost:8080/admin&lt;/code&gt;&lt;/a&gt;)&lt;/li&gt;
    &lt;li&gt;Un déploiement d'applications bien plus rapide qu'avant&lt;/li&gt;
    &lt;li&gt;Le changement de fournisseur de persistance. GlassFish est passé de &lt;a href="http://www.oracle.com/technology/products/ias/toplink/index.html"&gt;Toplink&lt;/a&gt; à &lt;a href="http://www.eclipse.org/eclipselink/"&gt;EclipseLink&lt;/a&gt;, donc quelques petites modifications sont à faire dans les fichiers de configuration des applications spécifiques.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;

Le temps de tester un peu plus en profondeur et je pourrais donner un avis un peu plus complet, mais pour l'instant, je suis plutôt enthousiaste :)</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/glassfish_v3tp2</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/utiliser_un_certificat_ssl_avec</guid>
    <title>Utiliser un certificat SSL avec GlassFish</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/DXBJwBmLd9k/utiliser_un_certificat_ssl_avec</link>
        <pubDate>Wed, 28 May 2008 19:11:16 +0100</pubDate>
    <category>GlassFish</category>
    <category>ssl</category>
    <category>glassfish</category>
            <description>Après de nombreuses tentatives, c'est enfin fait ! Le certificat &lt;a href="http://fr.wikipedia.org/wiki/SSL"&gt;SSL&lt;/a&gt; de &lt;code&gt;*.aperigeek.com&lt;/code&gt; est valide.&lt;br /&gt;
&lt;br /&gt;

Voici les différentes étapes de mon aventure :&lt;br /&gt;
&lt;em&gt;Pour information, mon serveur GlassFish utilise JKS en tant que KeyStore. Il s'agit du KeyStore par défaut sur une installation basique de GlassFish.&lt;/em&gt;

&lt;h2&gt;Générer une paire de clés&lt;/h2&gt;
Le JDK embarque un outil permettant de gérer les KeyStore de type JKS. Cet outil porte le doux nom de &lt;code&gt;keytool&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;

La première étape est donc de générer une paire de clés. Ces clés seront utilisées pour chiffrer les données entre le client et le serveur.&lt;br /&gt;
&lt;br /&gt;

Pour générer une paire de clés, la commande magique est :
&lt;pre&gt;
$ keytool -genkeypair -keyalg &lt;em&gt;&amp;lt;algorithm&gt;&lt;/em&gt; -keystore &lt;em&gt;&amp;lt;keystore&gt;&lt;/em&gt; -validity &lt;em&gt;&amp;lt;validity&gt;&lt;/em&gt; -alias &lt;em&gt;&amp;lt;alias&gt;&lt;/em&gt;
&lt;/pre&gt;
&lt;em&gt;Petite note : Pour les utilisateurs du JDK 5, l'option &lt;code&gt;-genkeypair&lt;/code&gt; est à remplacer par &lt;code&gt;-genkey&lt;/code&gt;.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;

Les options à fournir :
&lt;ul&gt;
    &lt;li&gt;&lt;em&gt;&amp;lt;algorithm&gt;&lt;/em&gt; corresponds à l'algorithme utilisé pour générer les clés (RSA, par exemple).&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;&amp;lt;keystore&gt;&lt;/em&gt; corresponds au fichier contenant les clés du serveur. Par défault, ce fichier s'appelle &lt;code&gt;keystore.pks&lt;/code&gt; et est stocké dans &lt;code&gt;domains/domain/config&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;&amp;lt;validity&gt;&lt;/em&gt; corresponds au temps de validité du certificat, en jour (365 pour un an, par exemple).&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;&amp;lt;alias&gt;&lt;/em&gt; corresponds au nom que vous souhaitez donner au certificat. Ce nom sera réutilisé par la suite pour désigner ce certificat à l'intérieur du serveur d'application.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

&lt;code&gt;keytool&lt;/code&gt; vous posera plusieurs questions, notamment :
&lt;ul&gt;
    &lt;li&gt;Le mot de passe du KeyStore (par défaut, le mot de passe du KeyStore est &lt;code&gt;changeit&lt;/code&gt;).&lt;/li&gt;
    &lt;li&gt;Un CN (Common Name). Mettez le nom de domaine pour lequel vous souhaitez créer un certificat (il est possible d'utiliser un wildcard, comme par exemple &lt;code&gt;*.aperigeek.com&lt;/code&gt; pour tous les sous domaines aperigeek.com).&lt;/li&gt;
    &lt;li&gt;Les autres informations n'influent pas sur le certificat en lui même.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Générer une demande de certificat (CSR : Certificate Signing Request)&lt;/h2&gt;

Ce fichier CSR va permettre d'effectuer une demande de certificat auprès d'une &lt;a href="http://fr.wikipedia.org/wiki/Autorit%C3%A9_de_certification"&gt;autorité de certification&lt;/a&gt;. Ce certificat permettra de justifier de l'identité du serveur auprès du client (afin d'éviter certaines attaques de type &lt;a href="http://fr.wikipedia.org/wiki/Attaque_de_l%27homme_du_milieu"&gt;Man in the Middle&lt;/a&gt;, par exemple).&lt;br /&gt;
&lt;br /&gt;

&lt;code&gt;keytool&lt;/code&gt; permet de générer cette demande de certificat. La commande est :
&lt;pre&gt;
keytool -certreq -alias &lt;em&gt;&amp;lt;alias&gt;&lt;/em&gt; -file &lt;em&gt;&amp;lt;file&gt;&lt;/em&gt; -keystore &lt;em&gt;&amp;lt;keystore&gt;&lt;/em&gt;
&lt;/pre&gt;
&lt;br /&gt;

Avec les options :
&lt;ul&gt;
    &lt;li&gt;&lt;em&gt;&amp;lt;alias&gt;&lt;/em&gt; corresponds au nom de votre certificat, celui que vous avez choisi dans la première étape.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;&amp;lt;file&gt;&lt;/em&gt; corresponds au fichier qui contiendra votre demande de certificat.&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;&amp;lt;keystore&gt;&lt;/em&gt; à votre KeyStore, le même que dans la première étape.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

Grâce à cette demande de certificat, nous allons pouvoir maintenant demander un certificat à une autorité de certification.

&lt;h2&gt;Demander un certificat à une CA&lt;/h2&gt;

Libre à vous de choisir une autorité de certification (CA). J'ai choisi &lt;a href="http://www.cacert.org"&gt;CAcert.org&lt;/a&gt;, car il s'agit d'une des rares autorité de certifications fournissant des certificats gratuitement.&lt;br /&gt;
&lt;br /&gt;

La demande du certificat dépend ensuite de l'autorité que vous avez choisi. Il se peut que l'autorité de certification vous demande de la rajouter dans en tant que telle dans votre navigateur. Une fois votre certificat créé, vous allez pouvoir le récupérer sois sous la forme d'un fichier &lt;code&gt;.cert&lt;/code&gt;, sois sous sa forme textuelle. Dans le deuxième cas, nous allons devoir copier le texte du certificat (y compris les balises &lt;code&gt;-----BEGIN&amp;nbsp;CERTIFICATE-----&lt;/code&gt; et &lt;code&gt;-----END&amp;nbsp;CERTIFICATE-----&lt;/code&gt;).

&lt;h2&gt;Insérer le certificat dans le KeyStore du serveur&lt;/h2&gt;

Cette étape est assez complexe à réaliser avec &lt;code&gt;keytool&lt;/code&gt;, j'ai donc pour ma part utilisé ce code Java :
&lt;pre name="code" class="java"&gt;
public class InsertCert {
    public static void main(String[] args) {
        try {
            String certFile = "aperigeek.cert";
            String certName = "*.aperigeek.com";
            String keyStoreFile = "keystore.pks";
            String keyStorePassword = "changeit";
            
            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
            Certificate cert = certFactory.generateCertificate(new FileInputStream(certFile));
            KeyStore keyStore = KeyStore.getInstance("JKS");
            keyStore.load(new FileInputStream(keyStoreFile), keyStorePassword.toCharArray());
            Key key = keyStore.getKey(certName, keyStorePassword.toCharArray());
            keyStore.setKeyEntry(certName, key, keyStorePassword.toCharArray(), new Certificate[]{cert});
            keyStore.store(new FileOutputStream(keyStoreFile), keyStorePassword.toCharArray());
        } catch (Exception ex) {
            Logger.getLogger(InsertCert.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
&lt;/pre&gt;
&lt;em&gt;(inspiré de &lt;a href="http://blogs.sun.com/enterprisetechtips/entry/using_ssl_with_glassfish_v2"&gt;Using SSL with GlassFish v2 : Enterprise Tech Tips&lt;/a&gt;)&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;

Les variables à remplacer :
&lt;ul&gt;
    &lt;li&gt;&lt;code&gt;certFile&lt;/code&gt; : le nom du fichier contenant le certificat, fourni par l'autorité de certification.&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;certName&lt;/code&gt; : le nom du certificat, que vous lui avez donné à l'étape 1&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;keyStoreFile&lt;/code&gt; : le nom du KeyStore&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;keyStorePassword&lt;/code&gt; : le mot de passe du KeyStore&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

Après exécution de ce morceau de code, voilà votre nouveau certificat entré dans la base de certificats de votre serveur d'applications. Il ne reste plus qu'à configurer GlassFish pour utiliser ce nouveau certificat !

&lt;h2&gt;Configuration du service HTTP&lt;/h2&gt;

Dans la console d'administration de GlassFish :
&lt;ul&gt;
    &lt;li&gt;Dans l'arbre : Configuration, Service HTTP, Listeners HTTP, nom-du-listeneur&lt;/li&gt;
    &lt;li&gt;Onglet SSL :
        &lt;ul&gt;
            &lt;li&gt;Certificate Nickname : nom du certificat (que vous lui avez donné à l'étape 1)&lt;/li&gt;
            &lt;li&gt;Cocher SSL3 et TLS&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;Onglet HTTP Listener :
        &lt;ul&gt;
            &lt;li&gt;Cocher Security Enabled&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;Redémarrer GlassFish&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;

Et voilà le résultat. Vous pouvez maintenant consulter &lt;a href="http://blog.aperigeek.com/viv/"&gt;mon blog&lt;/a&gt; en &lt;a href="https://blog.aperigeek.com/viv/"&gt;HTTPS&lt;/a&gt; avec un certificat valide, si le c&amp;oelig;ur vous en dit.</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/utiliser_un_certificat_ssl_avec</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/ex%C3%A9cuter_du_javascript_en_java</guid>
    <title>Exécuter du JavaScript en Java</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/tLo-r5j-2_0/ex%C3%A9cuter_du_javascript_en_java</link>
        <pubDate>Sun, 25 May 2008 17:56:20 +0100</pubDate>
    <category>Java</category>
    <category>java</category>
    <category>javascript</category>
            <description>Suite à un &lt;a href="http://groups.google.com/group/comp.lang.java.programmer/browse_thread/thread/ef30e210a1f3492f"&gt;sujet&lt;/a&gt; sur le forum &lt;a href="http://groups.google.com/group/comp.lang.java.programmer/topics"&gt;comp.lang.java.programmer&lt;/a&gt;, j'ai fait quelque recherches sur l'exécution de scripts (en particulier JavaScript) dans un environnement Java SE.&lt;br /&gt;
&lt;br /&gt;

L'exécution de scripts dans un environnement Java est fourni par le package &lt;a href="http://java.sun.com/javase/6/docs/api/javax/script/package-summary.html"&gt;&lt;code&gt;javax.script&lt;/code&gt;&lt;/a&gt; (depuis Java 6). Un moteur de script est défini par l'interface &lt;a href="http://java.sun.com/javase/6/docs/api/javax/script/ScriptEngine.html"&gt;&lt;code&gt;ScriptEngine&lt;/code&gt;&lt;/a&gt;, dont l'implémentation nous est fournie par la classe &lt;a href="http://java.sun.com/javase/6/docs/api/javax/script/ScriptEngineManager.html"&gt;&lt;code&gt;ScriptEngineManager&lt;/code&gt;&lt;/a&gt;.

Voici donc à quoi ressemble l'exécution de code JavaScript dans un environnement Java.&lt;br /&gt;
&lt;br /&gt;

&lt;h2&gt;1. Exécution simple de script&lt;/h2&gt;

Dans un premier temps, cet exemple montre comment exécuter un script simple. Le but est d'exécuter le code JS suivant :
&lt;pre name="code" class="js"&gt;
function myFunction() {
    return (4 + 5);
}
myFunction();
&lt;/pre&gt;
&lt;br /&gt;

Le but de ce code est de déclarer une méthode qui renvoie le résultat de 4 + 5, puis d'appeler cette méthode.&lt;br /&gt;
&lt;br /&gt;

Voici maintenant l'exécution du même code en Java, en affichant le résultat sur la sortie standard :
&lt;pre name="code" class="java"&gt;
public static void main(String[] args) {
    try {
        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine engine = mgr.getEngineByName("JavaScript");
        String myJSCode = new StringBuffer()
                .append("function myFunction() {")
                .append("return (4 + 5);")
                .append("}")
                .append("myFunction();").toString();
        System.out.println(engine.eval(myJSCode));
    } catch (ScriptException ex) {
        ex.printStackTrace();
    }
}
&lt;/pre&gt;
&lt;br /&gt;

Il est également possible de séparer la déclaration de la méthode de l'appel, ce qui permet plus de modularité (par exemple, nous déclarons une méthode une seule fois pour l'appeler plusieurs fois) :
&lt;pre name="code" class="java"&gt;
public static void main(String[] args) {
    try {
        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine engine = mgr.getEngineByName("JavaScript");
        String myJSCode = new StringBuffer()
                .append("var i = 12;")
                .append("function myFunction() {")
                .append("return (i++);")
                .append("}").toString();
        engine.eval(myJSCode);
        System.out.println(engine.eval("myFunction();"));
        System.out.println(engine.eval("myFunction();"));
        System.out.println(engine.eval("myFunction();"));
    } catch (ScriptException ex) {
        ex.printStackTrace();
    }
}
&lt;/pre&gt;
&lt;br /&gt;

L'exécution de script est donc très simple.

&lt;h2&gt;2. Partage de variables&lt;/h2&gt;

En plus d'être simple, l'exécution de scripts est également très puissante. Il est possible de partager des références vers des objets entre notre code Java et notre code JavaScript.&lt;br /&gt;
&lt;br /&gt;

Un petit exemple simple, mettant en scène un &lt;code&gt;StringBuffer&lt;/code&gt; dans lequel nous allons rajouter des données en JavaScript :
&lt;pre name="code" class="java"&gt;
public static void main(String[] args) {
    try {
        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine engine = mgr.getEngineByName("JavaScript");
        StringBuffer s = new StringBuffer();
        engine.put("s", s);
        engine.eval("s.append('toto');");
        System.out.println(s.toString());
    } catch (ScriptException ex) {
        ex.printStackTrace();
    }
}
&lt;/pre&gt;
&lt;br /&gt;

Il est donc possible de modifier des objets Java directement à l'intérieur de notre moteur de script.&lt;br /&gt;
&lt;br /&gt;

Enfin, un dernier point concerne les objets immuables (comme la classe String, par exemple). En effet, une instance de String ne peut pas changer de contenu. Un nouvel objet doit être créé. Dans ce cas, il est possible de récupérer un objet créé dans notre script :
&lt;pre name="code" class="java"&gt;
public static void main(String[] args) {
    try {
        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine engine = mgr.getEngineByName("JavaScript");
        String str = "toto";
        engine.put("str", str);
        engine.eval("str = str.concat(' tata');");
        str = (String) engine.get("str");
        System.out.println(str);
    } catch (ScriptException ex) {
        ex.printStackTrace();
    }
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;

L'exécution de scripts est donc assez aisée dans un environnement Java 6. L'API permettant cette exécution est à la fois simple et puissante, puisqu'elle permet même la modification d'objets Java.&lt;br /&gt;
&lt;br /&gt;

Seul bémol, sur ma machine (JVM 1.6.0_06-b02, sous Linux), il semblerais que le moteur de JavaScript soit le seul disponible...</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/ex%C3%A9cuter_du_javascript_en_java</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/nouveau_th%C3%A8me_pour_mon_blog</guid>
    <title>Nouveau thème pour mon blog</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/wMd8UI5S87A/nouveau_th%C3%A8me_pour_mon_blog</link>
        <pubDate>Sat, 24 May 2008 14:15:01 +0100</pubDate>
    <category>General</category>
    <category>thème</category>
    <category>blog</category>
            <description>Et oui &lt;a href="http://blog.keitboor.com/"&gt;Keitboor&lt;/a&gt;, &lt;a href="http://blog.matthieudordolo.com/"&gt;Matt&lt;/a&gt; t'a dénoncé ! Il m'a avoué ce que tu pensais de mon ancien thème. Et je te l'accorde, il n'était pas très esthétique.&lt;br /&gt;
&lt;br /&gt;

Mais maintenant, ce n'est plus le cas !&lt;br /&gt;
&lt;br /&gt;

J'ai décidé d'abandonner Basic, le thème par défaut de &lt;a href="http://roller.apache.org/"&gt;Roller&lt;/a&gt;, et d'en utiliser un plus frais, &lt;a href="http://www.freecsstemplates.org/preview/unqualified"&gt;unqualified&lt;/a&gt;, un des nombreux thèmes proposés par &lt;a href="http://www.freecsstemplates.org/"&gt;freeCSStemplates.org&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;

En espérant qu'il vous plaise à vous aussi (vous, mes quelques lecteurs).</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/nouveau_th%C3%A8me_pour_mon_blog</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/astuce_java_5_for_each</guid>
    <title>Astuce Java #5 : for-each sur une map</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/G2ZQxxCNkJY/astuce_java_5_for_each</link>
        <pubDate>Tue, 20 May 2008 01:32:47 +0100</pubDate>
    <category>Java</category>
    <category>astuce</category>
    <category>java</category>
    <category>map</category>
    <category>for-each</category>
            <description>Petite astuce pour iterer sur une &lt;code&gt;Map&lt;/code&gt; dans une boucle for-each, en attendant &lt;a href="http://blog.aperigeek.com/viv/entry/java_7_am%C3%A9lioration_de_la1"&gt;Java 7&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;

Il s'agit de considérer une &lt;code&gt;Map&lt;/code&gt; comme une collection de &lt;code&gt;Map.Entry&lt;/code&gt; :
&lt;pre name="code" class="java"&gt;
Map&amp;lt;Integer, String&gt; myMap = new HashMap&amp;lt;Integer, String&gt;();
// ...
for (Map.Entry entry : myMap.entrySet()) {
    System.out.println(entry.getKey() + "=" + entry.getValue());
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;

Via &lt;a href="http://jtoee.blogspot.com/2008/05/better-way-to-iterate-java-maps.html"&gt;A better way to iterate java maps&lt;/a&gt;.</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/astuce_java_5_for_each</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://blog.aperigeek.com/viv/entry/premiers_pas_avec_lucene_recherche</guid>
    <title>Premiers pas avec Lucene : Recherche dans l'index</title>
    <dc:creator>Vivien Barousse</dc:creator>
    <link>http://feedproxy.google.com/~r/vivblog/~3/PjF353pUs6c/premiers_pas_avec_lucene_recherche</link>
        <pubDate>Mon, 19 May 2008 20:26:35 +0100</pubDate>
    <category>Java</category>
    <category>indexation</category>
    <category>apache</category>
    <category>java</category>
    <category>lucene</category>
    <category>recherche</category>
            <description>Dans la continuité de l'&lt;a href="http://blog.aperigeek.com/viv/entry/premiers_pas_avec_lucene_cr%C3%A9ation"&gt;entrée précédente&lt;/a&gt;, qui parlait de l'indexation de données avec Lucene, je vais aujourd'hui parler des &lt;code&gt;Query&lt;/code&gt;, les objets permettant de faire des requêtes de recherche dans l'index.&lt;br /&gt;
&lt;br /&gt;

Prenons un petit exemple ; dans l'index que nous avons créé hier, essayons de rechercher les documents dont le &lt;code&gt;content&lt;/code&gt; contient le mot-clé "Java".&lt;br /&gt;
&lt;br /&gt;

Les différentes étapes à suivre dont les suivantes :
&lt;ol&gt;
    &lt;li&gt;Créer un &lt;code&gt;IndexReader&lt;/code&gt;, un objet capable de lire l'index.&lt;/li&gt;
    &lt;li&gt;Créer un objet de type &lt;code&gt;IndexSearcher&lt;/code&gt;, un objet capable de faire une recherche dans un index, à travers un &lt;code&gt;IndexReader&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;Créer un objet de type &lt;code&gt;QueryParser&lt;/code&gt;. Cet objet va parser la requête passée, et l'interpréter afin de fournir les résultats les plus pertinents.&lt;/li&gt;
    &lt;li&gt;Parser la requête, nous obtiendrons un objet de type &lt;code&gt;Query&lt;/code&gt;, contenant la requête à exécuter.&lt;/li&gt;
    &lt;li&gt;Exécuter la requête, qui nous renvera une liste de résultats (sous la forme d'un objet de type &lt;code&gt;Hits&lt;/code&gt;, contenant les résultats.&lt;/li&gt;
    &lt;li&gt;Itérer sur cette liste, afin d'afficher les résultats de notre recherche.&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;

Un petit exemple de code pour concrétiser tout ça :
&lt;pre name="code" class="java"&gt;
IndexReader index = IndexReader.open(INDEX_ROOT);
Searcher searcher = new IndexSearcher(index);
QueryParser parser = new QueryParser("content", new StandardAnalyzer());
Query results = parser.parse("Java");
Hits hits = searcher.search(results);
Iterator&amp;lt;Hit&amp;gt; iterator = hits.iterator();
while (iterator.hasNext()) {
    Hit hit = iterator.next();
    System.out.println(hit.get("title") + ", by " + hit.get("author"));
}
&lt;/pre&gt;
&lt;br /&gt;

Les résultats sont automatiquement triés par pertinence. Il est possible de récupérer un "score" représentatif de la pertinence d'un résultat grâce à la méthode &lt;code&gt;Hit.getScore()&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;

Voici donc un premier et rapide aperçu du mécanisme de requêtes dans des index Lucene. Le système de requête en entier est bien plus complexe, et permet des requêtes beaucoup plus poussées. Je continuerais donc cette série d'articles au fur et à mesure de mes découvertes. En attendant, la &lt;a href="http://lucene.apache.org/java/2_3_2/"&gt;documentation officielle&lt;/a&gt; de Lucene est très complète.</description>          <feedburner:origLink>http://blog.aperigeek.com/viv/entry/premiers_pas_avec_lucene_recherche</feedburner:origLink></item>
  </channel>
</rss>
