• Aucun résultat trouvé

F - Les paquetages

Dans le document Télécharger cours Java en pdf (Page 63-70)

II - Classes et interfaces II-A - L' objet par l'exemple

II- F - Les paquetages

II-F-1 - Créer des classes dans un paquetage

Pour écrire une ligne à l'écran, nous utilisons l'instruction

System.out.println(...)

Si nous regardons la définition de la classe System nous découvrons qu'elle s'appelle en fait java.lang.System :

Vérifions le sur un exemple :

public class test1{

public static void main(String[] args){ java.lang.System.out.println("Coucou"); }//main

}//classe

Compilons et exécutons ce programme :

E:\data\serge\JAVA\classes\paquetages>javac test1.java E:\data\serge\JAVA\classes\paquetages>dir 06/06/2002 15:40 127 test1.java 06/06/2002 15:40 410 test1.class E:\data\serge\JAVA\classes\paquetages>java test1 Coucou

Pourquoi donc pouvons-nous écrire System.out.println("Coucou");

au lieu de

java.lang.System.out.println("Coucou");

Parce que de façon implicite, il y a pour tout programme Java, une importation systématique du "paquetage" java.lang. Ainsi tout se passe comme si on avait au début de tout programme l'instruction :

Que signifie cette instruction ? Elle donne accès à toutes les classes du paquetage java.lang. Le compilateur y trouvera le fichier System.class définissant la classe System. On ne sait pas encore où le compilateur trouvera le paquetage java.lang ni à quoi un paquetage ressemble. Nous y reviendrons. Pour créer une classe dans un paquetage, on écrit :

package paquetage;

// définition de la classe ...

Pour l'exemple, créons dans un paquetage notre classe personne étudiée précédemment. Nous choisirons istia.st comme nom de paquetage. La classe personne devient :

// nom du paquetage dans lequel sera créé la classe personne

package istia.st; // classe personne

public class personne{ // nom, prénom, âge private String prenom; private String nom; private int age;

// constructeur 1

public personne(String P, String N, int age){ this.prenom=P; this.nom=N; this.age=age; } // toString

public String toString(){

return "personne("+prenom+","+nom+","+age+")"; }

}//classe

Cette classe est compilée puis placée dans un répertoire istia\st du répertoire courant. Pourquoi istia\st ? Parce que le paquetage s'appelle istia.st.

E:\data\serge\JAVA\classes\paquetages\personne>dir 06/06/2002 16:28 467 personne.java 06/06/2002 16:04 <DIR> istia E:\data\serge\JAVA\classes\paquetages\personne>dir istia 06/06/2002 16:04 <DIR> st E:\data\serge\JAVA\classes\paquetages\personne>dir istia\st 06/06/2002 16:28 675 personne.class

Maintenant utilisons la classe personne dans une première classe de test :

