Développement Java sur le Sharp Zaurus

2002-10-27 - Pierre Métras <pp@alterna.tv>

Nous allons voir dans ce document comment le Sharp Zaurus peut être utilisé pour le développement d’applications Java. Dans l’ordre, nous aborderons:

Le Zaurus possède toutes les capacités pour y développer de petites applications Java et les exécuter. Il ne s’agit pas d’un cours de programmation Java ou Bash et nous supposons que le lecteur possède les bases de ces deux langages. Pour des applications Java plus conséquentes, il est plus confortable d’utiliser une station de travail puis de télécharger sur le Zaurus les classes compilées.

Pour faciliter la lecture et l’expérimentation de cet article, j’ai réuni tous les logiciels et sources nécessaires dans un seul fichier jsearchall.zip disponible sur mon site Web (www.alterna.tv/jsearch/jsearchall.zip).

Java sur le Zaurus

Sharp, qui distribue les Zaurus SL-5000, SL-5500 et A300, a passé un accord avec Insignia Solution Inc (www.insignia.com) pour les diffuser avec l’environnement d’exécution Java Jeode. Jeode comporte une machine virtuelle Java assez performante, que l’on retrouve d’ailleurs sur d’autre PDA comme les iPAQ, ainsi que toutes les librairies définies dans la spécification PersonalJava 1.2, y compris celles déclarées optionnelles. Les applications Java qui fonctionnent sur le Zaurus peuvent donc s’appuyer sur le support de AWT pour l’interface graphique ou sur les couches réseau. En pratique, on retrouve la majorité des classes disponibles dans Java 1.1.8.

En revanche, Jeode ne dispose pas d’un environnement de développement. Le développeur a le choix de développer sur une station de travail, avec son environnement habituel puis de transférer les classes sur le Zaurus; ou bien d’éditer et compiler directement sur le Zaurus, valable pour des petites applications, solution que nous présenterons.

Une application de recherche de textes

La fenêtre de l'application JSearch

Bien qu’aspirant à une part du marché des PDA, le Zaurus ne dispose pas encore de toutes les fonctions bureautiques disponibles sur les autres PDA tels que les iPAQ ou Palm. Nous pouvons espérer que Sharp palliera ces manques dans les prochaines versions de la ROM afin d’attirer plus d’utilisateur vers cette plate-forme. En particulier, le Zaurus ne possède pas d’une fonction de recherche de documents, telle que celle présente sous Windows et à laquelle sont habitués de nombreux consommateurs.

Nous allons donc développer une application JSearch qui nous permettra:

Voici à quoi ressemblera notre application JSearch.

L’environnement de développement Java

MinIDE

Comme nous l’avons précédemment écrit, le Zaurus ne dispose pas d’un environnement de développement. Nous allons donc commencer par installer MinIDE, qui comme sont nom l’indique est un mini-éditeur de texte intégrant la possibilité de lancer une compilation, avec des fonctions d’aide à l’édition comme l’auto-indentation ou l’appairage de parenthèses.

MinIDE a été écris en Java par Dave Taubler et est disponible sur http://www.taubler.com/minide/. À l’heure actuelle (version 1.1), ce package doit être installé en RAM. Malgré sa petite taille (37 Ko), cette limitation peut causer des problèmes aux possesseurs de SL-5000 qui disposent de moins de mémoire, mais la prochaine version devrait corriger cette limitation.

L’utilisation de l’éditeur de textes du Zaurus n’est pas recommandée, pour le développement, pour deux raisons majeures:

Ces deux raisons suffisent à justifier l’installation de MinIDE et bannir l’éditeur de textes de Qtopia (Sharp et Trolltech, faites quelque chose!).

Téléchargez donc ce paquet et installez-le. Vous trouverez son icône dans l’onglet Jeode. Icône de MinIDE

Le terminal Konsole

