Appeler une commande shell en java

Résolu/Fermé
jklms Messages postés 13 Date d'inscription lundi 14 octobre 2013 Statut Membre Dernière intervention 12 mai 2014 - Modifié par jipicy le 19/01/2014 à 13:45
jklms Messages postés 13 Date d'inscription lundi 14 octobre 2013 Statut Membre Dernière intervention 12 mai 2014 - 5 févr. 2014 à 18:20
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?
A voir également:

5 réponses

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
19 janv. 2014 à 13:46
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);
0
jklms Messages postés 13 Date d'inscription lundi 14 octobre 2013 Statut Membre Dernière intervention 12 mai 2014
19 janv. 2014 à 14:00
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é.
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
Modifié par KX le 19/01/2014 à 14:30
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());
0
jklms Messages postés 13 Date d'inscription lundi 14 octobre 2013 Statut Membre Dernière intervention 12 mai 2014
19 janv. 2014 à 14:49
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...
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
19 janv. 2014 à 15:17
Tu peux également préciser le répertoire courant à utiliser dans la commande exec.

Process processus = rt.exec(cmd, null, new File("C:/..../monDossier/"));
0
jklms Messages postés 13 Date d'inscription lundi 14 octobre 2013 Statut Membre Dernière intervention 12 mai 2014
19 janv. 2014 à 16:10
c'est parfait, merci beaucoup
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
jklms Messages postés 13 Date d'inscription lundi 14 octobre 2013 Statut Membre Dernière intervention 12 mai 2014
5 févr. 2014 à 15:52
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 ;)
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
5 févr. 2014 à 18:15
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"};
0
jklms Messages postés 13 Date d'inscription lundi 14 octobre 2013 Statut Membre Dernière intervention 12 mai 2014
5 févr. 2014 à 18:20
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 ;)
0