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

Langage Java Discussion :

Execution d'un programme perl avec exec


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 15
    Par défaut Execution d'un programme perl avec exec
    Bonjour,

    je suis entrain de développer une application qui sera un portail web où on pourra lancer différents outils qui sont des programmes perl.
    J'ai lu pas mal de docs sur la classe runtime et sa fonction exec. et voici ce que j'ai reussi en en tirer: voici mon 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
     
    // On execute l'outil				
    				Runtime runtime = Runtime.getRuntime();
     
    				final Process process = runtime.exec(new String[] { "mfold_outputXML_2.pl", "T", temp, "Na", na, "Mg", mg, "-seqfile", "seqs.fasta"} );
    				try{				
    					int fin = process.waitFor();
    					System.out.println("apres wait : "+fin);
    					System.out.println("La valeur de sortie de l'executione est:"+process.exitValue());						
    				}
    				catch(InterruptedException ie){
    					ie.printStackTrace();
    					System.out.println("InterruptedException : Application interrompu par le System");				
    				}
    				catch(IllegalThreadStateException itse){
    					itse.printStackTrace();
    					System.out.println("IllegalThreadStateException : Application interrompu par le System");
    				}
     
    				new Thread() {
    					public void run() {
    						try {
     
    							BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    								String line = "";
    								try {
    									while((line = reader.readLine()) != null) {
    										// Traitement du flux de sortie de l'application si besoin est
    										sortie = sortie.concat(line);										
    									}
    								} finally {
    									reader.close();
    								}
     
    							} catch(IOException ioe) {
    								ioe.printStackTrace();
    								System.out.println("IOExc : Application interrompu par le System");
    							}
     
    						}
     
    				}.start();
     
     
    				System.out.println("Finsortie : "+sortie+"\n");
    Mon problème est que quand je lance le script perl en ligne de commande celui-ci s'execute parfaitement bien mais il met quelques secondes.
    Quand je lance mon application java, il lance bien le programme perl, mais on dirait qu'il s'arrête au milieu, car dans mon affichage de la variable sortie je n'est que les première lignes de la sortie du programme. Il n'affiche pas les lignes qui apparaissent qu'au bout de quelques secondes. Et surtout je n'ai aucun résultats.
    Autre chose, la methode waitFor(), renvoi 2, ainsi que la methode exitValue().
    Je ne sais pas a quoi cela correspond (ça ne devrait pas renvoyer 0 si le programme s'execute bien??).

    Merci de votre aide.

  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,


    Quelques remarques :
    • Tu lances ton thread de lecture après le waitFor(), et donc après la fin de ton script perl. Si ce dernier écrit un trop grand nombre de données dans ses sorties standards ou d'erreurs tu peux te retrouver dans un cas d'interblocages (les 2 programmes s'attendent mutuellement). il faut effectuer les traitements sur les flux d'E/S juste après avoir lancé le programme, et avant le waitFor()...
    • Tu ne lis pas le flux d'erreur... or c'est généralement là où se trouverait un éventuel message d'erreur. De plus, si tu ne traites pas un flux (stdin, stdout ou stderr), je te conseille fortement de le fermer...
    • Tu utilises concat() pour concaténer des chaines, ce qui peut être un gouffre en terme d'utilisation mémoire et de performance. Préfère lui un StringBuffer voir StringBuilder (équivalent non synchronisé).
    • Tu as un problème de synchronisation sur la variable "sortie", car tu la lis juste après avoir lancé le thread qui doit la renseigner... il y a de forte chance qu'elle soit encore vide...
    • Ton code n'est pas portable (je ne sais pas si c'est une nécessité pour toi), car je ne pense pas qu'il soit possible de lancer un script perl de cette manière sous Windows...



    Plus d'info :



    a++

  3. #3
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 15
    Par défaut
    Merci pour tes conseils, j'ai reussi à faire tourner mon application.
    Mais maintenant j'ai un autre problème. Mon scripts perl genère un dossier avec plusieurs fichiers, il me créer ce repertoire par défaut à la racine de mon home. Je voudrais qu'il le mette dans un dossier que j'ai créer préalablement.
    J'ai essayer avec cette commande juste avant le lancement du script perl, pour qu'il se place dans le dossier voulu. Mais aucun résultat, il me met qd même le rep résultat à la racine.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    final Process process1 = runtime.exec(new String[] { "/bin/sh", "-c",  "cd", "/home/richarde/essaiLaunchTool"});
    final Process process = runtime.exec(new String[] { "mfold_outputXML_2.pl", "T", temp, "Na", na, "Mg", mg, "-seqfile", "/anais/IT/reference/sequences/Interface-BioinfoTools/6-Code/Scripts_perl/TestMfold/seqs.fasta"} );
    Si vous avez une solution elle est la bienvenue, merci.

    Sinon autre question comment ferme t'on un flux, stdin par exemple dont je ne me sert pas?

  4. #4
    Membre chevronné Avatar de Rayndell
    Étudiant
    Inscrit en
    Mai 2007
    Messages
    289
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2007
    Messages : 289
    Par défaut
    En Java l'entrée standard (stdin en C) est accessible via le champ System.in.

    Elle est de type InputStream, qui possède une méthode close().

  5. #5
    Membre expérimenté Avatar de hydraland
    Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mai 2006
    Messages : 179
    Par défaut
    Salut,

    Pour fermer le flux d'entrée de ton processus tu dois faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    process.getInputStream().close()
    Pour ton problème de répertoire il faut que tu lances ton processus avec la méthode http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#exec(java.lang.String[],%20java.lang.String[],%20java.io.File).(Le troisième argument est celui qui devrait te convenir).

    A+
    Hydraland

  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 La Goule
    J'ai essayer avec cette commande juste avant le lancement du script perl, pour qu'il se place dans le dossier voulu. Mais aucun résultat, il me met qd même le rep résultat à la racine.
    C'est normal puisque les deux commandes sont complètement indépendante l'une de l'autre...

    Il vaut mieux utiliser la méthode exec() qui prend le chemin d'exécution en paramètre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    final Process process = runtime.exec(new String[] { "mfold_outputXML_2.pl", "T", temp, "Na", na, "Mg", mg, "-seqfile", "/anais/IT/reference/sequences/Interface-BioinfoTools/6-Code/Scripts_perl/TestMfold/seqs.fasta"},
       null, // variable d'environnement par défaut
       new File("/home/richarde/essaiLaunchTool") // répertoire d'exécution
    );
    Mais il faudra spécifier le chemin complet vers le script perl dans ce cas, à moins qu'il ne soit dans le PATH...


    Citation Envoyé par La Goule
    Sinon autre question comment ferme t'on un flux, stdin par exemple dont je ne me sert pas?
    Citation Envoyé par Rayndell
    En Java l'entrée standard (stdin en C) est accessible via le champ System.in.
    Je parlais des flux du process lancé, qui sont inversé lorsqu'on les utilises depuis le programme Java. Ils sont accessible via les méthode getOutputStream(), getInputStream() et getErrorStream() de la classe Process.

    Par exemple pour fermer le flux d'entrée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    process.getOutputStream().close();
    a++

    [edit] grillé

Discussions similaires

  1. lancé un programme perl avec un click droit.
    Par bubu251 dans le forum Langage
    Réponses: 1
    Dernier message: 28/05/2007, 13h40
  2. Impossible d'executer un programme perl avec TK
    Par pentaracing dans le forum Interfaces Graphiques
    Réponses: 10
    Dernier message: 26/04/2007, 08h50
  3. executer une commande non perl avec perl
    Par kolombo dans le forum Langage
    Réponses: 17
    Dernier message: 07/08/2006, 11h28
  4. Executer un script non Perl avec un script Perl.
    Par jabrane1983 dans le forum Langage
    Réponses: 6
    Dernier message: 03/08/2006, 14h43
  5. Réponses: 20
    Dernier message: 23/06/2006, 20h49

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