public class test{

public static void main(String[] args){

istia.st.personne p1=new istia.st.personne("Jean","Dupont",20); System.out.println("p1="+p1);

}//main }//classe test

On remarquera que la classe personne est maintenant préfixée du nom de son paquetage istia.st. Où le compilateur trouvera-t-il la classe istia.st.personne ? Le compilateur cherche les classes dont il a besoin dans une liste prédéfinie de répertoires et dans une arborescence partant du répertoire courant. Ici, il cherchera la classe istia.st.personne dans un fichier istia\st\personne.class. C'est pourquoi nous avons mis le fichier personne.class dans le répertoire

istia\st. Compilons puis exécutons le programme de test :

E:\data\serge\JAVA\classes\paquetages\personne>dir 06/06/2002 16:28 467 personne.java

06/06/2002 16:06 246 test.java 06/06/2002 16:04 <DIR> istia 06/06/2002 16:06 738 test.class E:\data\serge\JAVA\classes\paquetages\personne>java test p1=personne(Jean,Dupont,20)

Pour éviter d'écrire

istia.st.personne p1=new istia.st.personne("Jean","Dupont",20);

on peut importer la classe istia.st.personne avec une clause import :

import istia.st.personne;

Nous pouvons alors écrire

personne p1=new personne("Jean","Dupont",20);

et le compilateur traduira par

istia.st.personne p1=new istia.st.personne("Jean","Dupont",20);

Le programme de test devient alors le suivant : // espaces de noms importés

import istia.st.personne;

public class test2{

public static void main(String[] args){

personne p1=new personne("Jean","Dupont",20); System.out.println("p1="+p1);

}//main }//classe test2

Compilons et exécutons ce nouveau programme :

E:\data\serge\JAVA\classes\paquetages\personne>javac test2.java E:\data\serge\JAVA\classes\paquetages\personne>dir 06/06/2002 16:28 467 personne.java 06/06/2002 16:06 246 test.java 06/06/2002 16:04 <DIR> istia 06/06/2002 16:06 738 test.class 06/06/2002 16:47 236 test2.java 06/06/2002 16:50 740 test2.class E:\data\serge\JAVA\classes\paquetages\personne>java test2 p1=personne(Jean,Dupont,20)

Nous avons mis le paquetage istia.st dans le répertoire courant. Ce n'est pas obligatoire. Mettons-le dans un dossier appelé mesClasses toujours dans le répertoire courant. Rappelons que les classes du paquetage istia.st sont placées dans un dossier istia\st. L'arborescence du répertoire courant est la suivante :

E:\data\serge\JAVA\classes\paquetages\personne>dir 06/06/2002 16:28 467 personne.java 06/06/2002 16:06 246 test.java 06/06/2002 16:06 738 test.class 06/06/2002 16:47 236 test2.java 06/06/2002 16:50 740 test2.class 06/06/2002 16:21 <DIR> mesClasses E:\data\serge\JAVA\classes\paquetages\personne>dir mesClasses

06/06/2002 16:22 <DIR> istia E:\data\serge\JAVA\classes\paquetages\personne>dir mesClasses\istia 06/06/2002 16:22 <DIR> st E:\data\serge\JAVA\classes\paquetages\personne>dir mesClasses\istia\st 06/06/2002 16:01 1 153 personne.class

Maintenant compilons de nouveau le programme test2.java :

E:\data\serge\JAVA\classes\paquetages\personne>javac test2.java test2.java:2: package istia.st does not exist

import istia.st.personne;

Le compilateur ne trouve plus le paquetage istia.st depuis qu'on l'a déplacé. Remarquons qu'il le cherche à cause de l'instruction import. Par défaut, il le cherche à partir du répertoire courant dans un dossier appelé istia\st qui n'existe plus. Examinons les options du compilateur :

E:\data\serge\JAVA\classes\paquetages\personne>javac Usage: javac <options> <source files>

where possible options include: -g Generate all debugging info -g:none Generate no debugging info

-g:{lines,vars,source} Generate only some debugging info -O Optimize; may hinder debugging or enlarge class file -nowarn Generate no warnings

-verbose Output messages about what the compiler is doing

-deprecation Output source locations where deprecated APIs are used -classpath <path> Specify where to find user class files

-sourcepath <path> Specify where to find input source files -bootclasspath <path> Override location of bootstrap class files -extdirs <dirs> Override location of installed extensions

-d <directory> Specify where to place generated class files

-encoding <encoding> Specify character encoding used by source files -source <release> Provide source compatibility with specified release -target <release> Generate class files for specific VM version

-help Print a synopsis of standard options

Ici l'option -classpath peut nous être utile. Elle permet d'indiquer au compilateur où chercher ses classes et paquetages. Essayons. Compilons en disant au compilateur que le paquetage istia.st est désormais dans le dossier

mesClasses :

E:\data\serge\JAVA\classes\paquetages\personne>javac -classpath mesClasses test2.java E:\data\serge\JAVA\classes\paquetages\personne>dir

06/06/2002 16:47 236 test2.java 06/06/2002 17:03 740 test2.class 06/06/2002 16:21 <DIR> mesClasses

La compilation se fait cette fois sans problème. Exécutons le programme test2.class : E:\data\serge\JAVA\classes\paquetages\personne>java test2

Exception in thread "main" java.lang.NoClassDefFoundError: istia/st/personne at test2.main(test2.java:6)

C'est maintenant au tour de la machine virtuelle Java de ne pas trouver la classe istia/st/personne. Elle la cherche dans le répertoire courant alors qu'elle est maintenant dans le répertoire mesClasses. Regardons les options de la machine virtuelle Java :

E:\data\serge\JAVA\classes\paquetages\personne>java Usage: java [-options] class [args...]

(to execute a class)

or java -jar [-options] jarfile [args...] (to execute a jar file)

where options include:

-client to select the "client" VM -server to select the "server" VM

-hotspot is a synonym for the "client" VM [deprecated] The default VM is client.

-cp -classpath <directories and zip/jar files separated by ;> set search path for application classes and resources -D<name>=<value>

set a system property -verbose[:class|gc|jni] enable verbose output

-version print product version and exit

-showversion print product version and continue -? -help print this help message

-X print help on non-standard options -ea[:<packagename>...|:<classname>] -enableassertions[:<packagename>...|:<classname>] enable assertions -da[:<packagename>...|:<classname>] -disableassertions[:<packagename>...|:<classname>] disable assertions -esa | -enablesystemassertions enable system assertions -dsa | -disablesystemassertions disable system assertions

On voit que la JVM a également une option classpath comme le compilateur. Utilisons-la pour lui dire où se trouve le paquetage istia.st :

E:\data\serge\JAVA\classes\paquetages\personne>java.bat -classpath mesClasses test2 Exception in thread "main" java.lang.NoClassDefFoundError: test2

On n'a pas beaucoup progressé. C'est maintenant la classe test2 elle-même qui n'est pas trouvée. Pour la raison suivante : en l'absence du mot clé classpath, le répertoire courant est systématiquement exploré lors de la recherche de classes mais pas lorsqu'il est présent. Du coup, la classe test2.class qui se trouve dans le répertoire courant n'est pas trouvée. La solution ? Ajouter le répertoire courant au classpath. Le répertoire courant est représenté par le symbole .

E:\data\serge\JAVA\classes\paquetages\personne>java -classpath mesClasses;. test2 p1=personne(Jean,Dupont,20)

Pourquoi toutes ces complications ? Le but des paquetages est d'éviter les conflits de noms entre classes. Considérons deux entreprises E1 et E2 distribuant des classes empaquetées respectivement dans les paquetages

com.e1 et com.e2. Soit un client C qui achète ces deux ensembles de classes dans lesquelles les deux entreprises

ont défini toutes deux une classe personne. Le client C référencera la classe personne de l'entreprise E1 par

com.e1.personne et celle de l'entreprise E2 par com.e2.personne évitant ainsi un conflit de noms.

II-F-2 - Recherche des paquetages

Lorsque nous écrivons dans un programme

import java.util.*;

pour avoir accès à toutes les classes du paquetage java.util, où celui-ci est-il trouvé ? Nous avons dit que les paquetages étaient cherchés par défaut dans le répertoire courant ou dans la liste des répertoires déclarés dans l'option classpath du compilateur ou de la JVM si cette option est présente. Ils sont également cherchés dans les répertoires lib du répertoire d'installation du JDK. Considérons ce répertoire :

Dans cet exemple, les arborescences jdk14\lib et jdk14\jre\lib seront explorées pour y chercher soit des fichiers .class, soit des fichiers .jar ou .zip qui sont des archives de classes. Faisons par exemple une recherche des fichiers

.jar se trouvant sous le répertoire jdk14 précédent :

Il y en a plusieurs dizaines. Un fichier .jar peut s'ouvrir avec l'utilitaire winzip. Ouvrons le fichier rt.jar ci-dessus (rt=RunTime). On y trouve plusieurs centaines de fichiers .class dont celles appartenant au paquetage java.util :

Une méthode simple pour gérer les paquetages est alors de les placer dans le répertoire <jdk>\jre\lib où <jdk> est le répertoire d'installation du JDK. En général, un paquetage contient plusieurs classes et il est pratique de rassembler celles-ci dans un unique fichier .jar (JAR=Java ARchive file). L'exécutable jar.exe se trouve dans le dossier <jdk>\bin :

E:\data\serge\JAVA\classes\paquetages\personne>dir "e:\program files\jdk14\bin\jar.exe" 07/02/2002 12:52 28 752 jar.exe

Une aide à l'utilisation du programme jar peut être obtenue en l'appelant sans paramètres : E:\data\serge\JAVA\classes\paquetages\personne>"e:\program files\jdk14\bin\jar.exe" Syntaxe : jar {ctxu}[vfm0M] [fichier-jar] [fichier-manifest] [rÚp -C] fichiers ... Options :

-c crÚer un nouveau fichier d''archives

-t gÚnÚrer la table des matiÞres du fichier d''archives

-x extraire les fichiers nommÚs (ou tous les fichiers) du fichier d''archives -u mettre Ó jour le fichier d''archives existant

-v gÚnÚrer des informations verbeuses sur la sortie standard -f spÚcifier le nom du fichier d''archives

-m inclure les informations manifest provenant du fichier manifest spÚcifiÚ -0 stocker seulement ; ne pas utiliser la compression ZIP

-M ne pas crÚer de fichier manifest pour les entrÚes -i gÚnÚrer l''index pour les fichiers jar spÚcifiÚs

-C passer au rÚpertoire spÚcifiÚ et inclure le fichier suivant Si un rÚpertoire est spÚcifiÚ, il est traitÚ rÚcursivement.

Les noms des fichiers manifest et d''archives doivent Ûtre spÚcifiÚs dans l''ordre des indicateurs ''m'' et ''f''.

Exemple 1 : pour archiver deux fichiers de classe dans le fichier d''archives classes.jar : jar cvf classes.jar Foo.class Bar.class

Exemple 2 : utilisez le fichier manifest existant ''monmanifest'' pour archiver tous les fichiers du rÚpertoire foo/ dans ''classes.jar'':

jar cvfm classes.jar monmanifest -C foo/ .

Revenons à la classe personne.class créée précédemment dans un paquetage istia.st : E:\data\serge\JAVA\classes\paquetages\personne>dir

06/06/2002 16:28 467 personne.java 06/06/2002 17:36 195 test.java

06/06/2002 16:04 <DIR> istia 06/06/2002 16:06 738 test.class 06/06/2002 16:47 236 test2.java 06/06/2002 18:15 740 test2.class E:\data\serge\JAVA\classes\paquetages\personne>dir istia 06/06/2002 16:04 <DIR> st E:\data\serge\JAVA\classes\paquetages\personne>dir istia\st 06/06/2002 16:28 675 personne.class

Créons un fichier istia.st.jar archivant toutes les classes du paquetage istia.st donc toutes les classes de l'arborescence istia\st ci-dessus :

E:\data\serge\JAVA\classes\paquetages\personne>"e:\program files\jdk14\bin\jar" cvf istia.st.jar istia\st\* E:\data\serge\JAVA\classes\paquetages\personne>dir 06/06/2002 16:28 467 personne.java 06/06/2002 17:36 195 test.java 06/06/2002 16:04 <DIR> istia 06/06/2002 16:06 738 test.class 06/06/2002 16:47 236 test2.java 06/06/2002 18:15 740 test2.class 06/06/2002 18:08 874 istia.st.jar

Examinons avec winzip le contenu du fichier istia.st.jar :

Plaçons le fichier istia.st.jar dans le répertoire <jdk>\jre\lib\perso :

E:\data\serge\JAVA\classes\paquetages\personne>dir "e:\program files\jdk14\jre\lib\perso" 06/06/2002 18:08 874 istia.st.jar

Maintenant compilons le programme test2.java puis exécutons-le :

E:\data\serge\JAVA\classes\paquetages\personne>javac -classpath istia.st.jar test2.java E:\data\serge\JAVA\classes\paquetages\personne>java -classpath istia.st.jar;. test2 p1=personne(Jean,Dupont,20)

On remarque qu'on n'a eu qu'à citer le nom de l'archive à explorer sans avoir à dire explicitement où elle se trouvait. Tous les répertoires de l'arborescence <jdk>\jre\lib sont explorés pour trouver le fichier .jar demandé.

Dans le document Télécharger cours Java en pdf (Page 63-70)