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

JDBC Java Discussion :

blocage du programme sur méthode getConnexion


Sujet :

JDBC Java

  1. #1
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 21
    Par défaut blocage du programme sur méthode getConnexion
    Bonjour,
    j'ai un problème avec la méthode getConnexion de la classe DriverManager. Mon programme comprend deux threads qui exécutent chacun une méthode synchronized différente toutes les secondes. Dans chacune des méthodes il y a un appel à getConnexion. La base est volontairement inaccessible puisque je souhaite effectuer un traitetement particulier en mode déconnecté.

    Le problème c'est qu'au bout d'un certain nombres d'éxécutions la méthode getConnexion se bloque (plus d'exception SQLException levée). J'ai lu qu'il fallait pour utiliser une même connexion en multithread passer par des méthodes synchronized ce que je pense avoir fait donc je chercher toujours mon erreur. Merci de pour vos lumières !

    J'utilise le driver com.mysql.jdbc.Driver et le connector myslql 5.1.7 (j'ai essayé avec le 5.1.6 sans succès).

    Voici mes deux threads :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    public class SurvProductionFichier extends Thread{
     
        private SurvMetier monSurvMetier;
        public SurvProductionFichier(SurvMetier lInterface)
        {
            monSurvMetier = lInterface;
        }
     
        public void run()
        {
            Random rnd;
            int tempo = 0;
            while(Thread.currentThread().isInterrupted() == false)
            {
                //Je lance la surveillance des fichiers 
                monSurvMetier.traiterFichierProduit();
                try
                {
                    //TEST
                    tempo = 0;
                    //NON TEST
                    //On endors le thread pendant un temps aléatoire entre 1 et 30 secondes
                    //rnd = new Random();
                    //tempo = rnd.nextInt(29);
                    sleep((tempo+1)*1000);
                }
                catch(InterruptedException e)
                {
                        GestionLoggerProductionFichier.getLogger().log(Level.WARNING,"Thread SurvProjet interrompu dans son sommeil",e);
                        Thread.currentThread().interrupt();
                }
            }
            GestionLoggerProductionFichier.getLogger().log(Level.INFO,"Thread SurvProjet arrete");
        }
    }
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    public class SurvMajBdd extends Thread{
     
        private SurvMetier monSurvMetier;
        public SurvMajBdd(SurvMetier lInterface)
        {
            monSurvMetier = lInterface;
        }
     
     
        public void run()
        {
            Random rnd;
            int tempo = 0;
            while(Thread.currentThread().isInterrupted() == false)
            {
                //Je lance la surveillance de la bdd
                monSurvMetier.recupererMajListe();
                try
                {
                    //TEST
                    //tempo = 0;
                    //NON TEST
                    //On endors le thread pendant un temps aléatoire entre 1 et 30 secondes
                    rnd = new Random();
                    tempo = rnd.nextInt(29);
                    sleep((tempo+1)*1000);
                }
                catch(InterruptedException e)
                {
                        GestionLoggerBdd.getLogger().log(Level.WARNING,"Thread SurvProjet interrompu dans son sommeil",e);
                        Thread.currentThread().interrupt();
                }
            }
            GestionLoggerBdd.getLogger().log(Level.INFO,"Thread SurvProjet arrete");
        }
    }
    La classe SurvMetier
    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
    16
    17
    18
    19
    20
    21
    22
    23
    public class SurvMetier {
     
        GestionDonnee monGestionnaire;
     
        public SurvMetier()
        {
            monGestionnaire = new GestionDonnee();
        }
     
        synchronized void recupererMajListe()
        {
            GestionLoggerProductionFichier.getLogger().log(Level.INFO, "#########    DEBUT recupererMajListe         #########");
            monGestionnaire.creerFichierMAJ();
            GestionLoggerProductionFichier.getLogger().log(Level.INFO, "#########    FIN recupererMajListe         #########");
        }
     
        synchronized void traiterFichierProduit()
        {
            GestionLoggerProductionFichier.getLogger().log(Level.INFO, "#########    DEBUT traiterFichierProduit         #########");
            monGestionnaire.traiterFichierProduit();
            GestionLoggerProductionFichier.getLogger().log(Level.INFO, "#########    FIN traiterFichierProduit         #########");
        }
    }
    La classe qui effectue les traitements
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
    public class GestionDonnee {
     
     
    	//-- Donnée de l'application --//
            private int nbTentativeInsertionEnBase;
            private int NB_MAX_TENTATIVE = 2;
     
    	public GestionDonnee()
    	{
            maBDD = new BddMySql();
    	}
     
     
     
       public void traiterFichierProduit()
    	{
    		GestionLoggerProductionFichier.getLogger().log(Level.FINE, "Debut méthode");
    		LinkedList<TempsSurv> lesTemps = null;
    		TempsSurv leTemps = null;
    		String leFichier = "";
    		String lePath = "";
    		boolean premierErreur = false;
    		//On essaye d'ouvrir la connexion
    		try
    		{
    			//Ouverture de la connexion avec la BDD
    			maBDD.connexion(GestionLoggerProductionFichier.getLogger());
    			//On regarde si il y a un fichier TempsSurv dans le rep final
    			lePath = monXML.getPathExploitationFinal();
    			leFichier = monXML.fichierTempsSurvFinalExiste();
    		}
    		catch(Exception e)
    		{
    		   GestionLoggerProductionFichier.getLogger().log(Level.INFO, "La BDD distante n'est pas atteignable, travail en mode déconnecté");
    		   premierErreur = true;
    		}
    		GestionLoggerProductionFichier.getLogger().log(Level.FINE, "Fin méthode");
    	}
     
    	public void creerFichierMAJ()
    	{
    		GestionLoggerBdd.getLogger().log(Level.INFO, "Debut méthode");
    		boolean premierErreur = false;
    		long laDateMaj = -1;
    		try
    		{
    			//Ouverture de la connexion avec la BDD
    			GestionLoggerBdd.getLogger().log(Level.INFO, "Je tente la connexion");
    			maBDD.connexion(GestionLoggerBdd.getLogger());
    		}
    		catch(Exception e)
    		{
    			GestionLoggerProductionFichier.getLogger().log(Level.INFO, "La BDD distante n'est pas atteignable, travail en mode déconnecté");
    		   premierErreur = true;
    		}
    	}
    }
    et la méthode d'accès à la bdd présente dans la classe BddMySql
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    public void connexion(Logger leLogger) throws Exception
    	{
                leLogger.log(Level.INFO, "Debut methode");
                conn = null;
                st = null;
                try
                {
                    leLogger.log(Level.INFO, "Class.forName(com.mysql.jdbc.Driver)");
                    nbConnection++;
                    leLogger.log(Level.INFO, "NB CONNECTION : "+nbConnection);
                    DriverManager.setLoginTimeout(5);
                    leLogger.log(Level.INFO, "TIMEOUT: "+DriverManager.getLoginTimeout());
     
                    conn = DriverManager.getConnection(strConnexion, user, strMdp);
     
                    leLogger.log(Level.INFO, "conn.createStatement()");
                    st = conn.createStatement();
                    leLogger.log(Level.INFO, "Apres");
                }
                catch(SQLException e)
                {
                    leLogger.log(Level.WARNING, "CONNEXION IMPOSSIBLE : ",e);
                    fermerConnexion(leLogger);
                    throw e;
                }
                catch(Exception e){
                   leLogger.log(Level.WARNING, "CONNEXION IMPOSSIBLE : ",e);
                   throw e;
                }
                leLogger.log(Level.INFO, "Fin methode");
    	}

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    alors, évite d'envoyer autant de code, ca prend beaucoup de temps à lire, commence par simplifier ce que tu envoie. Car là, non seulement y a une tartine énorme, mais il manque le principal. Le code où tu lance tes deux threads, qu'on vois ce que tu leur passe.

  3. #3
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 21
    Par défaut
    A ok désolé c'est vrai que j'ai mis bcp de code.
    Voilà le lancement de mes deux threads :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    leMetier = new SurvMetier();
    SurvProductionFichier monThreadSurvGestionSurveillance= new SurvProductionFichier(leMetier);
    monThreadSurvGestionSurveillance.start();
    SurvMajBdd monThreadSurvBDD= new SurvMajBdd(leMetier);
    monThreadSurvBDD.start();
    Deuxième erreur de ma part, ce n'est pas forcément lié aux threads puisque quand j'éxécute soit l'un soit l'autre des threads, il se passe la même chose, le prog s'arrête et à chaque fois la dernière trace que j'obtiens c'est celle juste avant l'appel à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DriverManager.getConnection(strConnexion, user, strMdp);

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    combien de connection demande tu au total? Au delà d'un certain nombre de connections, c'est le serveur de base de donnée qui va, soit te mettre en attente qu'une connection se libère, soit t'envoyer péter (too many connections). Quand tu as fini d'utiliser une connection n'oublie pas d'appeler close() dessus, pour la libérer!

  5. #5
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 21
    Par défaut
    Ok merci pour l'info mais là dans mon problème aucune connexion n'est établie, je teste juste la dispo de la bdd pour pouvoir faire un traitement si la bdd n'est pas accessible.

    Dans mon test, je n'ai jamais accès à la bdd, en gros j'ai toujours l'exception SQLException qui est levée mais au bout d'un certain nombre de tentative qui varie entre 1600 et 3800 (je fais une tentative toutes les secondes), tout s'arrête sur la méthode getConnection et je ne reçois pas d'exception.

    J'espère être assez claire mais merci de m'aider en tout cas.

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    si tu travaille dans un ide, lors du blocage, tu peux faire un "pause" de ton application et regarder où en sont les threads pour avoir une idée de ce qui bloque. Si t'es en mode console, il va falloir faire un thread dump. Essaie aussi d'attendre un moment pour voir si un timeout ne se déclenche pas.

    Au fait, comme la connection (ou tout du moins la tentative) se fait sur le réseau, n'y a-t-il pas une sécurité sur le système cible qui conclue à une tentative de flood et ne répond simplement plus à tes paquets?

  7. #7
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 21
    Par défaut
    Merci je vais regarder pour tes deux premières remarques, pour la troisième concernant le réseau, c'est fort probable mais comment je peux m'en rendre compte ? j'ai initialisé le timeout à 5s mais ça ne change pas grand chose.
    Bon je continue mes recherches ...

  8. #8
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 21
    Par défaut
    J'ai quelques infos en plus.
    J'ai fait ce que tu m'a dis tchize_ :
    Le thread s'arrête dans la classe com.mysql.jdbc.util.ReadAheadInputStream mais je ne sais pas dans quelle méthode ?
    Voici la ligne exacte dans la fenêtre d'exécution des threads :
    Monitor com.mysql.jdbc.util.ReadAheadInputStream (#655)

    Dans le call stack, si ça peut aider, j'ai :
    Object.wait
    Object.wait:485
    TimerThread.mainLoop:483
    TimerThread.run:462

    Concernant l'erreur (s'il s'agit d'une sécurité réseau), je peux très bien en cas d'échec de la connexion, retenter la connexion au bout d'un temps plus long genre 1 ou 5 minutes mais j'aimerais identifier le problème pour être sur de faire la bonne correction.

    Merci

  9. #9
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    si c'est un problème de sécurité, il est assez facile à prouver (sans en trouvere pour autant la cause précise). Quand ton application bloque, tu la tue et tu la redémarre de suite, elle devrait etre a nouveau bloquée immédiatement.


    Sinon, pour ton stacktrace, on pourrait l'avoir en plus complet? Et il me semble que tu n'est pas dans le bon thread. Il s'agit là d'un timer qui attends qu'on le notifie, probablement un thread de mysql qui attends de nettoyer les connections... Si c'est un deadlock, il faut regarder tous les thread pour voir ce qui se passe.

  10. #10
    Membre chevronné Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Par défaut
    Citation Envoyé par smith_dev Voir le message
    Ok merci pour l'info mais là dans mon problème aucune connexion n'est établie, je teste juste la dispo de la bdd pour pouvoir faire un traitement si la bdd n'est pas accessible.
    Ha si, la méthode connexion de ta classe BddMySql ouvre bien une connexion, et peut être sans la fermer. Au bout de 1600 à 3800 connexions, plus ou moins simultanées (que fait le garbage collector exactement si la connexion n'était pas fermée ?), je comprendrai que ta BDD ne réponde plus.

    Au passage, si c'est pour tester ta BDD, tu peux ajouter l'exécution d'une requête très simple, pour vérifier que le moteur de ta bdd fonctionne, et pas uniquement la partie purement réseau.

  11. #11
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 21
    Par défaut
    Il y a sans doute des choses que je ne maitrise pas mais juste pour précision djsnipe :
    j'essaye de me connecter à une bdd mysql que je gère grace à easyphp en local et lors de mes tests easyphp n'est pas démarré. Alors pt qu'il y a quand même une connexion avec mysql, je pensais que non ... mais je veux bien plus d'info dans ce cas.

    Sinon j'ai fait le test suivant, j'ai créé la classe suivante :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
        public static void main(String[] args) {
            try {
                // TODO code application logic here
                Class.forName("com.mysql.jdbc.Driver");
                nbConnection = 0;
                strConnexion = "jdbc:mysql://localhost/base";
                user = "user";
                strMdp = "mdp";
                while (true) {
                    connexion();
                    Thread.sleep(100);
                }
            } catch (InterruptedException ex) {
                System.out.println("Impossible d'endormir le thread");
            } catch (ClassNotFoundException ex) {
                System.out.println("Impossile de charger le driver");
            }
        }
    public static void connexion()
        {
            conn = null;
            st = null;
            try
            {
     
                nbConnection++;
     
                DriverManager.setLoginTimeout(5);
                System.out.println("Je tente la connexion n° "+nbConnection);
                conn = DriverManager.getConnection(strConnexion, user, strMdp);
                st = conn.createStatement();
     
            }
            catch(SQLException e)
            {
                System.out.println("Echec de la connexion");
            }
            catch(Exception e){
                System.out.println("Autre erreur");
            }
        }
    Et j'ai lancé deux instances via le debugger. Sur la première instance lancée un peu avant, j'ai fait 1740 tentative de connexion avant blocage et la deuxième instance a continué après sans ce bloquer.

    Dans netbeans j'obtiens les infos suivantes :

    Threads :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    system
    	main
    		main
    			Owned Monitors
    				Monitor com.mysql.jdbc.util.ReadAheadInputStream(#335)
    				Monitor java.lang.object(#336)
    		MySQL Statement Cancellation Timer
    			Contended Monitor : java.util.TaskQueue(#337)
    		Reference Handler
    			Contended Monitor:java.lang.red.Reference$Lock(#333)
    		Finalizer
    			Contended Monitor:java.lang.ref.ReferenceQueue$Lock(#334)
    		Signal Dispatcher
    		Attach Listener
    Call Stack

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Object.wait
    ReferenceQueue.remove:116
    ReferenceQueue.remove:132
    Finalizer$FinalerThread.run:159
    Autre précision aussi dans tous les cas, conn reste à null donc il m'est impossible de faire un conn.close().

  12. #12
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 21
    Par défaut
    Threads :

    system
    main
    main
    Owned Monitors
    Monitor com.mysql.jdbc.util.ReadAheadInputStream(#335)
    Monitor java.lang.object(#336)
    MySQL Statement Cancellation Timer
    Contended Monitor : java.util.TaskQueue(#337)
    Reference Handler
    Contended Monitor:java.lang.red.Reference$Lock(#333)
    Finalizer
    Contended Monitor:java.lang.ref.ReferenceQueue$Lock(#334)
    Signal Dispatcher
    Attach Listener

    Avec l'indentation c'est mieux !

  13. #13
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 21
    Par défaut
    Threads :

    system
    main
    main
    Owned Monitors
    Monitor com.mysql.jdbc.util.ReadAheadInputStream(#335)
    Monitor java.lang.object(#336)
    MySQL Statement Cancellation Timer
    Contended Monitor : java.util.TaskQueue(#337)
    Reference Handler
    Contended Monitor:java.lang.red.Reference$Lock(#333)
    Finalizer
    Contended Monitor:java.lang.ref.ReferenceQueue$Lock(#334)
    Signal Dispatcher
    Attach Listener

    Désolé pas réveillé ce matin

  14. #14
    Membre chevronné Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Par défaut
    Citation Envoyé par smith_dev Voir le message
    j'essaye de me connecter à une bdd mysql que je gère grace à easyphp en local et lors de mes tests easyphp n'est pas démarré. Alors pt qu'il y a quand même une connexion avec mysql, je pensais que non ... mais je veux bien plus d'info dans ce cas.
    OK, ce n'était pas ce que j'avais compris. Je pensais que ton problème était avec une base démarrée qui fonctionne. Donc, si elle ne fonctionne pas, tu as une SQLException, et oui, il n'y a aucune connexion d'établie.
    Est-ce que c'est bien dans cette situation que tu as un blocage au bout de quelques milliers de tentatives ? Si oui, je penserai à un bug du driver JDBC MySQL qui se bloquerai tout seul après tout ces échecs.

  15. #15
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 21
    Par défaut
    oui exactement c'est uniquement dans le cas où j'ai systématiquement des échecs que mon programme ce bloque ... je n'ai pas trouvé de problèmes identiques concernant l'utilisation du driver JDBC, ça m'étonne d'être le premier à constater ça.

    Pour l'instant, j'utilise la solution suivante qui n'a pas amenée de blocage :
    Si la tentative de connexion échoue, je retente la connexion qu'après deux minutes et je considère pendant ce temps là que mon prog est en mode déconnecté mais il n'est pas impossible que cela amène un jour un blocage si le nombre de tentative devient élevé.

    Je n'ai rien trouvé de mieux pour l'instant.

Discussions similaires

  1. aide sur méthode de programmation
    Par shirya dans le forum C#
    Réponses: 1
    Dernier message: 25/02/2007, 18h48
  2. [Eclipse] Programmer sur un fond noir
    Par raj dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 27/12/2004, 10h15
  3. [Reseau] Execution de programmes sur un autre PC
    Par el3gans dans le forum Général Java
    Réponses: 5
    Dernier message: 18/11/2004, 11h20
  4. Methode de programmation sur des gros projets
    Par dynobremo dans le forum EDI
    Réponses: 10
    Dernier message: 08/06/2004, 02h59
  5. Déclenchement Programme sur Virtual Key
    Par Tom-G dans le forum API, COM et SDKs
    Réponses: 9
    Dernier message: 09/05/2003, 12h58

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