Bien que tout le développement puisse s’effectuer à l’aide de l’interface graphique Qtopia, il est parfois plus simple d’exécuter les applications depuis la ligne de commande, pour pouvoir bénéficier de l’affichage des messages d’erreur sur stderr.

Vous pouvez installer le Terminal fourni par Sharp, disponible sur MyZaurus.com (http://myzaurus.com/downloads.asp) ou sur le CD d’accompagnement de votre Zaurus. Mais je vous conseille d’installer plutôt le programme Konsole (http://www.killefiz.de/zaurus/showdetail.php?app=385) qui supporte l’ouverture simultanée de plusieurs shells. Donc, on le télécharge et on l’installe sans poser de question. Pour tester l’installation, ouvrez un shell et créez deux répertoires nommés jsearch et kopi dans le répertoire /home/userdata:

# cd /home/userdata
# mkdir jsearch
# mkdir kopi
# ls
jsearch
kopi
...
Testons également que Jeode fonctionne...
# evm -version
Jeode EVM version 1.10.2
  Supported Java Patforms: Personal Java 1.2
  Requires JeodeClass: 1.10.2

Le compilateur KOPI

KOPI est un compilateur optimiseur Java écrit en Java par DMS, disponible sur http://www.dms.at/kopi/. Ce compilateur possède de nombreuses fonctions avancées telles que le support des assertions ou des classes génériques (prévues pour la version 1.5 du compilateur de Sun) pour ceux qui voudraient s’aventurer dans ces nouvelles directions.

Téléchargez le paquet Kopi disponible sur Sourceforge (http://sourceforge.net/projects/zaurus) pour installer la version 1.1 (vous pourrez télécharger la version 2.1B, légèrement plus volumineuse, depuis le site de DMS, si vous désirez bénéficier des fonctions les plus avancées). Transférez ce fichier dans le répertoire /home/userdata/kopi que nous venons de créer et décompressez-le.

Nous allons écrire un script kjc pour invoquer le compilateur. Lancez MinIDE pour inaugurer notre éditeur et saisissez le code shell suivant:

#! /bin/sh
# Run Kopi Java compiler
evm -cp /home/userdata/kopi/kjc-suite.jar at.dms.kjc.Main -C.:/home/userdata/kopi/gclasses.zip $@

Enregistrez le fichier sous le nom /home/userdata/kopi/kjc

Si vous désirez afficher les conseils durant la compilation, ajoutez l’option -w3 à la ligne de commande. Kopi affichera de nombreux messages de compilation.

Le script kjc qui lance le compilateur

Enfin, l’ajout de kjc au PATH. Toujours avec MinIDE, éditez le fichier /home/root/.profile (oui, le nom du fichier commence par un point pour indiquer qu’il n’est généralement pas visible) et ajoutez les lignes suivantes à la fin du fichier:

# Compilateur Java Kopi
PATH=$PATH:/home/userdata/kopi
export PATH

Après sauvegarde, vérifions que tout fonctionne. Depuis le shell de Konsole, affichons la version de Kopi:

# kjc -version
Version 2.1A released 11. February 2002
#

D’autres compilateurs Java tels que Jikes d’IBM sont disponible pour le Zaurus ou même celui de Sun si vous disposez de beaucoup de place. Vous pourrez les trouver sur Sourceforge, ZaurusZone.com ou Killefiz.de.

Intégration de Kopi et MinIDE

Dernière étape de la configuration de notre environnement de développement, transformer notre éditeur MinIDE en véritable IDE (Environnement de Développement Intégré, à lire à l’envers pour le prononcer à l’anglaise), pour lancer les compilations directement depuis l’éditeur. Dans le menu Settings, sélectionnez l’option Compile Command et saisissez la commande suivante:

/home/userdata/kopi/kjc -d/home/userdata/jsearch 

en laissant un espace à la fin (une prochaine version de MinIDE permettra probablement des paramètres substituables, ce qui évitera de saisir des chemins d’accès en dur dans les options de compilation). Le nom du fichier édité sera concaténé à cette commande pour lancer la compilation. Dorénavant, il sera possible de compiler un fichier Java en édition.

Les utilitaires indispensables

Notre environnement de développement ne serait fin prêt sans quelques utilitaires qui deviendront bientôt indispensables. Téléchargez et installez les outils suivants:

Le code Java

Le but n’étant pas de donner un cours sur Java, le code de notre application est brièvement commenté.

L’interface utilisateur

Nous ouvrons une fenêtre qui comprend 3 parties:

Cette division de l’espace correspond parfaitement aux fonctions de positionnement proposées par un BorderLayout.

Nous alignons nos champs de saisie verticalement à l’aide d’un GridLayout, et les boutons se calent à droite à l’aide d’un FlowLayout.

L’usage des layout managers permet de redimensionner la fenêtre tout en conservant un positionnement harmonieux des éléments graphique: la liste des résultats rétrécie ou s’agrandie à la demande.

La recherche des fichiers

Le script de recherche des fichiers: jsearch.sh

Pour les fonctions de recherche des fichiers, nous allons faire appel à des commandes Unix qui sont certainement plus performantes que l’algorithme que nous mettrions en œuvre.

Nous employons ces commandes dans un petit script shell qui accepte deux arguments (suivant la valeur de nos champs de saisie) et qui nous permet de chercher soit par nom de fichier, soit par contenu, ou les deux à la fois. À l’aide de MinIDE, saisissez le code shell suivant et sauvegardez-le sous le nom /home/userdata/jsearch/jsearch.sh

#! /bin/sh
# jsearch.sh: Recherche de fichiers
# $1: nom du fichier
# $2: texte contenu

if [ ’$1’ = ’’ ] && [ ’$2’ = ’’ ] ; then
  echo ’Saisissez un critère de recherche’
elif [ ’$1’ = ’’ ] ; then
  find / -print -type f | xargs grep -H -i -s ’$2’
elif [ ’$2’ = ’’ ] ; then
  find / -name ’$1’ -print -type f
else
  find / -name ’$1’ -print -type f | xargs grep -H -i -s ’$2’
fi

Si aucun argument n’est fourni, on affiche un message.
Si seul le deuxième argument est fourni, on liste tous les fichiers de l’arborescence avec find, puis on y recherche la chaîne avec grep, en pipant le tout avec xargs.
Si seul le premier argument est disponible, on recherche les fichiers ayant ce nom le long de l’arborescence.
Enfin, si les deux arguments sont disponibles, on combine les deux recherches.

Les variables sont placées entre guillemet, ce qui nous permet d’effectuer des recherches sur des noms de fichiers partiels en utilisant les caractères joker * et ?. La recherche dans l’arborescence ne s’effectue que sur les noms de fichiers (option -type f), sans considérer les fichiers spéciaux tels que les liens ou les répertoires.
La recherche des chaînes s’effectue sans tenir compte de la casse (option -i), en préfixant avec le nom du fichier (option -H) et sans afficher de message d’erreur lorsque quelque chose va mal (option -s).

Avant de l’oublier, rendez ce script exécutable afin de pouvoir l’exécuter depuis notre interface Java. Dans la Konsole, changez les permissions:

# chmod a+x jsearch.sh
# ls -al jsearch.sh
-rwxrwxrwx     1   root   root    380 Oct 13 17:36 jsearch.sh

L’affichage des résultats

Nous exécutons le script jsearch.sh en lui passant la valeur des deux champs de saisie, en appelant la méthode exec de la class Runtime. Cet appel crée une instance d’un objet Process, duquel nous récupérons la sortie standard et que nous affichons ligne par ligne dans la liste results.

Comme Jeode n’implémente pas correctement la classe Cursor pour indiquer qu’une opération est en cours, nous désactivons le bouton de recherche au début de l’exécution du script, et nous le réactivons lorsque la recherche est terminée.

Le code

Le code du programme JSearch dans l'éditeur MinIDE

Ce code a été saisi sur mon Zaurus. Le style Java employé (une seule méthode et des classes anonymes) n’aurait probablement pas été utilisé pour une application plus conséquente, mais il m’a permis de programmer et mettre au point cette petite application, qui me dépanne bien, en une matinée.

import java.awt.*;
import java.awt.event.*;
import java.io.*;

/**
 * JSearch propose une interface de recherche de chaînes et de fichiers.
 * On peut saisir un nom de fichier ou une chaîne à rechercher: tous les
 * fichiers correspondant aux critères sont affichés dans une liste.
 *
 * @author Pierre Métras (pp@alterna.tv)- &copy;2002
 */

class JSearch
  extends Frame
{
  /**
   * Construit la fenêtre de recherche.
   * Positionne les éléments graphiques et contrôle les actions de l’utilisateur
   * sur les boutons.
   */
  JSearch()
  {
    // Le titre
    super("JSearch 1.0");
    
    setLayout(new BorderLayout());
    
    // Les champs de saisie en haut
    Panel top = new Panel(new GridLayout(0, 1));
    top.add(new Label("Rechercher les fichiers..."));
    top.add(new Label("... dont le nom contient:"));
    final TextField name = new TextField();
    top.add(name);
    top.add(new Label("... qui contiennent la chaîne:"));
    final TextField text = new TextField();
    top.add(text);
    final Label count = new Label("Résultats");
    top.add(count);
    
    add(top, BorderLayout.NORTH);
    
    // La liste des résultats au centre
    final List results = new List();
    add(results, BorderLayout.CENTER);
    
    // Les boutons d’action au bas de la fenêtre
    Panel bottom = new Panel(new FlowLayout(FlowLayout.RIGHT));
    final Button search = new Button("Rechercher");
    // Que faire lorsque le bouton [Rechercher] est pressé?
    search.addActionListener(new ActionListener()
      {
        public void actionPerformed(final ActionEvent evt)
        {
          // Effacer les résultats précédents et désactiver le bouton
          results.clear();
          search.setEnabled(false);
          
          // Exécuter le script jsearch.sh en redirigeant la sortie
          Process process = null;
          String command = System.getProperty("user.dir") + System.getProperty("file.separator") + "jsearch.sh";
          try
          {
            // Exécute le script en passant les critères de recherche
            String[] commands = {command, name.getText(), text.getText()};
            process = Runtime.getRuntime().exec(commands);
            
            // Rediriger la sortie du process et découper chaque ligne pour
            // l’afficher dans la liste des résultats
            BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = input.readLine()) != null)
            {
              results.add(line);
            }
          }
          catch (Exception e)
          {
            // S’il y a eu une erreur, l’afficher dans les résultats
            results.add(e.toString());
          }
          finally
          {
            // Attendre la fin du process et réactiver le bouton de recherche
            if (process != null)
            {
              try
              {
                process.waitFor();
              }
              catch (InterruptedException ie)
              {
                // On continue quand même
              }
            }
            search.setEnabled(true);
            // Afficher le nombre de résultats trouvés
            count.setText("" + results.getItemCount() + " résultats");
          }
        }
      });
    bottom.add(search);
    
    final Button clear = new Button("Effacer");
    // Que faire lorsque le bouton [Effacer] est pressé?
    clear.addActionListener(new ActionListener()
      {
        public void actionPerformed(final ActionEvent evt)
        {
          // Vider le contenu des champs de saisie et effacer la liste
          // des résultats
          name.setText("");
          text.setText("&rsquot;);
          count.setText("Résultats");
          results.clear();
        }
      });
    bottom.add(clear);
    
    add(bottom, BorderLayout.SOUTH);
    
    // Lorsque la fenêtre est fermée par l’utilisateur, on arrête l’application
    addWindowListener(new WindowAdapter()
      {
        public void windowClosing(final WindowEvent evt)
        {
          System.exit(0);
        }
      });
    
    Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
    setSize(dim);
    validate();
  }
  
  /**
   * La fonction principale de notre application affiche la fenêtre de recherche
   * et attend la saisie de l’utilisateur.
   *
   * @param args Les arguments ne sont pas utilisés
   */
  public static void main(final String[] args)
  {
    Frame jsearch = new JSearch();
    jsearch.show();
  }
}

Compilation

Résultats de compilation de JSearch

La saisie terminée, la compilation est lancée dans MinIDE depuis le menu Tools, dans l’option de menu Compile. Si tout se passe bien, la fenêtre de compilation affiche le message victorieux Successfull.

Sinon, il faut patiemment corriger toutes les erreurs en repérant leur numéro de ligne. L’option de menu Tools/Line #... permet de se rendre à une ligne donnée.

Lorsque la compilation a abouti, vous devriez disposer dans le répertoire jsearch des fichiers suivants:

# pwd
/home/userdata/jsearch
# ls
JSearch$1.class
JSearch$2.class
JSearch$3.class
JSearch.class
JSearch.java
jsearch.sh

Les fichiers JSearch$N.class sont les résultats de compilation des trois classes anonymes:

Tests et debug

Nous voici rendu aux premiers essais. Pour ce faire, le plus simple est d’utiliser le shell pour permettre l’affichage du maximum d’indices.

# evm -cp . JSearch

La fenêtre de l’application s’ouvre.

Essayez différentes recherches. Par exemple, recherchez les fichiers ’*java’ qui contiennent la chaîne ’TextField’. Vous devriez trouver JSearch.java parmi vos réponses.
Ou bien listez tous les fichiers: saisissez ’*’ comme nom de fichier. Après un peu moins d’une minutes, la liste des résultats devrait afficher quelques milliers de lignes (3854 chez moi).

Avant et arrière-plan

Lorsqu’une application Java est lancée depuis la ligne de commande, Qtopia n’affecte pas d’icône dans la barre des applications actives. Si vous placez une autre application en premier plan, vous ne pourrez retourner à cette première.

Pour reprendre la main sur la ligne de commande et tuer notre application invisible, appuyez sur [Fn]+[C] qui émet un ^C (ou sélectionnez la quatrième case blanche dans la liste des caractères Unicode, si vous utilisez le clavier virtuel).

Lorsque ça ne fonctionne pas comme prévu...

C’est normal. Quand ça doit planter, ça plante! Mais le Zaurus ne dispose pas (encore!) d’un debugger.

Vous pouvez adopter plusieurs stratégies pour trouver l’origine du problème. La plus simple est de mettre en œuvre du code d’instrumentation, c’est-à-dire plus prosaïquement d’afficher des traces pour suivre son exécution. Vous pouvez écrire une classe Debug qui disposera de plusieurs méthodes log() pour logger des messages dans un fichier, ou plus simplement ajouter des appels à System.err.println() pour afficher des messages. L’écriture de la classe Debug est bien souvent rentabilisée rapidement au bug ou au projet suivant...

Un autre problème possible est l’envoi d’une exception, par exemple pour l’utilisation d’une référence null. Les machines Java sur les stations de travail affichent dans ce cas un dump de la pile des appels avec les noms des fichiers sources et les numéros de ligne. Par défaut, Jeode n’offre pas autant de souplesse et l’on devra se contenter du numéro d’instruction de la machine virtuelle.

# evm -cp . JSearch
Exception in thread ’main’, java.lang.NullPointerException
	at java.awt.Container.addImpl (bytecode 95)
	at java.awt.Container.add (bytecode 4)
	at JSearch.<init> (bytecode 110)
	at JSearch.mian (bytecode 4)
#
Mais tout n’est pas perdu pour autant car l’option -Xlinenum utilisée au lancement active l’affichage des numéros de ligne.

# evm -cp . -Xlinenum JSearch
Exception in thread ’main’, java.lang.NullPointerException
	at java.awt.Container.addImpl (bytecode 95)
	at java.awt.Container.add (bytecode 4)
	at JSearch.<init> (JSearch.java, line 38)
	at JSearch.mian (JSearch.java, line 143)

Mon erreur se trouve donc à la ligne 38! Pour les besoins de l’exemple, j’avais initialisé à null la variable count.
Merci à Steph Meslin-Weber qui m’a révélé l’existence de cette option de la JVM. Ma procédure originale, qui nécessitait le désassemblage du code Java, était bien plus compliquée à mettre en œuvre...

Parfois, l’exception ne surgit pas lors du lancement, mais lorsque l’utilisateur effectue certaines opérations, sans toutefois provoquer l’arrêt de l’application. En lançant l’application depuis la Konsole, l’exception s’affiche sur la sortie d’erreur standard, ce qui permet de la repérer.

On empaquète le tout

Maintenant que notre application fonctionne, nous allons la packager pour faciliter sa diffusion. Le Zaurus utilise un format de paquet similaire à ceux de Debian, mais adapté aux ressources limitées des PDA. La création d’un paquet est une opération simple, du moment que l’on respecte scrupuleusement les règles et que l’on ne cherche pas à innover (http://adorphuye.com/zaurus/java/faq.jsp?section=Packaging&subsection=Packaging).

L’arborescence des fichiers

Dans le répertoire jsearch, créez un nouveau répertoire jsearch contenant l’arborescence suivante:

Fichier de contrôle

Le fichier de contrôle décrit l’application dans le paquet (http://www.zauruszone.farplanet.net/howtos/ipkg_howto.shtml). Ce fichier est utilisé par l’installateur. Saisissez le contenu du fichier de contrôle et enregistrez-le sous le nom control dans le répertoire CONTROL.

Package: jsearch
Priority: optional
Section: Utilities
Version: 1.0
Architecture: arm
Maintainer: Pierre Metras
Depends:
Description: JSearch - Recherche de texte et fichiers
 JSearch offre des fonctions de recherche de texte ou
 de fichiers, en affichant les resultats dans une liste.
 .
 Necessite une machine virtuelle Java (par ex. Jeode)

Dans la description, laissez un espace en début de ligne si vous devez saisir le texte sur plusieurs lignes. Vous ne pouvez laisser de ligne vide: on a l’habitude de saisir un point ’.’ pour marquer un saut de ligne.

Fichier Jar

Notre environnement de développement sur le Zaurus ne dispose pas d’une commande jar pour créer une archive Java (http://java.sun.com/docs/books/tutorial/jar/basics/). Mais nous allons nous en passer en créant nous-même le fichier jar, qui n’est en fait qu’un fichier zip contenant les classes java.

Créez le répertoire META-INF et placez-y le fichier MANIFEST.MF que vous créez avec le contenu suivant:

Manifest-Version: 1.0
Created-By: 1.0 (alterna)

Il ne nous reste plus qu’à zipper nos classes avec ce fichier, et de renommer le tout pour faire plus joli. Et voici une archive jar!

# zip jsearch.zip META-INF/* JSearch*class
  adding: META-INF/MANIFEST.MF (deflated 2%)
  adding: JSearch$1.class (deflated 45%)
  adding: JSearch$2.class (deflated 44%)
  adding: JSearch$3.class (deflated 35%)
  adding: JSearch.class (deflated 44%)
# mv jsearch.zip jsearch.jar

En fait, si vous utilisez les classes classes.zip (8 Mo!) Java du JDK 1.1 plutôt que celles fournies dans Kopi (gclasses.zip), vous pouvez exécuter la commande jar en utilisant la syntaxe:

evm -cp classes.zip sun.tools.jar.Main cf jsearch.jar JSearch*class

Fichier de configuration Qtopia

Qtopia nécessite un fichier de configuration pour connaître les caractéristiques de notre application (http://www.freedesktop.org/standards/desktop-entry-spec/desktop-entry-spec.html). Créez le fichier jsearch.desktop avec le contenu ci-dessous et placez-le dans le répertoire jsearch/opt/QtPalmtop/apps/Applications. L’icône du programme sera donc visible dans l’onglet Applications. Placez-le dans le répertoire jsearch/opt/QtPalmtop/apps/Jeode si vous préférez regrouper toutes vos applications Java dans l’onglet Jeode, mais pour l’utilisateur final, je pense qu’il n’y a pas de raison de distinguer le langage utilisé pour programmer une application.

[Desktop Entry]
Name=JSearch
Comment=Recherche de texte et de fichier
Exec=runjsearch
Icon=jsearch.png
Type=Application

Icône

Notre application nécessite un icône. Créez une image de 32x32 pixels, en 24bpp pour le nombre de couleurs, que vous sauvegarderez au format PNG. Par convention, l’icône possède une marge haute et gauche de 2 pixels, et une marge de 3 pixels à droite et en bas qui contient un ombrage. Placez le fichier sous le nom jsearch.png dans le répertoire jsearch/opt/QtPalmtop/pics.

Pour créer l’image, vous pouvez télécharger et utiliser IconEdit (http://www.killefiz.de/zaurus/showdetail.php?app=379) ou bien employer l’icône que j’ai réalisé. L’iône JSearch

Aide en ligne

L'aide en ligne de JSearch

Si vous désirez ajouter une aide en ligne, pour finaliser et rendre plus professionnelle notre application, créez un fichier runjsearch.htmlcode> que vous placerez dans le répertoire jsearch/opt/QtPalmtop/help/en/html. Si l’aide est en français, elle devrait être placée dans le répertoire help/fr/html, mais comme il n’existe pas de version officielle française du Zaurus, nous laisserons l’aide en anglais. Vous pouvez également créer un sous-répertoire img pour y placer d’éventuelles images.

Lorsque Qtopia détecte la présence d’un fichier d’aide correspondant à l’application en cours d’exécution, il ajoute automatiquement l’icône (?) dans la barre de titre de la fenêtre principale de celle-ci. Vous pouvez en conclure que notre application s’appellera runjsearch (pour ceux qui ne l’auraient pas deviné du contenu du fichier de configuration Qtopia), pour suivre une convention utilisée par toutes les applications Java sur le Zaurus...

Pour les besoins de l’exemple, nous utiliserons le code suivant comme contenu de notre fichier jsearch/opt/QtPalmtop/help/en/html/runjsearch.html:

<html>
  <head>
    <title>JSearch - v1.0</title>
  </head>
  <body>
    <h1>JSearch</h1>
    JSearch vous permet de rechercher des fichiers sur votre Zaurus:
    <ul>
      <li>Par nom de fichier. * et ? sont des caract&egrave;res joker.
      <li>Par texte contenu. La recherche ne tient pas compte de la casse.
    </ul>
  </body>
</html>

Script de démarrage

Comme explicité précédemment, nous allons enfin écrire le script de démarrage runjsearch qui lancera notre application. Ce script a plusieurs objectifs:

#! /bin/sh
#
# Demarre Jsearch
#

# Se placer dans le repertoire d’installation
cd $PKG_ROOT/opt/QtPalmtop/java

# Creer le CLASSPATH
CLASSPATH=./jsearch.jar

# Demarrer la JVM et l’application
evm -cp $CLASSPATH -XappName=runjsearch Jsearch

Saisissez ce fichier et enregistrez-le sous le nom runjsearch dans jsearch/opt/QtPalmtop/bin. Rendez-le exécutable avec un chmod a+x runjsearch.

Construction du paquet

Nous construirons notre paquet en utilisant le script ipkg-build qui vérifie les composants puis assemble le paquet.

Adaptation de ipkg-build

ipkg-build a été écrit pour fonctionner sur un système linux complet. Mais certaines commandes du Zaurus sont substituées par des équivalents BusyBox (http://www.busybox.net/) pour économiser l’espace mémoire en ROM. Le script ipkg-build utilise les deux commandes find et tar avec des options qui ne sont pas supportées par leur version BusyBox. Nous devons donc l’adapter pour le rendre utilisable sur le Zaurus.

Le script modifié est disponible sur mon site Web: http://www.alterna.tv/jsearch/ipkg-build.

Commentez les lignes 32 à 38, pour désactiver la vérification du propriétaire des fichiers. Comme sur le Zaurus, l’utilisateur par défaut est root, cette opération ne porte pas à conséquence.

#	large_uid_files=`find . -uid +99`
#	if [ -n ’$large_uid_files’ ]; then
#		echo ’*** Warning: The following files have a UID greater than 99.
#You probably want to chown these to a system user: ’ >&2
#		ls -ld $large_uid_files
#		echo >&2
#	fi

Ensuite, remplacez les lignes 150 à 164 (fin du fichier) par le texte ci-dessous qui substitue les options tar -cfz par la combinaison de tar et gzip.

tmp_dir=/tmp/IPKG_BUILD.$$
mkdir $tmp_dir

tar -C $pkg_dir -cf $tmp_dir/data.tar . --exclude=$CONTROL
gzip -9  $tmp_dir/data.tar
tar -C $pkg_dir/$CONTROL -cf $tmp_dir/control.tar .
gzip -9  $tmp_dir/control.tar

echo ’2.0’ > $tmp_dir/debian-binary

pkg_file=${pkg}_${version}_${arch}.ipk
tar -C $tmp_dir -cf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz
gzip -9 $tmp_dir/$pkg_file
mv $tmp_dir/$pkg_file.gz $dest_dir/$pkg_file

rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
rmdir $tmp_dir

echo ’Packaged contents of $pkg_dir into $pkg_file’

Création du paquet avec ipkg-build

La création du paquet avec ipkg-build

Toutes les pièces du puzzle sont en place, il ne reste que la dernière étape qui va créer le paquet. Vous devez disposer maintenant des fichiers suivants:

Depuis notre répertoire /home/userdata/jsearch, exécutez la commande ipkg-build en spécifiant le nom du répertoire qui contient notre application:

# ./ipkg-build jsearch

Ce script vérifie sommairement que tous les constituants sont présents et corrects. Si vous n’avez pas fait d’erreur, vous devriez découvrir le fichier jsearch_1.0_arm.ipk, résultat de notre longue quête.

La dernière étape...

Nous approchons de la fin. Avant de faire fortune, vous devrez vous assurer:

Et comme votre application Java est portable sur d’autres plates-formes, vous pouvez ensuite envisager de la diffuser sur PocketPC, téléphone Java sous Epoc ou autres...

Conclusions

Nous avons vu que le Zaurus est autonome et dispose de tous les outils nécessaires pour développer des applications Java graphiques qui s’intègrent et complètent les applications natives disponibles. Sa petite taille ne doit pas décourager les développeurs qui veulent diffuser un logiciel ou les étudiants qui apprennent Java ou linux.

Pour améliorer l’application...

L’application JSearch était un prétexte à la découverte de l’environnement de programmation Java du Zaurus. À vous maintenant de pratiquer pour l’améliorer et la rendre réellement utilisable, par exemple en limitant la recherche à certains répertoires ou en ouvrant le fichier lorsque l’utilisateur sélectionne un élément de la liste. Une extension simple et pratique consiste à copier dans le presse-papier l’élément sélectionné dans la liste: on peut ainsi le récupérer dans une autre application.

Bons développements.

Si vous désirez plus d’explications, vous pouvez me contacter à l’adresse pp@alterna.tv.


Fichiers

Versions