Cet article est paru dans le magazine francophone consacré à Linux et aux logiciels libres n°41 (juillet 2002). ![]() Editions Diamond |
Cette série a pour but de montrer la possibilité de construire un environnement utilisateur entièrement en Java/Swing au dessus de Linux et XFree. Ce troisième article s'intéresse à l'appel de programmes externes.
Le système GNU/Linux dispose d'une quantité impressionnante de logiciels, souvent disponibles dès l'installation. Une bonne partie de ceux-ci se présente comme des outils en ligne de commande, d'autres ont separé leur traitement dans une bibliothèque utilisable séparement. L'objectif est de montrer comment utiliser cette mine inépuisable de pépites directement dans notre bureau.
Les explications suivantes s'appliquent à la version 0.21 de JDistro. L'utilisation d'un logiciel, qu'il soit natif ou non, se fait par la création d'une entité le représentant. Sélectionnez "Créer une entité", choisissez le type "Application" pour un exécutable natif, entrez le chemin du binaire et éventuellement le chemin vers une icône (gif, jpg ou png). Vous pouvez saisir d'éventuels arguments dans le second onglet. (désolé, tout n'a pas encore été traduit)
L'entité sera accessible à la fois sur le bureau et dans le panneau. Pour lancer le logiciel, il suffit de double-cliquer dessus.
Le but étant d'avoir un bureau pur java, l'exemple de la calculatrice n'était pas des plus probants. La MVJ dispose de capacités multimedia intéressantes (audio et video grâce à JMF, le Java Media Framework) mais qui ne sont pas encore très pratiques à mettre en oeuvre et qui sont assez consommatrices en cycles processeur. D'autre part, j'aime bien XMMS et celui-ci, en plus de son interface graphique, dispose d'un mode en ligne de commande xmms-shell
.
Le but du script est de simplifier l'usage de XMMS en permettant le passage d'une liste de fichiers ou d'un répertoire dans lequel les fichiers musicaux seront recherchés.
#!/bin/sh # Lancement de XMMS /usr/bin/xmms& sleep 1 # Construction de la commande s="window all hide;clear;" if [ -n "$*" ]; then for f in $* do if [ -d "$f" ]; then for p in `find "$f" -follow | \ egrep ".*\.(ogg|mp3|wav)" ` do s="${s}load $p;" done else if [ `basename "$f" .m3u` == `basename "$f"` ]; then s="${s}load $f;" else for p in `cat "$f"` do s="${s}load $p;" done fi fi done s="${s}play;" fi s="${s}quit;" # Déverminage echo "$s">$HOME/xmms-bridge.tmp # Envoi de la commande echo "$s" | /usr/bin/xmms-shell \ 2>&1 >$HOME/xmms-bridge.err
Pour utiliser XMMS, il suffit alors de créer l'entité représentant le script. Ceci fait, vous pouvez ouvrir l'explorateur et faire glisser des fichiers audio vers l'entité pour les écouter. D'autre part, le quatrième onglet ("Features") sert à indiquer les (mime) types gérés, comme par exemple audio/*. Ceci permet d'afficher les actions appropriées dans l'aperçu et jouer un morceau en double-cliquant dessus.
La MVJ propose principalement deux classes pour gérer les processus externes: Runtime
et Process
. La première dispose d'une méthode exec(String[] _params)
où _params
est un tableau de chaînes de caractères dont le premier élément est le chemin de l'exécutable et les suivants les arguments de la ligne de commande. Cette méthode lance l'exécutable et renvoie une instance de Process
représentant le processus en cours. Voici un exemple d'utilisation:
String[] parametres=new String[] { "/usr/bin/xmms", "le-dernier-tube-de-metal.ogg" }; Process processus=Runtime. getRuntime().exec(parametres); // Attendre la fin processus.waitFor();
La classe Process
permet notamment de récupérer les flux standards. On peut les utiliser pour interagir avec le processus. Notre script peut alors être réécrit en Java.
import java.io.*; public class Xmms { public static void main(String[] _args) throws Exception { Process p=Runtime.getRuntime() .exec("xmms-shell"); PrintWriter out=new PrintWriter (p.getOutputStream()); int l=_args.length; for(int i=0;i<l;i++) out.println("load "+_args[i]); out.println("play"); out.println("quit"); out.close(); p.waitFor(); } }
Je vous laisse le soin d'implanter la gestion des répertoires. Ce n'est pas très difficile vu les facilités offertes par la classe File
et en particulier les méthodes boolean isDirectory()
et File[] listFiles(FileFilter _filter)
. Il faut juste une goutte de récursivité pour avoir le même comportement que find. De la même manière, on peut récupérer des informations en lisant la sortie du processus.
BufferedReader in=new BufferedReader (new InputStreamReader(p.getInputStream())); // Skip the prompt int c=0; while((c=in.read())!=' ') ; out.println("status"); out.flush(); String s=in.readLine(); s=s.substring(s.indexOf(':')+2,s.indexOf('(')-1); System.out.println("Le morceau en cours est "+s+"."); in.close();
La communication avec le processus externe peut se faire aussi par d'autres moyens. Une possibilité est d'utiliser des sockets (ce qui est très similaire à la méthode exposée vu qu'une socket possède un flux d'entrée et un flux de sortie). Une autre est d'utiliser JNI (Java Native Interface) qui permet de charger une bibliothèque dynamique (.so) dans l'espace mémoire de la MVJ. Elle présente l'avantage de donner accès à l'ensemble des fonctions C, au détriment toutefois de la robustesse et de la portabilité. D'autres possibilités, plus lourdes, résident dans l'utilisation de DCOP, CORBA, XML-RPC ou encore SOAP.
RÉFÉRENCES