[Java]Lancement appli. par Runtime.exec() [Résolu] - OK avec calc.exe, pas OK pour Apache.exe

Problème résolu, voir mon post du "29/05/2006, 03:00:17"

Bonsoir les gens,

J’essaie de me faire une petite application Java pour lancer des applications.
J’utilise Runtime.exec(String command)command est la ligne de commande pour lancer l’application en question.
Lorsque la commande “calc.exe”, “notepad.exe”, “mspaint.exe”, il n’y pas de :??: problèmes, la calculatrice, le bloc-note ou Paint se lancent et sont fonctionnels (utilisables).
Cependant, le but de mon programme est de lancer un logiciel tel que Apache dont la ligne de commande (de lancement) est plus complexe que “notepad.exe”, j’utilise :

"C:\Program Files\Apache 2.0.55\Apache2\bin\Apache.exe" -w -f "C:\Program Files\Apache 2.0.55\Apache2\conf\httpd-php4.conf" -d "C:\Program Files\Apache 2.0.55\Apache2\."

Cette commande qui marche (lance Apache et Apache est utilisable) lorsqu’elle est tapée dans une console, refuse de marcher lorsque qu’elle est executée par mon programme Java : Il y a bien un Apache dans la liste des Processus Windows, mais impossible de contacter mon serveur web via un navigateur web.

Ce que j’ai remarqué c’est que lorsque je lance la commande pour Apache depuis une console, ce n’est pas 1 mais 2 processus Apache qui apparaissent dans la liste des processus, alors que lorsque lancée par mon programme Java, il n’y en a qu’un seul.

J’ai donc controlé, avec Process Explorer, le lancement des processus dans les 2 cas (console et programme Java) pour voir plus en details les différences.
Il s’avère que dans le cas qui marche (par console) il y a bien 2 processus “Apache.exe” mais l’un est le fils de l’autre.
Dans le cas non fonctionnel (programme Java), il n’y a bien qu’un seul processus, sans fils.

Alors est-ce que, quelque part, le processus Apache lancé par mon programme Java est empêché (par quoi ?) de lancer un second processus Apache ? Pourquoi ?

J’aimerais avoir vos avis sur le sujet s’il vous plait :slight_smile:

pourrai tu mettre sur le forum la ligne de code que tu utilise pour vérification ?

J’utilise :

process = Runtime.getRuntime().exec(command);

command est une String contenant la ligne de commande.
Je récupère le Process pour pouvoir appeller Process.destroy() par la suite.

c’etait surtout le string command qui m’interessait.

perso :
String command = "\"C:\\Program Files\\Apache 2.0.55\\Apache2\\bin\\Apache.exe" + " -w -f" + "\"C:\\Program Files\\Apache 2.0.55\\Apache2\\conf\\httpd-php4.conf\""+ " -d" + "\"C:\\Program Files\\Apache 2.0.55\\Apache2\\.\"";

Le string est créé par lecture d’un fichier XML, tu penses que ca viendrait de la ligne de commande qui serait altérée lorsque lu par le parseur XML (qui est SAX) ?

a mon avis ce serait la seule explication
le mieux serait d’afficher ce string à l’écran

Je viens de vérifier et la commande est OK, identique à celle entrée dans le fichier XML.

Solution d’appoint : ajoute apache dans ton path?

Autre solution de contournement: est-ce qu’on peut lancer un .bat avec Runtime.exec ?

réussi au bout de 30 minutes :


try
        {           
            Runtime.getRuntime().exec("C:\\test.bat",null,new File("C:\\"));      
        } 
        catch (Exception ex)
        {
           ex.printStackTrace();            
        }

:super: merci, C’est cool.
Raynor> je pense que le problème est dans les noms de fichiers à espace ou dans les paramètres, alors tu peux commencer par lancer un .bat dans un répertoire sans espaces, ça devrais marcher sams problème.

après, tu peux aussi essayer de lancer la même commande sans les " mais avec des noms de fichier 8.3 que tu obtient par la command dir /x.
:slight_smile:

Je vais tester…

Et ca aussi…

Histoire de voir quel peut etre le probleme.

Bon, apparement, le PATH et les noms en 8.3 ça n’a pas d’influence.

J’ai remarqué un truc bizarre cependant :
Mon application a des JButton (Swing) qui permettent de lancer/fermer des logiciels.
Lorsque je lance Apache avec la commande donnée plus haut, un processus Apache.exe est lancé, voir image ci-dessous :

