TP1. Outils Java 1 Préambule - Page enseignement de Sébastien

publicité
c sep. 2008 , v2.2
Java
TP1. Outils Java
Sébastien Jean
Le but de ce TP, sur une séance, est de se familiariser avec les outils de développement et de documentation Java fournis par Sun sous le nom de J2SE SDK.
1
Préambule
1.1
Rappels sur les variables d’environnement
Les variables d’environnement sont utilisées par le système sous-jacent (Windows, DOS, Linux) pour
obtenir des informations sur des chemins d’accès, . . . Certaines variables d’environnement sont déjà définies (par exemple, la variable d’environnement PATH contenant la liste des répertoires dans lesquels le
shell recherche l’existence de fichiers lorsqu’on lui demande l’exécution d’une commande qu’il ne connaît
pas). D’autres peuvent être définies par l’utilisateur lorsqu’il le souhaite. Une variable d’environnement
est caractérisée par son nom, sa valeur (une chaîne de caractères) et dans certains cas son accessibilité
(publique/privée).
1.1.1
Syntaxe Linux
• Pour définir une variable d’environnement privée de nom var et de valeur val, il suffit de taper
dans une console shell var=val,
• Pour que cette variable d’environnement devienne publique (c’est à dire qu’elle soit connue de tous
les processus issus de ce shell), il suffit de taper dans la même console export var,
• La valeur de cette variable peut ensuite être désignée et utilisée via $var,
• Le contenu de cette variable peut également être visualisé avec echo $var,
• Enfin, pour supprimer la définition de cette variable, il suffit de taper (toujours dans la console)
unset var.
1.1.2
Syntaxe DOS/Windows
• Pour définir une variable d’environnement publique (il n’est pas possible de créer de variable d’environnement privée en DOS) de nom var et de valeur val, il suffit de taper dans une console DOS
SET var=val,
• La valeur de cette variable peut ensuite être désignée et utilisée via %var%,
• Le contenu de cette variable peut également être visualisé avec echo %var%,
• Enfin, pour supprimer la définition de cette variable, il suffit de taper (toujours dans la console)
SET var= .
1.2
Avant toute chose. . .
Dans votre répertoire de travail, créez un répertoire manip1 et éditez-y le fichier HelloWorld.java
dont le contenu sera le suivant :
public class HelloWorld
{
public static void main (String[] args)
{
System.out.println("Hello world");
}
}
1
L’éditeur utilisé est quelconque : emacs, vi, jgrasp, kedit, . . .Certains éditeurs ont la faculté de colorer
la syntaxe et ainsi de donner la possibilité au rédacteur de se rendre compte plus rapidement d’éventuelles
erreurs dans l’écriture de mots-clés du langage,. . .
Cette application java est quasiment la plus simple qu’il soit possible d’écrire. Elle consiste à afficher
le message « Hello world » sur la console. Les différentes constructions de langage sont résumées dans
le document d’accompagnement intitulé « Eléments de syntaxe ». Au cours de ce TP, nous ne nous
intéresserons qu’à la compilation, l’exécution, l’archivage et la documentation d’applications.
2
Manipulations
2.1
Compilation, utilisation basique de javac
Comme tout programme source de type non script, notre application Java nécessite d’être compilée
pour pouvoir être exécutée ultérieurement. Cette opération s’effectue à l’aide de la commande javac.
– En vous plaçant dans le répertoire où le fichier est édité, exécutez la commande javac sans paramètre
pour obtenir l’aide en ligne.
– Compilez ensuite la classe HelloWorld et vérifiez qu’un fichier .class a bien été produit dans le
même répertoire.
– Exécutez la même commande avec l’option -verbose et observez les informations générées durant
le processus de compilation. Ces informations vous en apprendront plus sur la manière dont se
déroule la compilation.
– Recompilez la classe, en vous plaçant cette fois-ci dans le répertoire parent, et visualisez l’endroit
où le fichier .class a été produit.
– Créez maintenant deux sous-répertoires de manip1 que vous appellerez src et build. Placez le
fichier HelloWorld.java dans le premier et, en utilisant l’option -d de javac, faites en sorte que
le fichier .class soit produit dans le second.
2.2
Comprendre l’utilisation de la variable d’environnement CLASSPATH
Préambule
La variable d’environnement CLASSPATH est utilisée de manière différente au moment de la compilation
(par le compilateur donc) et au moment de l’exécution (par la machine virtuelle).
Le processus de compilation conduit (en cas de réussite) à la génération d’un fichier .class contenant
le code interprétable de la classe spécifiée en entrée. Lorsque le compilateur détecte une instruction où
l’utilisation d’une autre classe est faite (appel de méthode, accès à un attribut), il tente de se procurer le
fichier .class associé à cette classe afin de vérifier simplement que la-dite classe est correctement utilisée
(i.e. l’attribut ou la méthode existent, sont visibles, . . .). Le compilateur sait implicitement localiser ces
fichiers pour les classes des bibliothèques fournies avec le SDK (par exemple la classe System). Pour
les autres, et notamment celles écrites par les développeurs tiers, il utilise le contenu de la variable
d’environnement CLASSPATH (qu’il est donc utile de bien initialiser et de rendre publique). La valeur de
cette variable est une suite de chemins de recherche séparés par : (convention Linux) ou ; (convention
DOS/Windows). L’ordre des chemins dans cette variable est important, le compilateur cessant de chercher
lorsqu’il a trouvé un chemin le conduisant au fichier souhaité. Lorsque cette variable n’est pas définie, il
est considéré par défaut que la recherche s’effectue uniquement dans le répertoire courant.
Lors de l’exécution d’une application, les classes sont chargées au fur et à mesure de leur première
utilisation, en commençant par celle contenant le main. La machine virtuelle a donc besoin, comme le
compilateur, d’obtenir les fichiers .class correspondant aux différentes classes. La variable d’environnement CLASSPATH est alors utilisée à cette fin, de la même manière. Il est cependant important d’avoir à
l’esprit que le fichier .class utilisé par la machine virtuelle n’est pas forcément celui ayant été utilisé par
le compilateur. Si le contenu de ces deux fichiers n’est pas identique, il peut survenir des erreurs lors de
l’exécution.
Manipulations
– Créez, au même niveau que le répertoire manip1, un répertoire manip2 et éditez-y un fichier nommé
TestHello.java dont le contenu est le suivant :
2
public class TestHello
{
public static void main (String[] args)
{
Hello h = new Hello();
h.print();
}
}
– Créez ensuite deux sous-répertoires de manip2 nommés hello1 et hello2 et éditez-y deux fichiers
Hello.java dont le contenu ressemble au suivant (en veillant cependant à différencier le message
affiché) :
public class Hello
{
public void print()
{
System.out.println("un message au choix");
}
}
L’application est maintenant décomposée en deux parties :
• un programme principal TestHello.java, exécutable via la commande java TestHello 1
• une classe Hello fournissant une méthode print qui affiche un message sur la console comme
précédemment.
– Compilez les deux fichiers source Hello.java en faisant en sorte que chaque fichier produit soit
dans le même répertoire que son fichier source.
– Compilez maintenant le fichier TestHello.java et justifiez l’erreur survenue.
– Résolvez le problème en positionnant correctement la variable d’environnement CLASSPATH 2 .
– Essayez de montrer que même si c’est la classe du répertoire hello1 qui a été utilisée lors de
la compilation, le fait d’utiliser la classe du répertoire hello2 à l’exécution n’introduit pas de
dysfonctionnement (i.e. le message affiché est celui de la classe du répertoire hello2).
– Changez le nom de la méthode print de la classe du répertoire hello2, et recompilez l’application
en utilisant la classe du répertoire hello1. Montrez que l’exécution de l’application, en utilisant la
classe du répertoire hello2, conduit à une erreur.
2.3
Archivage
Il est dans certains cas utile (notamment lorsque l’on transmet l’application via le réseau) de regrouper
au sein d’une archive l’ensemble de classes d’une application ou d’une librairie. Une telle archive a en
Java un format normalisé et se dénomme un jar. Un outil éponyme permet d’archiver des classes.
– A l’aide de cet outil (dont l’aide en ligne s’obtient avec l’option –help 3 ), créez une archive dénommée
TestHello.jar et contenant le fichier TestHello.class ainsi qu’un des fichiers Hello.class au
choix. La syntaxe de la commande de création d’archive est la suivante : jar -cvf [nom du jar
à créer] [fichiers à inclure]. Les fichiers à inclure sont désignés par leur nom uniquement.
Il est possible d’utiliser des jokers (par exemple A*.class) ou d’indiquer un nom de répertoire
(ce qui aura pour effet d’inclure tous les fichiers du répertoire, en conservant la structure dans
l’archive). L’outil jar considère comme répertoire de base celui à partir duquel il est exécuté, si
l’on souhaite inclure des fichiers situés dans un autre répertoire, il faut spécifier avant leur nom le
chemin conduisant au répertoire avec l’option -C.
– Placez l’archive dans un nouveau sous-répertoire nommé manip3.
Lorsque les fichiers .class sont archivés, il faut que la variable CLASSPATH contienne non pas le
répertoire contenant l’archive jar mais le chemin désignant l’archive elle-même (il en est de même lorsque
1. La commande java lance la machine virtuelle, et prend en paramètre uniquement le nom d’une classe (sans le .class)
censée définir un main.
2. Sous linux, pensez à exporter la variable après l’avoir définie. Il est encore plus simple d’effectuer les 2 opérations d’un
coup en écrivant export CLASSPATH=...
3. ou dans la documentation en ligne du SDK dont l’URL vous a été également fournie en début de séance.
3
les classes sont archivées dans un zip, l’environnement Java supportant aussi ce format d’archive non
standard).
– Positionnez donc correctement la variable CLASSPATH (elle ne doit contenir que l’archive jar), puis
vérifiez que l’exécution de l’application TestHello ne génère pas d’erreur.
Il est également possible d’exécuter directement une application contenue dans une archive jar avec
l’option -jar de l’outil java. Pour ce faire, il faut cependant avoir ajouté à l’archive un fichier de métadonnées que l’on appelle manifest indiquant quelle est la classe de l’archive contenant le main.
– Pour ce faire, éditez un fichier manifest contenant uniquement la ligne Main-Class: TestHello
(attention, la ligne doit se terminer par un saut de ligne).
– Recréez l’archive en incluant le manifest avec l’option -m.
– Syntaxe : jar -cvmf [manifest] [jar] [fichiers]
– Exécutez directement la classe TestHello avec l’option -jar de java. On remarquera qu’il n’est
plus utile de positionner la variable CLASSPATH dans la mesure où la machine virtuelle prend en
entrée l’archive complète.
2.4
Documentation
Le SDK fournit un outil de génération de documentation (avec pour cible privilégiée le langage HTML)
nommé javadoc et basé sur l’utilisation de balises (tags) dans le code source. Vous pouvez consulter la
partie de la documentation en ligne traitant de cette outil afin de vous familiariser avec les balises et
les paramètres de la ligne de commande. La finalité de cet outil est de fournir une documentation pour
chaque classe, détaillant notamment la signification des attributs, des méthodes, des paramètres et valeurs
de retour.
Les commentaires JavaDoc s’insèrent toujours avant ce qu’ils sont censés décrire, et peuvent mélanger
du texte qui sera inséré tel quel dans la documentation et des balises interprétées par l’outil.
Il est par exemple possible, en utilisant cette syntaxe, de préciser à quoi sert la classe, qui en est
l’auteur et quel est le numéro de version :
/**
* La classe Lampe ...
* @author S.Jean
* @version 1.0
*/
public class Lampe {...}
Il est aussi possible de préciser à quoi sert un attribut :
/**
* La puissance de la lampe
*/
public int puissance;
Il est également possible de préciser à quoi sert une méthode (ou un constructeur) :
/**
* Constructeur avec paramètre.
* @param p La puissance de la lampe.
*/
public Lampe(int p) {...}
/**
* Obtention de la puissance de la lampe.
* @return la puissance de la lampe.
*/
public int getPuissance() {...}
– Expérimentez l’utilisation de l’outil javadoc sur la classe Lampe du cours à laquelle vous ajouterez une méthode isAllumee permettant de savoir si la lampe est allumée ou non. Vous pourrez
également observer dans quelle mesure du code HTML peut être inséré dans les commentaires, et
générer une documentation incluant ou non les descriptions des attributs et méthodes privés.
4
Téléchargement