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

avec Java Discussion :

StdErr et Thread ?


Sujet :

avec Java

  1. #1
    Nouveau membre du Club
    Profil pro
    technicien
    Inscrit en
    Avril 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : technicien

    Informations forums :
    Inscription : Avril 2013
    Messages : 32
    Points : 25
    Points
    25
    Par défaut StdErr et Thread ?
    Bonjour,
    Depuis quelques jours je me prends pas mal la tête.
    J'ai un jar inclus dans mon programme java.
    Je lance une commande du jar depuis mon programme java et les résultats sortent sur la sortie stdout et stderr.
    Comme j'ai besoin de ce résultat je me suis dis, pas de problème on va capturer les sorties en mémoire via ByteArrayOutputStream.
    Sous eclipse -> pas de pb
    En production, cela ne fonctionne pas, la sortie err n'est pas capturé et la commande est lancée avec du retard par rapport aux suites d'instructions de mon programme.
    Je me suis dis : problème de thread.
    Donc vas y implémente un thread. Bon, toujours pas de résultat. J'ai arrêté de vouloir charger la mémoire, j'ai suivi ce tuto https://blogs.oracle.com/nickstephen...system_out_and pour rediriger les sorties vers un fichier.
    La je crée le thread à partir d'une fonction, la redirection, la commande et ré-applique System.out, Sytem.err aux anciennes valeurs.
    Puis le thread est lance et .
    Je ne capture toujours pas la sortie stderr mais la sortie sdtout, oui.

    Désolé si je suis confus,
    Là je suis perdu...
    Merci

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Quand tu parles de lancer une commande du jar, tu veux dire que tu exécutes une méthode main() d'une classe du jar avec une commande du type "java -jar ..." ? Dans ce cas utilise un ProcessBuilder, et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ProcessBuilder pb = new ProcessBuilder( "java", "-jar"...);
     
    pb.redirectError(Redirect.toFile( errfile ));
    pb.redirectOutput(Redirect.toFile( stdfile ));
    pb.start();
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Nouveau membre du Club
    Profil pro
    technicien
    Inscrit en
    Avril 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : technicien

    Informations forums :
    Inscription : Avril 2013
    Messages : 32
    Points : 25
    Points
    25
    Par défaut
    Effectivement j'avais pensé à cette possibilité. Je ne l'ai pas tester car j'aimerais vraiment inclure le jar dans le projet et de directement appeler une commande de ce jar. Ca m’évite de vérifier le path du jar, et je maîtrise cette version. Tant que je ne recompile pas mon projet j'utilise toujours la même version.
    J'ai réussi à capturer ce flux d'erreur quelquefois mais je pense que c'est aléatoire.
    Y a t il une suite logique entre Thread - Capture du flux d'erreur - Tache ?

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par The_GuiGui Voir le message
    de directement appeler une commande de ce jar.
    Tu ne répoonds pas directement à ma question ! Je déduis du fait que tu ne confirmes pas sur le fait que tu exécutes un "java -jar" que tu parles en fait d'invoquer directement une méthode d'une classe de ce jar.

    Normalement, il n'y a pas de raison d'invoquer la méthode dans un thread. Il y a une problématique à prendre en compte : les sorties standard et erreur sont bufferisées, rien ne garantit donc que l'invocation terminée, le flux soit complètement vidé dans ton fichier. Essaye simplement de forcer le vidage par appel de flush(), au retour de l'appel de la méthode du jar. En revanche, il méthode utilisé pose un autre problème, la fermeture du fichier. Il faudrait faire une implémentation hybride qui te permet d'indiquer un fichier avant invocation, et de fermer après (ce qui forcera le flush() par la même occasion), ainsi, après invocation, les sorties repartiraient normalement vers la console.

    Si cela ne fonctionne pas, montre-nous alors ton code.

    PS une autre voie serait de faire une invocation par ligne de commande en déterminant dynamiquement l'emplacement du jar. S'il est inclus dans ton application, tu peux en contrôler facilement l'emplacement.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Nouveau membre du Club
    Profil pro
    technicien
    Inscrit en
    Avril 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : technicien

    Informations forums :
    Inscription : Avril 2013
    Messages : 32
    Points : 25
    Points
    25
    Par défaut
    Oui effectivement, je ne fais pas d'appel à "java -jar". Je ne passe pas par "Process Builder" ou par "Runtime".
    J'ai essayé avec un flush sur les 2 sorties et c'est sans effet. Avec ou sans thread c'est le même résultat.
    Voici le code
    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    public static void Main(String args){
     
    	RedirectStream redirect = RedirectStream(new File(path));
    	redirect.CallRedirect();
     
    	Program.Call(args);
     
    	redirect.CallClose();
    }
     
    public class Program{
     
    	public static void Call(String[] args){
    		//Programme contenu dans un jar dans le projet
    		CommandLine c = CommandLine(args);	
    	}
     
    public class RedirectStream {
     
    	private PrintStream oldout;
    	private PrintSteam olderr;
    	private File f;
     
    	public RedirectStream(File f){
    		this.oldout=System.out;
    		this.olderr=System.err;
    		this.f=f;
    	}
     
    	public void CallRedirect(){
            LogManager logManager = LogManager.getLogManager();
            logManager.reset();
     
            // log file max size 10K, 3 rolling files, append-on-open
            Handler fileHandler = new FileHandler(this.f, 10000, 3, true);
            fileHandler.setFormatter(new SimpleFormatter());
            Logger.getLogger("").addHandler(fileHandler);    
            PrintStream stdout = System.out;                                       
            PrintStream stderr = System.err;                                       
     
            Logger logger;                                                         
            LoggingOutputStream los;                                               
     
            logger = Logger.getLogger("stdout");                                   
            los = new LoggingOutputStream(logger, StdOutErrLevel.STDOUT);          
            System.setOut(new PrintStream(los, true));                             
     
            logger = Logger.getLogger("stderr");                                   
            los= new LoggingOutputStream(logger, StdOutErrLevel.STDERR);           
            System.setErr(new PrintStream(los, true));                             
    	}
     
    	public void CloseRedirect(){
     
    	System.out.flush();
    	System.err.flush();
    	System.setOut(this.oldout);
    	System.setErr(this.olderr);
    	}
        }                                                                          
    }                                                                              
    public class StdOutErrLevel extends Level {
     
        private StdOutErrLevel(String name, int value) {
            super(name, value);
        }
     
        public static Level STDOUT =
            new StdOutErrLevel("STDOUT", Level.INFO.intValue()+53);
     
        public static Level STDERR =
            new StdOutErrLevel("STDERR", Level.INFO.intValue()+54);
     
     
    protected Object readResolve()
            throws ObjectStreamException {
            if (this.intValue() == STDOUT.intValue())
                return STDOUT;
            if (this.intValue() == STDERR.intValue())
                return STDERR;
            throw new InvalidObjectException("Unknown instance :" + this);
        }   
    }
     
    class LoggingOutputStream extends ByteArrayOutputStream { 
     
        private String lineSeparator; 
     
        private Logger logger; 
        private Level level; 
     
        public LoggingOutputStream(Logger logger, Level level) { 
            super(); 
            this.logger = logger; 
            this.level = level; 
            lineSeparator = System.getProperty("line.separator"); 
        } 
     
        public void flush() throws IOException { 
     
            String record; 
            synchronized(this) { 
                super.flush(); 
                record = this.toString(); 
                super.reset(); 
     
                if (record.length() == 0 || record.equals(lineSeparator)) { 
                    // avoid empty records 
                    return; 
                } 
     
                logger.logp(level, "", "", record); 
            } 
        } 
    }
    Beaucoup du code est inspiré du blog mentionné.
    Penses tu que faire appel à la méthode du jar en passant par une méthode "static" puisse être le problème. Je n'aurais pas l'ensemble du code sous la main ce week end pour tester...
    Vois tu quelque chose qui puisse être le problème ?

  6. #6
    Nouveau membre du Club
    Profil pro
    technicien
    Inscrit en
    Avril 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : technicien

    Informations forums :
    Inscription : Avril 2013
    Messages : 32
    Points : 25
    Points
    25
    Par défaut
    Bonjour,
    Le fait de passer par une méthode static ne semble pas poser problème car le problème persiste sans.

  7. #7
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Oui, ça, le fait de passer en static ou pas n'a pas de raison de changer quoique ce soit.
    C'est quoi le code de la classe CommandLine ?

    Je n'ai pas le temps de regarder le reste du code du logging pour le moment. Mais j'ai deux autres questions : c'est quoi le jar exactement ? Le code source est-il disponible ?
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  8. #8
    Nouveau membre du Club
    Profil pro
    technicien
    Inscrit en
    Avril 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : technicien

    Informations forums :
    Inscription : Avril 2013
    Messages : 32
    Points : 25
    Points
    25
    Par défaut
    Oui
    Voici le github du code source, la classe c'est CommandLineGatk
    https://github.com/broadgsa/gatk/tre...te/gatk/engine

  9. #9
    Nouveau membre du Club
    Profil pro
    technicien
    Inscrit en
    Avril 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : technicien

    Informations forums :
    Inscription : Avril 2013
    Messages : 32
    Points : 25
    Points
    25
    Par défaut
    Bon j'aurais du lire la doc du soft. Ils détournent leur OutputStream, je vais voir avec eux.
    Merci beaucoup, j'ai pu ecarter une erreur de code de mon cote, je n'aurais pas su avancer sans cela

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  2. récupérer la valeur de sortie d'un thread
    Par jakouz dans le forum Langage
    Réponses: 3
    Dernier message: 31/07/2002, 11h28
  3. Programmer des threads
    Par haypo dans le forum C
    Réponses: 6
    Dernier message: 02/07/2002, 13h53
  4. Réponses: 5
    Dernier message: 12/06/2002, 15h12
  5. [Kylix] Pb de Thread !!
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 25/04/2002, 13h53

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