Cependant, Apache ne marche pas : jusque là, rien de changé.

Si je clique sur le JButton correspondant à la fermeture, c’est la méthode Process.destroy() this.process.destroy() qui est appelée dans mon programme et le processsus Apache.exe se termine, voir image ci-dessous :

Normallement, quand je ferme mon application, j’execute ma fonction de fermeture, la même que lorsque je clique sur le JButton de fermeture. Si par contre, je désactive ce nettoyage lors de la fermeture de mon application, je me suis rendu compte d’un truc bizarre, le deuxième Apache.exe se lance (voir image ci-dessous) et Apache marche :??: http://raynorwebsite.free.fr/_raynor_stuff/forum_stuff/serverslaunchers-probleme_lancement_apache/3-Apache_lanc�_puis_application_ferm�.jpg

Il semble donc, que mon application Java empèche bien le premier processus Apache.exe de lancer le deuxième Apache.exe.

essaie en englobant l’activation dans un thread


//méthode appelé lors de l'appui sur le jbutton
public void doSomething()
{
 new Thread()
 {
   try
       {          
           Runtime.getRuntime().exec("C:\\test.bat",null,new File("C:\\"));      
       }
       catch (Exception ex)
       {
          ex.printStackTrace();            
       }
  }.start();
}


J’y avais vaguement pensé, mais je m’étais dit que lancer un Thread pour ça, ça semblait trop lourd pour être la solution.

Par contre, je ne connaissait pas cette syntaxe :

new UneClasse() {
	// du code
};

(un bloc de code après un constructeur)

C’est la syntaxe des classes anonymes (sans nom, comme moi)

OK, ça évite de se faire une class MyThread qui hérite de Thread.

yes. Sauf qu’en général on fait un Runnable :

new Thread(new Runnable() {}, "Thread Apache").start();

C’est plus léger (au niveau héritage), et moins barbare

Je rencontre un truc assez “strange” (du moins pour moi), dans la méthode appelée lors du clic sur le JButton, j’ai le code suivant :

System.out.println("LoadedServer.startServer() called");
System.out.println("LoadedServer.startServer(): 1. creating a new ServerThread");
ServerThread runner = new ServerThread(this);
System.out.println("LoadedServer.startServer(): 2. starting that new ServerThread");
runner.start();
System.out.println("LoadedServer.startServer(): 3. getting the Process of that new ServerThread");
this.process = runner.getProcess();
System.out.println("LoadedServer.startServer(): 4. Done with the new ServerThread");

Et en première ligne de code de mon constructeur de ServerThread, j’ai :

System.out.println("ServerThread.ServerThread() called");

Et de même pour les méthodes run() et getProcess().

Ce qui est étrange, c’est que l’ordre des appels des fonctions dans le code est (aparement) différent de celui effectué lors de l’éxecution.
Voici la sortie de la console :[quote=""]
LoadedServer.startServer() called
LoadedServer.startServer(): 1. creating a new ServerThread
ServerThread.ServerThread() called
LoadedServer.startServer(): 2. starting that new ServerThread
LoadedServer.startServer(): 3. getting the Process of that new ServerThread
ServerThread.getProcess() called
LoadedServer.startServer(): 4. Done with the new ServerThread
ServerThread.run() called
[/quote]
La méthode ServerThread.run() est appelée après l’appel de getProcess(), alors que ça devrait être l’inverse.

Je n’y comprends rien et je me retrouve avec un problème, parce que la méthode getProcess() est censée retournée le Process résultant de l’exécution de la commande pour lancer le serveur après que celle-ci ait été exécutée (logique), si on l’appelle avant, elle retournera null. Or, ces commandes sont exécutées dans la méthode run() (qu’il faut appeler avant d’appeler getProcess()).
Je peux toujours appeler run() dans le constructeur, mais je ne crois pas que ça soit une bonne idée.

Apparement la machine Java n’interrompt pas une fonction pour lancer le Thread, elle attends que la fonction soit terminée pour faire le start(), ce qui explique cette différence d’ordre.

Pour mon problème de Apache.exe qui se bloque, je crois que j’ai trouvé :

(linuxfr.org : Programmation.java : Lancement d’une jvm depuis un programme Java ?)

J’ai pas encore testé, mais ça semble être la bonne solution :slight_smile: