IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Affichage des résultats du sondage: Êtes-vous pour ou contre cette proposition ?

Votants
227. Vous ne pouvez pas participer à ce sondage.
  • Pour

    53 23,35%
  • Contre

    174 76,65%
Langage Java Discussion :

JDK 7: Proposition 8 : rethrow exceptions [Débat]


Sujet :

Langage Java

  1. #1
    Expert éminent sénior


    Profil pro
    Inscrit en
    Mai 2003
    Messages
    3 240
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 3 240
    Points : 11 101
    Points
    11 101
    Par défaut JDK 7: Proposition 8 : rethrow exceptions
    Aujourd'hui :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    try {
      doable.doit(); // Throws several types
    } catch (Throwable ex) {
      logger.log(ex);
      throw ex; // Error: Throwable not declared
    }
    Demain :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    try {
      doable.doit(); // Throws several types
    } catch (final Throwable ex) {
      logger.log(ex);
      throw ex; // OK: Throws the same several types
    }

  2. #2
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Points : 9 529
    Points
    9 529
    Billets dans le blog
    1
    Par défaut
    Non, je n'aime pas le principe... je préfère devoir ajouter un throws Exception à ma méthode pour être certain que celui qui l'appel est conscient du problème...

  3. #3
    Membre actif
    Avatar de bobuse
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 232
    Points : 269
    Points
    269
    Par défaut
    Là, je suis un peu perplexe. Car il faut prendre en compte la prop 7. Si on peut catcher plusieurs types d'exception, on peut alors écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    try {
      doable.doit(); // Throws ExceptionType1 or ExceptionType2
    } catch (ExceptionType1, ExceptionType2 : ex) {
      logger.log(ex);
      throw ex; // OK, because ExceptionType1 and ExceptionType2 are already declared
    }
    Vous me suivez ?
    Qu'en pensez-vous ?

  4. #4
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut
    Contre,

    je vois pas bien l'intérêt ni l'application ..

    Cela veut-il dire que des exceptions non Runtime pourraient être "throwée" (dieu du français pardonnez moi ) sans déclaration préalable dans la signature de la méthode ?

    Je veux bien que le compilo ajoute le throws a la signature automatiquement mais jusqu'a nouvel ordre je ne suis pas un compilo, je le vois comment moi ce truc ? En parcourant tout le code de chaque méthode a chaque fois ? Et la javadoc dans tout ça ?

    Bulbo

  5. #5
    Rédacteur
    Avatar de eclesia
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    2 108
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 108
    Points : 3 203
    Points
    3 203
    Par défaut
    Contre, idem que bulbo.

  6. #6
    Membre actif
    Avatar de bobuse
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 232
    Points : 269
    Points
    269
    Par défaut
    Citation Envoyé par bulbo Voir le message
    Cela veut-il dire que des exceptions non Runtime pourraient être "throwée" (dieu du français pardonnez moi ) sans déclaration préalable dans la signature de la méthode ?
    Pas du tout !

    Je pense que vous n'avez pas bien compris, ou alors c'est moi

    Je reformule l'exemple avec plus de détail.

    Avant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public void myMethod(String prefix, String suffix) throws Throwable {
      try {
        File.createTempFile(prefix, suffix);
        // Could throw IllegalArgumentException, IOException or SecurityException
      } catch (Throwable ex) {
        logger.log(ex);
        throw ex; // myMethod could throw a Throwable
      }
    }
    Après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public void myMethod(String prefix, String suffix) throws IOException {
      try {
        File.createTempFile(prefix, suffix);
        // Could throw IllegalArgumentException, IOException or SecurityException
      } catch (Throwable ex) {
        logger.log(ex);
        throw ex;
      }
    }
    Sachant que dans mon exemple, IllegalArgumentException et SecurityException n'ont pas besoin d'être déclarée en throws car elles sont des RuntimeException. Mais elles seront cependant interceptées dans le catch.

    Est-ce que mon exemple convient ?

  7. #7
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut
    Citation Envoyé par bobuse Voir le message
    Je pense que vous n'avez pas bien compris, ou alors c'est moi

    Je reformule l'exemple avec plus de détail.

    Avant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public void myMethod(String prefix, String suffix) throws Throwable {
      try {
        File.createTempFile(prefix, suffix);
        // Could throw IllegalArgumentException, IOException or SecurityException
      } catch (Throwable ex) {
        logger.log(ex);
        throw ex; // myMethod could throw a Throwable
      }
    }
    Après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public void myMethod(String prefix, String suffix) throws IOException {
      try {
        File.createTempFile(prefix, suffix);
        // Could throw IllegalArgumentException, IOException or SecurityException
      } catch (Throwable ex) {
        logger.log(ex);
        throw ex;
      }
    }
    Sachant que dans mon exemple, IllegalArgumentException et SecurityException n'ont pas besoin d'être déclarée en throws car elles sont des RuntimeException. Mais elles seront cependant interceptées dans le catch.

    Est-ce que mon exemple convient ?
    Ton exemple est construit pour marcher alors forcément il te convient

    Bon du coup j'ai relu l'exemple, et un exemple que je dois relire 3 fois pour en comprendre le fonctionnement me laisse a penser que la maintenance de ce genre de trucs risque d'être piégeuse..

    Je pense que la methode englobante (et que l'on ne voit pas dans l'exemple, pourtant ça aurait aidé) déclare les throws des "several type" mais pas de Throwable, ce qui explique qu'aujourd'hui on soit obligé d'écrire un catch pour chaque type d'exception pour faire la même chose.

    Maintenant que va-t'il se passer si une exception non déclarée dans le throws arrive ? Le compilo saura que ce n'est pas bon et pourra indiquer que telle exception doit être catchée ? Ou bien l'exception sera rethrowée () et on aura un crash au runtime ?

    Ca manque de précision; dans le cas ou le compilo retrouve ses petits c'est bon pour moi sinon a proscrire absolument.

    Bulbo

  8. #8
    Membre actif
    Avatar de bobuse
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 232
    Points : 269
    Points
    269
    Par défaut
    Citation Envoyé par bulbo Voir le message
    Je pense que la methode englobante (et que l'on ne voit pas dans l'exemple, pourtant ça aurait aidé) déclare les throws des "several type" mais pas de Throwable, ce qui explique qu'aujourd'hui on soit obligé d'écrire un catch pour chaque type d'exception pour faire la même chose.

    Maintenant que va-t'il se passer si une exception non déclarée dans le throws arrive ? Le compilo saura que ce n'est pas bon et pourra indiquer que telle exception doit être catchée ? Ou bien l'exception sera rethrowée () et on aura un crash au runtime ?
    Je ne suis toujours pas sûr qu'on parle de la même chose.

    Ici, il n'est pas question de permettre de jeter des exceptions qui ne sont pas déclarées dans le throws.
    Il est bien question de permettre de déclarer dans le throws uniquement les exceptions pouvant être lancées par un throw, sachant que dans les types d'exceptions pris en compte sont bien ceux des méthodes englobées par le try et nom le type du catch.

    Mais c'est vrai que l'exemple n'est pas très clair.
    vbrabant, si tu pouvais nous éclairer un peu plus

  9. #9
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut
    On parle de la même chose rassure toi.

    Mais si tu regardes l'exemple, il y a un catch Throwable, qui, par définition catch tout.
    Imaginons que dans un premier temps tu ai déclaré dans ton throws toutes les exceptions que tu sais possible et que plus tard tu rajoutes un appel qui lance une nouvelle exception et que tu l'oublie celle la..

    Que va faire le catch ? Catcher tout comme l'utilisation de Throwable laisse a penser ou ne va-t'il catcher que les exceptions déclarées dans le throws ?

    En fait je vois mal comment il pourrait savoir quoi catcher et il catchera tout (cas de try imbriqués: qui catch quoi ?) et donc rethrow de tout

    Comment ne plus avoir de problème de compil dans ce cas, il y aura de toute façon problème, ou ira la nouvelle exception ? Qui la catchera ? Ou aura-t'on droit a une Runtime ?

    Bref je ne veux pas de ce système, pourquoi ne pas faire des exceptions qu'on ne catch jamais et qui ne plante rien a la C++ tant qu'on y est ..

    Bulbo

  10. #10
    Membre actif
    Avatar de bobuse
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 232
    Points : 269
    Points
    269
    Par défaut
    Citation Envoyé par bulbo Voir le message
    Mais si tu regardes l'exemple, il y a un catch Throwable, qui, par définition catch tout.
    Imaginons que dans un premier temps tu ai déclaré dans ton throws toutes les exceptions que tu sais possible et que plus tard tu rajoutes un appel qui lance une nouvelle exception et que tu l'oublie celle la..

    Que va faire le catch ? Catcher tout comme l'utilisation de Throwable laisse a penser ou ne va-t'il catcher que les exceptions déclarées dans le throws ?
    Le catch fera comme avant, il catchera tout ce qui hérite du type utilisé (ici Throwable, mais ça peut être autre chose). Par contre, le throws de la signature devra être modifiée pour ajouter ta nouvelle exception.

  11. #11
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut
    Citation Envoyé par bobuse Voir le message
    Le catch fera comme avant, il catchera tout ce qui hérite du type utilisé (ici Throwable, mais ça peut être autre chose). Par contre, le throws de la signature devra être modifiée pour ajouter ta nouvelle exception.
    Je ne vois pas très bien comment le compilo pourrait bien se débrouiller avec ça.. surtout en cas de try catch imbriqué qui lance quoi, qui doit déclarer quoi ..

    Bref pas convaincu du tout par ce truc..

    Bulbo

  12. #12
    Expert éminent
    Avatar de elitost
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2003
    Messages
    1 985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 985
    Points : 6 566
    Points
    6 566
    Par défaut
    Pour cette évolution, même si il faut bien faire attention au mot clé final, peut être ambigu dans la lecture

  13. #13
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 866
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 866
    Points : 22 919
    Points
    22 919
    Billets dans le blog
    52
    Par défaut
    Pour, j'ai ai marre d'initialiser de nouvelles exceptions et de les chainer a la precedente avec initCause() a chaque fois.

  14. #14
    Membre éclairé

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2002
    Messages
    346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 346
    Points : 737
    Points
    737
    Par défaut
    J'ai voté contre car je pense que ça permettrais une gestion plus laxiste des exception et que c'est mauvais.

    Par contre, en lisant les différents messages je me pose des question quand à la compréhension, donc si l'auteur original, vbrabant, pouvait un peu plus expliquer ce serait sympa.

  15. #15
    Membre actif
    Avatar de bobuse
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 232
    Points : 269
    Points
    269
    Par défaut
    Effectivement, la proposition peut être mal comprise, et laisser à penser à du laxisme.
    Je pense que c'est la notation qui n'est pas très explicite. Qu'est-ce qu'on pourrait trouver de mieux ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    catch (? extends Throwable ex)
    Bof

    Encore une fois, le problème ne se poserait pas avec la proposition 7, et ce serait beaucoup moins ambigü !!

  16. #16
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Un petit contre, non pas contre la proposition mais contre la syntaxe qui est incompréhensible à mon avis...

    D'ailleurs je pense que certain ne l'on pas bien compris...



    En fait il ne s'agit pas réellement d'un vrai catch puisqu'on laisse remonter les exception à chaque fois. Il s'agit plus d'un "filtre" qui permettrait de voir passer les exceptions juste avant de les remonter, par exemple pour les logger.


    Imaginer une méthode toute simple qui pourrait remonter des IOException :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	public void method() throws IOException {
    		method1(); // throws IOException
    		method2();
    	}
    Comme toutes méthodes elle peut également remonter des RuntimeException (NullPointerException par exemple) ou des Error (OutOfMemory).



    Maintenant si vous voulez rajouter un log au sein de cette méthode juste pour conserver une trace des problèmes rencontré tout en continuant à les remonter, il vous faut traiter chaque cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    	public void method() throws IOException, SQLException {
    		try {
    			method1(); // throws IOException
    			method2();
    		} catch (IOException e) {
    			log("...");
    			throw e;
    		} catch (RuntimeException e) {
    			log("...");
    			throw e;
    		} catch (Error e) {
    			log("...");
    			throw e;
    		}
    	}


    Cette proposition vise à permet cela plus simplement, en utilisant un catch unique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	public void method() throws IOException {
    		try {
    			method1(); // throws IOException
    			method2();
    		} catch (final Throwable t) {
    			log("...");
    			throw t;
    		}
    	}
    En fait ce catch là ne traite pas les exceptions et les laisse remonter, mais ce code ne marche pas car Throwable pourrait correspondre à n'importe quoi, or dans ce cas précis ce ne peut être qu'une IOException, une RuntimeException ou une Error ce qui est parfaitement compatible avec la déclaration de notre méthode...



    Bref ce bloc catch ne correspond qu'à un simple passage pour l'exception qui sera quand même remonté... et du coup la syntaxe ne me plait pas.
    J'opterais plutôt pour ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	public void method() throws IOException, SQLException {
    		try {
    			method1(); // throws IOException
    			method2();
    		} catch (Throwable t) {
    			// Toutes les exceptions qui arrive ici seront
    			// remonté après l'exécution de ce bloc :
    			log("...");
    		}
    	}
    Ici le bloc throws() est exécuté lorsqu'un élément est remonté, mais cela ne traite pas l'exception. Ainsi si le bloc remonte une exception qui n'est pas propagé par la méthode il y aura une erreur et il faudra la catcher normalement, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    	public void method() throws IOException, SQLException {
    		try {
    			method1(); // throws IOException
    			method2(); // throws SQLException
    			method3();
    		} catch (SQLException e) {
    			log("...");
    			throw new IOException("SQL Error");
    		} catch (Throwable t) {
    			// Toutes les exceptions qui arrive ici seront
    			// remonté après l'exécution de ce bloc :
    			log("...");
    		}
    	}

    a++

  17. #17
    Membre averti
    Homme Profil pro
    Inscrit en
    Juillet 2002
    Messages
    705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 705
    Points : 393
    Points
    393
    Par défaut
    Contre

    perte de sémantique;

    La sémantique n'est elle pas la voie de la sagesse.

    Par contre un truc qui manque peut etre à JAVA c'est la possibilité d'écrire un listener d'exception. Pour les évènements java swing on branche un AWTEventListener sur le toolkit ce qui permet de tracer les actions utilisateurs (pour faire de la recherche en ergonomie, du debuggage, et des graphe fonctionnels... c'est super pratique).

    Je crois pas qu'on peut faire pareil avec les Exception. Si c'était possible on pourrait centraliser les log4J (je fais un appel dans le constructeur pour ma part).

  18. #18
    Membre actif
    Avatar de bobuse
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 232
    Points : 269
    Points
    269
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    J'opterais plutôt pour ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	public void method() throws IOException, SQLException {
    		try {
    			method1(); // throws IOException
    			method2();
    		} throws (Throwable t) {
    			// Toutes les exceptions qui arrive ici seront
    			// remonté après l'exécution de ce bloc :
    			log("...");
    		}
    	}
    Ouais. Moi j'aime bien l'idée. Ça paraît effectivement plus clair
    Reste à discuter si « throws » et le bon terme, mais je trouve que l'idée est la bonne.

  19. #19
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut
    Tient une idée si throws ne plait pas: watch

    Comment ça on risque de confondre avec catch

    Bulbo

  20. #20
    Membre émérite
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Points : 2 410
    Points
    2 410
    Par défaut
    Contre.

    Je préfère la proposition 7 qui me semble être absolument équivalente (corrigez-moi si je me trompe) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    try {
      ...
    } catch (IOException e | SQLException e) { // fault-il mettre des final ?
      log(...);
      throw e;
    }

Discussions similaires

  1. Réponses: 165
    Dernier message: 03/09/2009, 15h35
  2. Réponses: 78
    Dernier message: 27/08/2009, 19h29
  3. Réponses: 170
    Dernier message: 19/08/2009, 16h13
  4. JDK 7: Proposition 3 : Comparer les énumérations
    Par vbrabant dans le forum Langage
    Réponses: 52
    Dernier message: 19/10/2008, 12h36
  5. Réponses: 27
    Dernier message: 19/10/2008, 11h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo