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

Tests et Performance Java Discussion :

Comment tester si un flush a bien été fait ?


Sujet :

Tests et Performance Java

  1. #1
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut Comment tester si un flush a bien été fait ?
    Bonjour,

    Honte à moi, j'oublie très régulièrement de faire le flush de mes flux de sortie, par exemple le BufferedWriter, ce qui provoque des bugs souvent difficiles à découvrir.

    Le plus ennuyeux est que je ne vois absolument pas comment on peut tester si, à sa fermeture, un flux a bien été flushé auparavant ?

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 334
    Points : 36 855
    Points
    36 855
    Par défaut
    Bonsoir,
    pourquoi ne pas "flusher" sans se poser de question?
    -W

  3. #3
    Membre averti
    Profil pro
    Développeur Java
    Inscrit en
    Novembre 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2007
    Messages : 301
    Points : 368
    Points
    368
    Par défaut
    Il n'y a pas de moyen de savoir s'il y a eu un flush ou non. La solution est de faire un flush() avant de faire le close(). Je trouve que ça rejoint un peu les problèmes de gestion des sessions/transactions que l'on avait avant où on avait oublié de faire un close.

    Une solution serait de gérer ça via un modèle de conception Template ou alors via des aspects.

    Pour le template où on pourrait imaginer quelque chose comme ça (je ne sais pas si c'est vraiment utilisable, à creuser) :
    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
    abstract class Template {
     
    	public void execute(BufferedWriter writter) {
    		try {
    			handle(writter);
    		} catch(IOException e) {
    			// ...
    		} finally {
    			try {
    				if(writter != null) {
    					writter.flush();
    					writter.close();
    				}
    			} catch(IOException e) {
    				// ...
    			}
    		}
    	}
     
    	protected abstract void handle(BufferedWriter writter) throws IOException;
    }

  4. #4
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Bonsoir,
    pourquoi ne pas "flusher" sans se poser de question?
    -W
    Ben précisement parce que je l'oublie ! Donc... je suis bien obligé de me poser des questions. Cela fait presque 1 mois que je cherche un bug indémerdable à cause d'un flush oublié dans un coin oublié, donc je cherche à ne pas recommencer !

    Citation Envoyé par darkxan Voir le message
    Une solution serait de gérer ça via un modèle de conception Template ou alors via des aspects.
    Je m'étais fait le même genre de réflexion : impossible de tester l'usage du flush. (d'où ma question ici)

    Tu présentes un exemple de Template ; cela à l'air d'être de méthode toute prête ; mais, par Template, est-ce que tu fais référence à un méthodologie particulière, ou est-ce que c'est simplement l'idée de regrouper flush/close dans un utilitaire ?

    J'avais pensé aux aspects aussi, mais je ne m'y connais pas beaucoup dans ce domaine ; je m'étais simplement dit que d'après ce que j'avais compris des aspects, un truc qui s'applique à un ensemble d'objets variés, cela pouvait peut être être une piste. As-tu un exemple dans ce domaine ?

  5. #5
    Membre averti
    Profil pro
    Développeur Java
    Inscrit en
    Novembre 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2007
    Messages : 301
    Points : 368
    Points
    368
    Par défaut
    Comme je l'ai précisé dans mon message précédent Template [GOF] est un modèle de conception ou design pattern.

    Il est pour implémenter des parties invariantes d'un algorithme et laisser les sous classes s'occuper du comportement.
    Cela permet aussi d'éviter de la duplication de code et rentre plus généralement dans le refactoring de code.
    Si tu veux en savoir plus, je te conseille la littérature sur ce design pattern.

    J'ai fait un rapprochement avec les transactions et ce n'est pas innocent car avant l'avènement des aspects, il était très pratique d'utiliser des templates pour gérer les transactions. Cela évitait les problèmes de copier/coller et d'oubli comme tu l'as actuellement avec ta méthode flush().

    Je ne sais exactement ce que tu as lu les aspects mais il faut vraiment le voir comme la capacité d'ajouter des fonctionnalités à des méthodes. Les exemples classiques sont la gestion des logs, la gestion des exceptions, la sécurité, les transactions, etc...
    Fondamentalement, c'est trop proche de la classe Template que j'ai présenté au dessus en parlant d'éviter la duplication de code.
    Si je prends l'exemple des transactions avec une méthode createUser, si je gère manuellement mon aspect je devrais créer une méthode autour de la méthode de création.

    Par exemple on pourrait gérer les transactions de cette manière (attention c'est juste un schéma pour donner une idée) :
    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
    public void createUser(User user) {
    	this.userDAO.save(user);
    }
     
    public void transactionAspect(JoinPoint p, Object... args) {
    	try {
    		Session session = sessionFactory.getCurrentSession();
    		Transaction tx = session.beginTransaction();
     
    		p.execute(args);
     
    		tx.commit();
    	} catch(RuntimeException e) {
    		if(tx != null) {
    			tx.rollback();
    		}
    	}
    }
    On voit bien que cela correspond fortement à l'idée de template au dessus sauf que c'est bien plus puissant car on choisir d'exécuter ce bout de code avant l'appel à la méthode, après son appel, après une exception ou au tour comme dans le code précédent.

    Donc en conclusion, effectivement tu pourrais utiliser des aspects pour gérer ton problème mais cela à tout de même des contraintes : il faut pouvoir accéder facilement à ta ressource le BufferedWritter. Dans le cas des transactions, c'est le pied car on peut accéder très facilement à la session et donc aux transactions; ici cela me semble plus dur d'accéder facilement à ton Writter.

    Une solution serait donc que la méthode prennent en paramètre Writter comme ça l'aspect pourrait le récupérer sans problème soit il faudrait créer un système similaire au session dans le cas de la gestion des BD qui te permettrait de savoir avec quel Writter tu travailles actuellement. La deuxième solution demande d'avoir une architecture assez particulière alors que le premier cas peut s'appliquer partout.

    Donc on voit bien que les deux solutions Template ou aspects ne répondent pas forcément parfaitement aux besoins de gestion des ressources et c'est cela qui doit expliquer pourquoi on ne voit peu de code utiliser ces méthodes dans ce cas.

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 334
    Points : 36 855
    Points
    36 855
    Par défaut
    Ben précisement parce que je l'oublie ! Donc... je suis bien obligé de me poser des questions. Cela fait presque 1 mois que je cherche un bug indémerdable à cause d'un flush oublié dans un coin oublié, donc je cherche à ne pas recommencer !
    Pourquoi ne pas dériver "BufferedWriter" et surcharger le close avec un code qui fasse ce "flush"?
    - W

  7. #7
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Citation Envoyé par darkxan Voir le message
    Comme je l'ai précisé dans mon message précédent Template [GOF] est un modèle de conception ou design pattern.
    C'est le Patron de méthode (ou Template method ) ?

    Citation Envoyé par darkxan Voir le message
    Donc en conclusion, effectivement tu pourrais utiliser des aspects pour gérer ton problème mais cela à tout de même des contraintes : il faut pouvoir accéder facilement à ta ressource le BufferedWritter. Dans le cas des transactions, c'est le pied car on peut accéder très facilement à la session et donc aux transactions; ici cela me semble plus dur d'accéder facilement à ton Writter.
    Cela ne me dérange qu'à moitié de rendre mon BufferedWritter public, car j'ai l'habitude de rendre publics les objets sensibles pour les tests. Je préfère avoir un objet public et fiable, plutôt qu'un objet privé où c'est le bordel

    Je vais essayer d'approfondir ces aspects, dans lesquels je suis trop novice pour me faire une opinion. L'occasion est bonne, d'autant plus que j'aborde aussi Spring en ce moment, et que, en plus, à ce que je comprends, l'usage du pattern Template est un bon début.

    À terme, j'ai l'espoir, me semble-t-il, que Template+Aspect puisse rendre mon flush testable, puisque j'aurai factorisé mon code, et que donc mon problème qui est disséminé partout sera rassemblé en un seul point bien identifié. (la procédure classique pour fiabiliser son code, quoi).

    Citation Envoyé par wiztricks Voir le message
    Pourquoi ne pas dériver "BufferedWriter" et surcharger le close avec un code qui fasse ce "flush"?
    - W
    À partir du moment où l'on dit C'est pas testable, ton idée est effectivement bonne. Il me semble qu'on peut la voir comme une forme du pattern Template, non ?

    Merci à tous deux pour vos réflexions.

  8. #8
    Membre averti
    Profil pro
    Développeur Java
    Inscrit en
    Novembre 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2007
    Messages : 301
    Points : 368
    Points
    368
    Par défaut
    C'est le Patron de méthode (ou Template method ) ?
    Euh... C'est la même chose sauf que l'un est en français l'autre en anglais.

    car j'ai l'habitude de rendre publics les objets sensibles pour les tests
    Pour ma part, je ne modifie jamais mon code pour effectuer des tests. Si je dois tester un champs privé ou une méthode privée, j'utilise l'api reflection qui permet de faire ça très aisément.

    J'ai des méthodes toutes faites comme : Object invoke(Object objet, String methodName, Object... args)

    À partir du moment où l'on dit C'est pas testable, ton idée est effectivement bonne. Il me semble qu'on peut la voir comme une forme du pattern Template, non ?
    Je ne pense pas, ici c'est juste un héritage tout bête. Je te laisse regarder en détail le pattern Template. Par contre, tu pourrais faire en sorte que pour tes tests, tu utilises ta version spécialisée de ton BufferedReader qui fait un test si oui ou non le buffer a été flushée, comment ?
    Simplement en faisant en override de toutes les méthodes d'écritures et en ajoutant un boolean flushed.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    BufferedReader getBufferedReader(Reader reader) {
        // return new BufferedReader(reader);
        return new TestBufferedReader(reader);
    }

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 334
    Points : 36 855
    Points
    36 855
    Par défaut
    Stricto sensu, le pattern template permet de factoriser l'implémentation de certaines méthodes pour en laisser certains détails à des classes dérivées.

    Dans notre cas, nous n'avons pas grand chose à factoriser sinon "adapter" un peu l'objet BufferedWriter pour qu'il n'oublie pas de faire un flush avant le close.

    - W

  10. #10
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    À partir de quel moment un héritage tout bête devient un pattern Template... Avec un jeu de méthodes final et abstract, mais aucun des deux ne semble vraiment obligatoire, d'après l'article de wikipedia.

    Bon, merci à tous, grâce à vous je vais me remettre au travail sur ces questions !

  11. #11
    Membre averti
    Profil pro
    Développeur Java
    Inscrit en
    Novembre 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2007
    Messages : 301
    Points : 368
    Points
    368
    Par défaut
    Je cite (Template Method [GOF]) :
    "A template method defines an alogorithm in terms of abstract operations that subclass override to provide concrete behavior."

    Mon exemple de Template correponds exactement à ça. L'algorithme est execute, il définit un ensemble d'étapes et une opération abstraite qui est handle. Celle-ci va être surchargée par les classes filles.

    Dans ton cas, tu n'as pas de classe Template. Tu as un BufferedWriter qui définit une méthode close mais qui ne définit aucun algorithme et aucune opérations abstraites. Tu as simplement surchargée cette méthode pour lui ajouter un comportement. Et il n'y a dans ton exemple qu'une seule classe fille ce qui n'est pas non plus la philosophie du Template.

    En effet, on peut aussi le rapprocher du modèle de conception : Stratégie. C'est en cela que l'on voit qu'il y a plusieurs classes filles qui ont chacune un comportement différent pour chaque méthode abstraite.

    Si tu utilisais mon example de Template, tu serais obligé de définir autant de classe que tu as de traitements sur tes BufferedWriter.

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 334
    Points : 36 855
    Points
    36 855
    Par défaut
    dériver et surcharger correspond mieux au pattern adapter.
    - W

  13. #13
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Oui, ok, sauf que la classe BufferedWriter descend de la classe Writer, qui est abstract, qui stipule diverses méthodes abstraites et concrètes, dans l'objectif de définir un modèle d'écriture de flux de caractères. Alors Writer est un Template selon la définition du GOF. Donc BufferedWriter est aussi un Template, puisque il hérite de Writer. Le fait qu'il soit une concrétisation ne l'empêche pas de conserver les propriétés du modèle, et de pouvoir servir de modèle à son tour.

    Certes, ton exemple correspond très bien à la définition également, et je t'en remercie. Il me permet de réfléchir pour trouver si ma problématique est vraiment différente de celle du BufferedWriter, auquel cas j'ai meilleur compte à créer un Template séparé comme tu le proposes, ou si c'est pareil à peu de choses près, auquel cas je sous-classe BufferedWriter. Il y a aussi la piste des interfaces Flushable et Closeable qui pourraient me servir de base.

    Je crois qu'il faut laisser ouvertes toutes ces définitions et tous ces principes, tout en conservant et comprenant leurs formes originales, pour voir comment ils découvrent différents cas.

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 334
    Points : 36 855
    Points
    36 855
    Par défaut
    Hu?!? Je préfére mettre une certaine distance entre les patterns de conception et les implémentations. Sinon nous allons dire qu'un template C++ colle au pattern template.
    - W

  15. #15
    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
    Citation Envoyé par darkxan Voir le message
    Il n'y a pas de moyen de savoir s'il y a eu un flush ou non. La solution est de faire un flush() avant de faire le close().
    A moins d'avoir raté un concept, je ne vois pas l'intérêt de faire un flush() suivit d'un close() puisque la méthode close() fait un flush() avant comme indiqué dans la doc
    http://java.sun.com/javase/6/docs/ap...redWriter.html
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void close()  
              Closes the stream, flushing it first.
    Y aurait-il une raison particulière ou s'agit-il d'un problème lié à autre chose qu'un BufferedWriter ?

  16. #16
    Membre averti
    Profil pro
    Développeur Java
    Inscrit en
    Novembre 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2007
    Messages : 301
    Points : 368
    Points
    368
    Par défaut
    LOL. Je me disais depuis hier que c'était étrange qu'il ne faisait pas un flush avant de faire un close. Je me suis fait avoir car dans la doc 1.4 sur le BufferedWriter il ne le mentionne pas.

  17. #17
    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
    Citation Envoyé par darkxan Voir le message
    LOL. Je me disais depuis hier que c'était étrange qu'il ne faisait pas un flush avant de faire un close. Je me suis fait avoir car dans la doc 1.4 sur le BufferedWriter il ne le mentionne pas.
    Disons que le lien n'est pas direct, mais si tu cliques sur close dans
    Specified by:close in class Writer
    ils le disent également

  18. #18
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Ce n'est pas aussi clair que ce que dit la doc, malheureusement. Moi aussi j'avais été surpris, surtout en constatant que mes closes avaient toutes les caractéristiques d'un flush mal fait.

    Voici les sources 1.6 des flush et close du BufferedWriter :
    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
         public void flush() throws IOException {
    	synchronized (lock) {
    	    flushBuffer();
    	    out.flush();
    	}
        }
     
        public void close() throws IOException {
    	synchronized (lock) {
    	    if (out == null) {
    		return;
    	    }
    	    try {
    	        flushBuffer();
    	    } finally {
    	        out.close();
    	        out = null;
    	        cb = null;
    	    }
    	}
        }
    On voit donc que le close fait une sorte de flush incomplet par rapport à la méthode flush (seulement flushBuffer, sans out.flush). Je ne peux pas l'affirmer mordicus, n'ayant pas tout compris du code du BufferedWriter, mais...

    Coté BufferedOutputStream, à voir le code, les choses sont plus claires : close appelle bien la méthode flush elle même, donc le close fait bien un flush complet chez les streams.

    Qu'en pensez-vous ?

  19. #19
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 334
    Points : 36 855
    Points
    36 855
    Par défaut
    On voit donc que le close fait une sorte de flush incomplet par rapport à la méthode flush (seulement flushBuffer, sans out.flush). Je ne peux pas l'affirmer mordicus, n'ayant pas tout compris du code du BufferedWriter, mais...
    Est-ce que out.close n'appelle pas out.flush?

    La cause de la cause?
    Si cela n'est pas la cause du problème qui vous a posé tracas, ajouter des "flush" contournerait un problème dont la cause n'a pas été identifiée...
    Ce qui est quand même pus génant (pour votre application).
    - W

  20. #20
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Dans mon cas le BufferedWriter contenait un FileWriter ; pour le FileWriter, c'est le OutputStreamWriter qui s'occupe des flush et close. Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        public void flush() throws IOException {
    	se.flush();
        }
     
        public void close() throws IOException {
    	se.close();
        }
    Donc, pas d'appel du flush dans le close à ce niveau là. Quand à se, c'est un sun.nio.cs.StreamEncoder, dont les sources ne sont pas dispo ; je ne peux pas remonter plus loin.

    Il est vrai que l'origine du problème peut être discutée, tant qu'il n'a pas été prouvé que close n'appelle pas systématiquement le flush. En tous les cas je n'ai pas vu du bug enregistré là dessus.

    Mumpf. Pas facile. Peut être que je coupe des cheveux en 4 dans la mauvaise direction.

Discussions similaires

  1. Réponses: 1
    Dernier message: 27/04/2009, 22h59
  2. comment tester qu'un fichier existe bien
    Par adilou1981 dans le forum Langage
    Réponses: 2
    Dernier message: 05/06/2007, 09h57
  3. Comment tester qu'une base est bien présente?
    Par xilay dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 20/10/2005, 16h26
  4. Comment tester qu'un objet String est bien initialisé
    Par Jones dans le forum Servlets/JSP
    Réponses: 8
    Dernier message: 17/09/2004, 11h29
  5. comment tester si une fonction fait bien son travail
    Par access dans le forum Requêtes
    Réponses: 1
    Dernier message: 24/11/2003, 15h46

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