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

Entrée/Sortie Java Discussion :

Shell depuis java et IOException


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 20
    Par défaut Shell depuis java et IOException
    Bonjour,
    J'ai créé mon propre shell sur un serveur linux que je dois appeler depuis une application web sous tomcat.
    J'utilise l'API d'adiguba concernant les shell qui, en principe, règle les pbs d'entrée-sortie des flux.
    J'ai encapsulé l'appele de ce shell danjs un thread, comme suit :
    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
     
    package fr.britair.analyzerPVE.thread;
     
    import java.io.IOException;
     
    import org.apache.log4j.Logger;
     
    import com.developpez.adiguba.shell.ProcessConsumer;
    import com.developpez.adiguba.shell.Shell;
     
    import fr.britair.analyzerPVE.constants.Constants;
     
    public class ThreadGenerationPVE implements Runnable{
     
    	/** Logger. */
    	private static Logger log = Logger.getLogger(ThreadGenerationPVE.class);
     
    	private long tempsAttenteAvantVerificationPVEGenere;
     
    	String[] parametresFormatagePVE = new String[9];
     
    	public String[] getParametresFormatagePVE() {
    		return parametresFormatagePVE;
    	}
     
    	public void setParametresFormatagePVE(String[] parametresFormatagePVE) {
    		this.parametresFormatagePVE = parametresFormatagePVE;
    	}
     
    	public void run() {
    //		MainClientSafetyPveGenerator.main(getParametresFormatagePVE());
    		StringBuilder stringBuilder = new StringBuilder();
    		stringBuilder.append(Constants.RUN_SHELL_PVE);
    		stringBuilder.append(" ");
    		for (int i = 0; i < getParametresFormatagePVE().length; i++) {
    			if (i!=5)
    				stringBuilder.append(getParametresFormatagePVE()[i]);
    			else
    				stringBuilder.append("\""+getParametresFormatagePVE()[i]+"\"");
    			if (i != getParametresFormatagePVE().length-1)
    				stringBuilder.append(" ");
    		}
    		log.error("COMMANDE SHELL = " +stringBuilder.toString());
    		Shell shell = new Shell();
    		ProcessConsumer process = shell.command(stringBuilder.toString());
    		try {
    			int result = process.consume();
    		} catch (Exception e) {
    			log.error("IOException dans l'execution du Shell " + Constants.RUN_SHELL_PVE);
    			e.printStackTrace();
    		}
    	}
     
    	public long getTempsAttenteAvantVerificationPVEGenere() {
    		return tempsAttenteAvantVerificationPVEGenere;
    	}
     
    	public void setTempsAttenteAvantVerificationPVEGenere(
    			long tempsAttenteAvantVerificationPVEGenere) {
    		this.tempsAttenteAvantVerificationPVEGenere = tempsAttenteAvantVerificationPVEGenere;
    	}
     
    }
    Puis dans mon appli web, j'appelle ce thread tout simplement avec la méthode
    'start' du thread.
    Le shell est censé me générer ou pas des fichiers XML.
    Il m'arrive parfois dans mon code d'iterer plusieurs fois l'appel à ce thread qui m'execute mon Shell linux, de la façon 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
     
    for(Object[] objects : listeRoutes)
    {
     
    						ThreadGenerationRoute threadGenerationRoute = new ThreadGenerationRoute();
    						threadGenerationRoute.setParametresGenerationRoute(parametresGenerationRoute);
    						Thread t = new Thread(threadGenerationRoute);
    						/** Appel du gestionnaire PVE **/
    						log.error("##### APPEL DU GESTIONNAIRE DE GENERATION D'UNE ROUTE SECOURS pour la Route " + aeroportDepart+"/"+aeroportArrivee+"/"+groupeAvion+"/"+route);
    						t.start();
    						try {
    							int nb=0;
    							//On vérifie si le fichier est arrivé toutes les 50 sec.
    							while(!verifiePresenceFichierLogSecoursGenere(fichierGenere) && nb<12) {
    								log.error("##### On attend "+(50000)/1000+" sec. de plus avant de verifier si le fichier XML de la route est là");
    								Thread.sleep(50000);
    								nb++;
    							}
    						} catch (InterruptedException e1) {
    							throw new CommonsRuntimeException("InterruptedException dans la méthode sleep du Thread courant d'appel à la génération de route ");
    						}
    //						log.error("## INTERRUPTION DE L'APPEL A LA GENERATION DE LA ROUTE ##");
    						t.interrupt();
    }
    //fin for
    }

    Or il se trouve que j'ai toujours des IOException lorsque j'appelle ce thread plusieurs fois avec mon itération de la boucke for.
    Je pensais que l'API d'adiguba réglait les pbs d'I/O mais apparemment j'ai tjs des pbs d'I/O, ce qui a pour effet d'arreter le serveur TOMCAT lorsque cette Exception est rencontrée.
    Quelq'un aurait il une idée ?
    Merci.

  2. #2
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,


    Tu obtiens quoi comme exception exactement ?

    a++

  3. #3
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 20
    Par défaut
    Salut,
    tout d'abord merci pour l'explication de ton API sur le site.
    En fait l'exception est rencontrée dans la méthode "consume" comme dans mon code ci-dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    try {
    	int result = process.consume();
    } catch (Exception e) {
    	log.error("IOException dans l'execution du Shell " + Constants.RUN_SHELL_PVE);
    	e.printStackTrace();
    }
    Mais ceci est aléatoire car lors de mes tests d'intégration je n'ai pas réussi à reproduire l'exception à chaque fois.

    Pour être plus précis, j'ai 2 shells différents que j'ai encapsulé chacun dans un e classe thread, comme je l'ai expliqué.
    L'appel à un de ces shell se fait de la façon 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
     
    ThreadGenerationRoute threadGenerationRoute = new ThreadGenerationRoute();
    						threadGenerationRoute.setParametresGenerationRoute(parametresGenerationRoute);
    Thread t = new Thread(threadGenerationRoute);
    /** Appel du gestionnaire PVE **/
    log.error("##### APPEL DU GESTIONNAIRE DE GENERATION D'UNE ROUTE SECOURS pour la Route " + aeroportDepart+"/"+aeroportArrivee+"/"+groupeAvion+"/"+route);
    	t.start();
    	try {
    	int nb=0;
    	//On vérifie si le fichier est arrivé toutes les 50 sec.
    							  while(!verifiePresenceFichierLogSecoursGenere(fichierGenere) && nb<12) {
    								log.error("##### On attend "+(50000)/1000+" sec. de plus avant de verifier si le fichier XML de la route est là");
    	Thread.sleep(50000);
    	nb++;
    	}
    	} catch (InterruptedException e1) {
    	throw new CommonsRuntimeException("InterruptedException dans la méthode sleep du Thread courant d'appel à la génération de route ");
    	}
    //	log.error("## INTERRUPTION DE L'APPEL A LA GENERATION DE LA ROUTE ##");
    	t.interrupt();
    Je vais donner quelques petites explications :
    Ce code est dans une classe d'action STRUTS. J'appelle le shell en instanciant la classe thread contenant ton API d'execution de mon shell puis j'appelle la méthode 'start' de ce thread. Ce shell est censé me généré un fichier XML. Ce calcul est tyrès long, donc je vérifie si ce fichier XML est arrivé toutes les 50 secondes (boucle 'while'). Si le fichier est arrivé interruption du thread d'appel du shell.
    Après l'arrivée de ce fichier XML, je fais une verification. En fonction de cette vérification, je dois appeler ou pas 'X' fois le 2ème SHELL encapsulé dans un thread. C'est le code que j'ai posté au début. Et c'est là que je rencontre l'IOException.

    Je n'ai pas besoin des flux de sorties, erreurs ... évoqués dans ton API.
    Y aurait-il un probleme avec l'écriture dans le fichier "catalina.out" de sortie standard de TOMCAT.

    Merci beaucoup pour ton idée.
    A +.

  4. #4
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par gbruno
    En fait l'exception est rencontrée dans la méthode "consume" comme dans mon code ci-dessous :
    Mais en fait il me faudrais surtout le stacktrace de l'exception qui est remonté...

    Citation Envoyé par gbruno
    Ce shell est censé me généré un fichier XML. Ce calcul est tyrès long, donc je vérifie si ce fichier XML est arrivé toutes les 50 secondes (boucle 'while'). Si le fichier est arrivé interruption du thread d'appel du shell.
    Ton exception peut venir de là : lorsqu'elle reçoit une interruption la méthode consume() est censé remonté une InterruptedIOException...

    Citation Envoyé par gbruno
    Je n'ai pas besoin des flux de sorties, erreurs ... évoqués dans ton API.
    Y aurait-il un probleme avec l'écriture dans le fichier "catalina.out" de sortie standard de TOMCAT.
    Normalement non, mais si le programme appelé écrit un grand nombre de donnée cela peut être gênant. Dans ce cas il suffit de désactiver les traces :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int result = process.output().error().consume();
    a++

  5. #5
    Membre averti
    Inscrit en
    Octobre 2006
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 20
    Par défaut
    Mais en fait il me faudrais surtout le stacktrace de l'exception qui est remonté...
    Pour l'instant je ne peux te proposer de stacktrace car je vide le fichier de sortie de catalina.out lorsque je redémarre le serveur Tomcat or à chaque fois qu'est rencontrée cette Exception ça a pour effet d'arreter le serveur Tomcat.
    Je peux te donner le stacktrace dès que je rencontrerai l'erreur.


    Ton exception peut venir de là : lorsqu'elle reçoit une interruption la méthode consume() est censé remonté une InterruptedIOException...
    Dans ce cas crois-tu que je peux lever l'exception en supprimant la ligne
    après la boucle while qui teste toutes les N secondes si le fichier est arrivé ??
    Le fait de ne pas faire d'"interrupt" sur le thread qui appelle le shell que j'ai créé. Il sera toujours vivant non ? Ce n'est pas grave ?

    int result = process.output().error().consume();
    Cette ligne n'aura aucun effet sur le fichier de sortie de Tomcat ? Car j'ai besoin des traces de Tomcat ...
    Penses-tu que cette ligne de code peux résoudre mon probleme aussi ?
    Merci beaucoup pour ton aide.
    A +

  6. #6
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par gbruno
    Dans ce cas crois-tu que je peux lever l'exception en supprimant la ligne
    après la boucle while qui teste toutes les N secondes si le fichier est arrivé ??
    Le fait de ne pas faire d'"interrupt" sur le thread qui appelle le shell que j'ai créé. Il sera toujours vivant non ? Ce n'est pas grave ?
    La méthode consume() renvoi un InterruptedException si elle reçoit un interrupt pendant son traitement.

    Donc tu as deux solutions :
    • Soit tu continues à envoyer l'interrupt pour arrêter "violemment" le process et tu "ignores" l'InterruptedException.
    • Soit tu supprimes l'interrupt et dans ce cas le thread sera terminé à la fin du process que tu lances (consume() se termine en même temps que le process fils).


    La question est surtout de savoir pourquoi tu le lances dans un thread et que tu vérifies le fichier en parallèle...

    Ne serait-il pas préférable d'attendre simplement la fin de consume() et de traiter le fichier une fois que le process est complètement terminée ?

    Citation Envoyé par gbruno
    Cette ligne n'aura aucun effet sur le fichier de sortie de Tomcat ? Car j'ai besoin des traces de Tomcat ...
    Non.
    Par défaut consume() copie les flux de sortie du process lancé dans les flux de sortie de l'application Java, qui correspondent au fichier "catalina.out" sous Tomcat. Cette ligne indique seulement que les flux de sortie et d'erreur du process doivent être ignoré au lieu d'être réécrit sur la sortie...

    Citation Envoyé par gbruno
    Penses-tu que cette ligne de code peux résoudre mon probleme aussi ?
    Non : cela se contentera de ne pas écrire la sortie du process dans le fichier de sortie de Tomcat, et donc potentiellement limité la taille des logs si ton process génère un grand nombre de trace...


    a++

Discussions similaires

  1. Réponses: 3
    Dernier message: 10/01/2008, 12h08
  2. [Système]commandes linux / unix depuis java
    Par msiramy dans le forum API standards et tierces
    Réponses: 12
    Dernier message: 20/03/2007, 11h29
  3. [débutant]lancement d'une commande Unix ou LInux depuis Java
    Par msiramy dans le forum API standards et tierces
    Réponses: 6
    Dernier message: 30/09/2005, 18h10
  4. [Info] Appeler une fonction Ada95 depuis Java
    Par mmathieu dans le forum API standards et tierces
    Réponses: 6
    Dernier message: 15/09/2005, 09h42
  5. [debutant] créer un alias odbc depuis java
    Par chassonj dans le forum JDBC
    Réponses: 5
    Dernier message: 08/07/2004, 15h03

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