Appeler une commande shell en java [Résolu/Fermé]

Signaler
Messages postés
13
Date d'inscription
lundi 14 octobre 2013
Statut
Membre
Dernière intervention
12 mai 2014
-
Messages postés
13
Date d'inscription
lundi 14 octobre 2013
Statut
Membre
Dernière intervention
12 mai 2014
-
Bonjour,

Je souhaiterai appeler une commande shell en java. Je veux appeler "pdflatex" sur un fichier tex pour le compiler. J'ai regardé la classe runtime et process, mais ma commande ne semble pas fonctionner :

public class Test {

 /**
  * @param args
  */
 public static void main(String[] args) {
    
        try {
         Runtime rt = Runtime.getRuntime();
         String[] tabcommande = {"pdflatex"};
         String[] tabparam = {"essai.tex"};
   Process processus=rt.exec(tabcommande, tabparam);
   processus.waitFor();
   System.out.println(" exit : " + processus.exitValue());
   System.out.println("ok");
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   System.out.println("error");
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   System.out.println("error");
  } 

 }

}


Mon fichier .tex n'est pas compilé.

Pourtant, quand je fais ça, ca marche :

import java.io.IOException;

/**
 * 
 */

/**
 * @author clem
 *
 */
public class Test2 {

 /**
  * @param args
  */
 public static void main(String[] args) {
    
        try {
         Runtime rt = Runtime.getRuntime();
         Process processus=rt.exec("gedit test2");
   //processus.waitFor();
   //System.out.println(" exit : " + processus.exitValue());
   System.out.println("ok");
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   System.out.println("error");
  }
 }
}


Quelqu'un a une idée?

5 réponses

Messages postés
16327
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
4 mai 2021
2 826
Process processus=rt.exec(tabcommande, tabparam);

Le deuxième argument c'est pour les variables d'environnements. Les paramètres doivent aller dans le premier argument.

String[] cmd = {"pdflatex","essai.tex"};
Process processus = rt.exec(cmd);
Messages postés
13
Date d'inscription
lundi 14 octobre 2013
Statut
Membre
Dernière intervention
12 mai 2014

ok, mais même quand je fais
String[] cmd = {"pdflatex","essai.tex"};
Process processus = rt.exec(cmd);


ou même directement
Process processus = rt.exec("pdflatex essai.tex)

le processus reste dans le waitFor et ne termine pas.
Sans le waitFor, le fichier n'est même pas compilé.
Messages postés
16327
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
4 mai 2021
2 826
Si tu ne fais pas de waitFor tu vas avoir une IllegalThreadStateException au moment où tu fais un processus.exitValue(), il est donc important d'attendre la fin du programme avant d'afficher sa valeur de retour.

Il faudrait aussi lire les messages que tu récupères de la commande, il y a peut-être des informations à en tirer (des erreurs peut-être) :

Process processus = rt.exec(...);

Scanner out = new Scanner(processus.getInputStream());
while (out.hasNextLine())
    System.out.println(out.nextLine());
out.close();

Scanner err = new Scanner(processus.getErrorStream());
while (err.hasNextLine())
    System.err.println(err.nextLine());
err.close();

processus.waitFor();

System.out.println(processus.exitValue());
Messages postés
13
Date d'inscription
lundi 14 octobre 2013
Statut
Membre
Dernière intervention
12 mai 2014

C'est bien ce qu'il me semblait pour le waitFor(). J'ai compris grace toi ce qui n'allait pas, merci : je n'étais pas dans le bon dossier, et un
System.out.println(System.getProperties().get("user.dir"));
m'a permit de m'en rendre compte.

Maintenant, mon fichier latex est bien compilé, mais le résultat pdf est enregistré dans le workspace d'eclipse et pas dans un répertoire que je voudrais. Cela doit être un parametre de pdflatex...
Messages postés
16327
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
4 mai 2021
2 826
Tu peux également préciser le répertoire courant à utiliser dans la commande exec.

Process processus = rt.exec(cmd, null, new File("C:/..../monDossier/"));
Messages postés
13
Date d'inscription
lundi 14 octobre 2013
Statut
Membre
Dernière intervention
12 mai 2014

c'est parfait, merci beaucoup
Messages postés
13
Date d'inscription
lundi 14 octobre 2013
Statut
Membre
Dernière intervention
12 mai 2014

Bon je croyais avoir compris et bien non en fait...
Je veux a partir de mon programme java appelé un jar file (checkstyle)

Quand, dans le dossier /Documents/chTest, je fais :

java -jar checkstyle-5.6-all.jar \-c sun_checks.xml Check.java
Tout marche bien.
(ne vous préoccupez pas des deux arguments de checkstyle, il renvoie un message d'erreur d'usage s'il les deux fichiers xml et java ne sont pas là.

Par contre, quand j'appelle partir de mon programme

public static void main(String[] args) {

try {
System.out.println(System.getProperties().get("user.dir"));
Runtime rt = Runtime.getRuntime();
//Le jar checkstyle-5.6-all.jar a deux arguments (un .xml (s'il y a \-c) et un .java)
String[] tabcommande = {"java -jar checkstyle-5.6-all.jar \\-c sun_checks.xml Check.java"};

Process processus=rt.exec(tabcommande,null, new File((String) "/home/clem/Documents/chTest/"));

Scanner out = new Scanner(processus.getInputStream());
while (out.hasNextLine())
System.out.println(out.nextLine());
out.close();

Scanner err = new Scanner(processus.getErrorStream());
while (err.hasNextLine())
System.err.println(err.nextLine());
err.close();

processus.waitFor();

System.out.println("exit value " + processus.exitValue());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

j'ai ce résultat :

/home/clem/Documents/Eclipse-workspace
java.io.IOException: Cannot run program "java -jar checkstyle-5.6-all.jar \-c sun_checks.xml Check.java" (in directory "/home/clem/Documents/chTest"): java.io.IOException: error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:488)
at java.lang.Runtime.exec(Runtime.java:612)
at Test2.main(Test2.java:25)
Caused by: java.io.IOException: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.<init>(UNIXProcess.java:164)
at java.lang.ProcessImpl.start(ProcessImpl.java:81)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:470)
... 2 more

J'ai déjà eu une exception FileNotFound, mais je comprends pas puisque le fichier est bien là...

Si quelqu'un a une idée je sèche. merci ;)
Messages postés
16327
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
4 mai 2021
2 826
Soit tu mets toute ta commande dans un String, soit tu la mets dans un String[] mais en mettant chaque argument dans une case distincte. Comme tu as fait il pense que le programme à exécuter est "java -jar ..." or le programme c'est juste "java" car "-jar" est une option.

String[] tabcommande = {"java", "-jar", "checkstyle-5.6-all.jar", "\\-c" "sun_checks.xml" "Check.java"};
Messages postés
13
Date d'inscription
lundi 14 octobre 2013
Statut
Membre
Dernière intervention
12 mai 2014

Ah d'accord, en fait j'avais essayé ça, mais j'avais laissé les espaces à la fin de chaque chaine de caractère, et ca marchait pas comme ça... Du coup là, c'est bon. merci ;)