Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

Les archives Java et l'outil jar

Les droits d'accès en Java Les modules Java et l'outil jmod



Accès rapide :
Qu'est-ce qu'un fichier .jar ?
L'outil jar[.exe] proposé par le JDK
Création d'un jar en mode ligne de commande
Création d'un jar assistée par Eclipse
Configuration du fichier de manifeste
Spécifier l'entrée Main-Class du fichier de manifeste
Spécifier l'entrée Class-Path du fichier de manifeste
Autres opérations possibles sur une archive Jar
Lister le contenu d'une archive Java
Extraction d'une archive Jar
Modification d'une archive Jar
Automatisation de la construction des archives Java

Qu'est-ce qu'un fichier .jar ?

Il s'agit d'une archive contenant des fichiers Java compilés (des fichiers .class). Le terme de Jar singifie Java ARchive. Cette archive est au format ZIP : vous pouvez donc ouvrir un fichier JAR avec n'importe quel outil de manipulation de fichier ZIP (7-Zip, WinZip, Gestionnaire d'archives Linux...).

Vous pouvez créer une archive JAR avec un outil de compression ZIP quelconque. Pour autant il est vivement conseillé d'utiliser l'outil jar[.exe] proposé par votre JDK (Java Development Kit). Effectivement, outre vos fichiers .class, un JAR doit contenir un fichier de « manifeste » : il doit être obligatoirement se nommer META-INF/MANIFEST.MF. L'outil jar gère de manière automatisée la production de ce fichier de manifeste.

L'outil jar[.exe] proposé par le JDK

L'outil jar se manipule en mode ligne de commande. Il accepte un certain nombre d'options (de paramètres) pour contrôler le contenu de l'archive produite. Pour commencer, je vous propose de jeter un coup d'oeil sur les options proposées.

$> jar --help
Usage: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...
jar creates an archive for classes and resources, and can manipulate or
restore individual classes or resources from an archive.

 Examples:
 # Create an archive called classes.jar with two class files:
 jar --create --file classes.jar Foo.class Bar.class
 # Create an archive using an existing manifest, with all the files in foo/:
 jar --create --file classes.jar --manifest mymanifest -C foo/ .
 # Create a modular jar archive, where the module descriptor is located in
 # classes/module-info.class:
 jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0
     -C foo/ classes resources
 # Update an existing non-modular jar to a modular jar:
 jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0
     -C foo/ module-info.class
 # Create a multi-release jar, placing some files in the META-INF/versions/9 directory:
 jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes

To shorten or simplify the jar command, you can specify arguments in a separate
text file and pass it to the jar command with the at sign (@) as a prefix.

 Examples:
 # Read additional options and list of class files from the file classes.list
 jar --create --file my.jar @classes.list


 Main operation mode:

  -c, --create               Create the archive
  -i, --generate-index=FILE  Generate index information for the specified jar
                             archives
  -t, --list                 List the table of contents for the archive
  -u, --update               Update an existing jar archive
  -x, --extract              Extract named (or all) files from the archive
  -d, --describe-module      Print the module descriptor, or automatic module name

 Operation modifiers valid in any mode:

  -C DIR                     Change to the specified directory and include the
                             following file
  -f, --file=FILE            The archive file name. When omitted, either stdin or
                             stdout is used based on the operation
      --release VERSION      Places all following files in a versioned directory
                             of the jar (i.e. META-INF/versions/VERSION/)
  -v, --verbose              Generate verbose output on standard output

 Operation modifiers valid only in create and update mode:

  -e, --main-class=CLASSNAME The application entry point for stand-alone
                             applications bundled into a modular, or executable,
                             jar archive
  -m, --manifest=FILE        Include the manifest information from the given
                             manifest file
  -M, --no-manifest          Do not create a manifest file for the entries
      --module-version=VERSION    The module version, when creating a modular
                             jar, or updating a non-modular jar
      --hash-modules=PATTERN Compute and record the hashes of modules 
                             matched by the given pattern and that depend upon
                             directly or indirectly on a modular jar being
                             created or a non-modular jar being updated
  -p, --module-path          Location of module dependence for generating
                             the hash

 Operation modifiers valid only in create, update, and generate-index mode:

  -0, --no-compress          Store only; use no ZIP compression

 Other options:

  -?, -h, --help[:compat]    Give this, or optionally the compatibility, help
      --help-extra           Give help on extra options
      --version              Print program version

 An archive is a modular jar if a module descriptor, 'module-info.class', is
 located in the root of the given directories, or the root of the jar archive
 itself. The following operations are only valid when creating a modular jar,
 or updating an existing non-modular jar: '--module-version',
 '--hash-modules', and '--module-path'.

 Mandatory or optional arguments to long options are also mandatory or optional
 for any corresponding short options.

$> 
ceux qui connaissent bien Linux et ses commandes de bases trouveront certainement quelques similitudes avec la commande tar.

Création d'un jar en mode ligne de commande

Si vous souhaitez créer un jar, il faudra donc utiliser la commande jar avec l'option -c (create). Si vous souhaitez avoir la liste des fichiers et dossiers archiver, il faudra cumuler l'option -v (verbose). Enfin, pour contrôler le nom du fichier .jar produit, il faut encore cumuler l'option -f (file) : elle devra être suivie du nom de l'archive à produire.

si vous devez founir plusieurs options, vous pourrez les cumuler : par exemple, -cvf.

Voici un exemple d'utilisation.

$> cd projectName/bin
$> ls -al
total 12
drwxr-xr-x. 3 dominique dominique 4096 25 mars  16:11 .
drwxr-xr-x. 6 dominique dominique 4096 26 mars  10:59 ..
drwxr-xr-x. 3 dominique dominique 4096 25 mars  16:11 fr
$> jar -cvf ../test.jar . 
added manifest
adding: fr/(in = 0) (out= 0)(stored 0%)
adding: fr/koor/(in = 0) (out= 0)(stored 0%)
adding: fr/koor/poo/(in = 0) (out= 0)(stored 0%)
adding: fr/koor/poo/RationalTest.class(in = 1124) (out= 629)(deflated 44%)
adding: fr/koor/poo/Rational.class(in = 2174) (out= 1145)(deflated 47%)
adding: fr/koor/testrunner/(in = 0) (out= 0)(stored 0%)
adding: fr/koor/testrunner/TestRunner.class(in = 4982) (out= 2482)(deflated 50%)
adding: fr/koor/testrunner/TestRunner$1.class(in = 1829) (out= 916)(deflated 49%)
adding: fr/koor/testrunner/TestMethod.class(in = 756) (out= 409)(deflated 45%)
adding: fr/koor/testrunner/TestClass.class(in = 469) (out= 287)(deflated 38%)
adding: fr/koor/testrunner/TestMethod$NoExceptionExpected.class(in = 507) (out= 330)(deflated 34%)
adding: fr/koor/testrunner/Assert.class(in = 800) (out= 485)(deflated 39%)
adding: fr/koor/testrunner/AssertException.class(in = 701) (out= 409)(deflated 41%)
$> ls -al ..
total 44
drwxr-xr-x. 6 dominique dominique 4096 26 mars  10:59 .
drwxr-xr-x. 6 dominique dominique 4096 22 mars  12:58 ..
drwxr-xr-x. 3 dominique dominique 4096 25 mars  16:11 bin
-rw-r--r--. 1 dominique dominique  268 20 mars  13:11 .classpath
-rw-r--r--. 1 dominique dominique  369 20 mars  10:05 .project
drwxr-xr-x. 2 dominique dominique 4096 20 mars  10:05 .settings
drwxr-xr-x. 3 dominique dominique 4096 20 mars  10:07 src
drwxr-xr-x. 3 dominique dominique 4096 20 mars  13:59 test
-rw-rw-r--. 1 dominique dominique 9290 26 mars  10:59 test.jar
$> 

J'attire votre attention sur le fait que, lors du lancement de la commande jar, un fichier de manifeste par défaut a été produit. Voici par curiosité, une partie du contenu de l'archive produite.

Une partie du contenu de l'archive produite

Création d'un jar assistée par Eclipse

Vous pouvez aussi produire un fichier Jar à partir d'Eclipse. Pour ce faire, cliquez avec le bouton droit de la souris sur le projet, cliquez sur « Export... », puis sélectionnez l'assistant « JAR file », comme montré dans la capture d'écran ci-dessous.

Démarrage de l'assistant de production d'un Jar

Il ne vous reste plus qu'a sélectionner les éléments à archiver et a spécifier le nom de votre fichier Jar. Voici une capture d'écran de cet assistant.

Démarrage de l'assistant de production d'un Jar

Configuration du fichier de manifeste

Voici le contenu initial du fichier de manifeste qui a été produit. Le caractère : permet de séparer un nom de paramètre de sa valeur. J'ai utilisé la commande jar[.exe] d'un JDK 14 (d'où le second numéro de version).

Manifest-Version: 1.0
Created-By: 14 (Oracle Corporation)

Vous pouvez compléter ce fichier avec vos propres paramètres. Pour ce faire, il suffit de rajouter l'option -m avec un fichier de manifeste secondaire contenant les paires de clés/valeurs à rajouter dans le fichier de manifeste produit par l'outil jar.

Spécifier l'entrée Main-Class du fichier de manifeste

L'entrée Main-Class du fichier de manifeste permet de spécifier le nom de la classe, portant la méthode main et permettant de démarrer votre programme. Il sera ensuite possible de démarrer une JVM est lui demandant de localiser la Main-Class à partir du fichier de manifeste.

Pour rajouter l'entrée Main-Class dans le jar, commencez par écrire un fichier texte avec le contenu suivant (adaptez le nom de la classe en fonction de votre projet).

Main-Class: fr.koor.testrunner.TestRunner
Le fichier manifest-additions.txt

Ensuite, veuillez exécuter la commande suivante, en adaptant les chemins si nécessaire.

$> cd bin
$> jar -cvfm ../test.jar ../manifest-additions.txt .
added manifest
adding: fr/(in = 0) (out= 0)(stored 0%)
adding: fr/koor/(in = 0) (out= 0)(stored 0%)
adding: fr/koor/poo/(in = 0) (out= 0)(stored 0%)
adding: fr/koor/poo/RationalTest.class(in = 1124) (out= 629)(deflated 44%)
adding: fr/koor/poo/Rational.class(in = 2174) (out= 1145)(deflated 47%)
adding: fr/koor/testrunner/(in = 0) (out= 0)(stored 0%)
adding: fr/koor/testrunner/TestRunner.class(in = 4982) (out= 2482)(deflated 50%)
adding: fr/koor/testrunner/TestRunner$1.class(in = 1829) (out= 916)(deflated 49%)
adding: fr/koor/testrunner/TestMethod.class(in = 756) (out= 409)(deflated 45%)
adding: fr/koor/testrunner/TestClass.class(in = 469) (out= 287)(deflated 38%)
adding: fr/koor/testrunner/TestMethod$NoExceptionExpected.class(in = 507) (out= 330)(deflated 34%)
adding: fr/koor/testrunner/Assert.class(in = 800) (out= 485)(deflated 39%)
adding: fr/koor/testrunner/AssertException.class(in = 701) (out= 409)(deflated 41%)
$> 

Et voici maintenant le nouveau contenu du fichier de manifeste.

Manifest-Version: 1.0
Main-Class: fr.koor.testrunner.TestRunner
Created-By: 14 (Oracle Corporation)

Pour démarrer le programme à partir du fichier .jar, veuillez exécuter la ligne de commande suivante.

$> java -jar test.jar

Spécifier l'entrée Class-Path du fichier de manifeste

Une autre entrée du fichier de manifeste permet d'ajouter des dépendances sur d'autres fichiers Jar : c'est l'entrée Class-Path. Cela simplifie considérablement la ligne de code nécessaire au démarrage du programme. Vous devez procéder de la même manière que pour l'entrée Main-Class, pour ajouter cette nouvelle entrée du manifeste.

Main-Class: fr.koor.testrunner.TestRunner
Class-Path: first.jar second.jar third.jar
Le fichier manifest-additions.txt

Ensuite, veuillez exécuter la commande suivante, en adaptant les chemins si nécessaire.

$> cd bin
$> jar -cvfm ../test.jar ../manifest-additions.txt .
added manifest
adding: fr/(in = 0) (out= 0)(stored 0%)
adding: fr/koor/(in = 0) (out= 0)(stored 0%)
adding: fr/koor/poo/(in = 0) (out= 0)(stored 0%)
adding: fr/koor/poo/RationalTest.class(in = 1124) (out= 629)(deflated 44%)
adding: fr/koor/poo/Rational.class(in = 2174) (out= 1145)(deflated 47%)
adding: fr/koor/testrunner/(in = 0) (out= 0)(stored 0%)
adding: fr/koor/testrunner/TestRunner.class(in = 4982) (out= 2482)(deflated 50%)
adding: fr/koor/testrunner/TestRunner$1.class(in = 1829) (out= 916)(deflated 49%)
adding: fr/koor/testrunner/TestMethod.class(in = 756) (out= 409)(deflated 45%)
adding: fr/koor/testrunner/TestClass.class(in = 469) (out= 287)(deflated 38%)
adding: fr/koor/testrunner/TestMethod$NoExceptionExpected.class(in = 507) (out= 330)(deflated 34%)
adding: fr/koor/testrunner/Assert.class(in = 800) (out= 485)(deflated 39%)
adding: fr/koor/testrunner/AssertException.class(in = 701) (out= 409)(deflated 41%)
$> 

Et voici maintenant le nouveau contenu du fichier de manifeste.

Manifest-Version: 1.0
Main-Class: fr.koor.testrunner.TestRunner
Class-Path: first.jar second.jar third.jar
Created-By: 14 (Oracle Corporation)

Autres opérations possibles sur une archive Jar

Si vous reprennez la liste des options supportées par la commande jar, vous constaterez que vous pouvez aussi lister le contenu d'une archive Jar, la modifier, en extraire son contenu...

Lister le contenu d'une archive Java

Pour lister le contenu d'un fichier Jar, vous devez invoquer l'option t (pour table of content). Voici un exemple d'utilisation de cette option de l'outil jar[.exe].

$> jar -tvf test.jar
     0 Thu Mar 26 19:24:14 CET 2020 META-INF/
   149 Thu Mar 26 19:24:14 CET 2020 META-INF/MANIFEST.MF
     0 Wed Mar 25 16:11:58 CET 2020 fr/
     0 Wed Mar 25 16:11:58 CET 2020 fr/koor/
     0 Wed Mar 25 16:11:58 CET 2020 fr/koor/poo/
  1124 Wed Mar 25 16:11:58 CET 2020 fr/koor/poo/RationalTest.class
  2174 Wed Mar 25 16:11:58 CET 2020 fr/koor/poo/Rational.class
     0 Wed Mar 25 16:11:58 CET 2020 fr/koor/testrunner/
  4982 Wed Mar 25 16:11:58 CET 2020 fr/koor/testrunner/TestRunner.class
  1829 Wed Mar 25 16:11:58 CET 2020 fr/koor/testrunner/TestRunner$1.class
   756 Wed Mar 25 16:11:58 CET 2020 fr/koor/testrunner/TestMethod.class
   469 Wed Mar 25 16:11:58 CET 2020 fr/koor/testrunner/TestClass.class
   507 Wed Mar 25 16:11:58 CET 2020 fr/koor/testrunner/TestMethod$NoExceptionExpected.class
   800 Wed Mar 25 16:11:58 CET 2020 fr/koor/testrunner/Assert.class
   701 Wed Mar 25 16:11:58 CET 2020 fr/koor/testrunner/AssertException.class
$> jar -tf test.jar
META-INF/
META-INF/MANIFEST.MF
fr/
fr/koor/
fr/koor/poo/
fr/koor/poo/RationalTest.class
fr/koor/poo/Rational.class
fr/koor/testrunner/
fr/koor/testrunner/TestRunner.class
fr/koor/testrunner/TestRunner$1.class
fr/koor/testrunner/TestMethod.class
fr/koor/testrunner/TestClass.class
fr/koor/testrunner/TestMethod$NoExceptionExpected.class
fr/koor/testrunner/Assert.class
fr/koor/testrunner/AssertException.class
$> 
l'option -v (verbose) utilisée conjointement avec l'option d'affichage de la table de matière permet d'obtenir des informations complémentaires : la taille des fichiers et les dates de création de ces derniers.

Extraction d'une archive Jar

Pour extraire le contenu d'un Jar, vous devez utiliser l'option -x. Voici un exemple d'utilisation.

$> ls -l
total 0
$> jar -xvf ../test.jar
  créé : META-INF/
 décompressé : META-INF/MANIFEST.MF
  créé : fr/
  créé : fr/koor/
  créé : fr/koor/poo/
 décompressé : fr/koor/poo/RationalTest.class
 décompressé : fr/koor/poo/Rational.class
  créé : fr/koor/testrunner/
 décompressé : fr/koor/testrunner/TestRunner.class
 décompressé : fr/koor/testrunner/TestRunner$1.class
 décompressé : fr/koor/testrunner/TestMethod.class
 décompressé : fr/koor/testrunner/TestClass.class
 décompressé : fr/koor/testrunner/TestMethod$NoExceptionExpected.class
 décompressé : fr/koor/testrunner/Assert.class
 décompressé : fr/koor/testrunner/AssertException.class
$> ls -l
drwxrwxr-x. 3 dominique dominique 4096 25 mars  16:11 fr
drwxrwxr-x. 2 dominique dominique 4096 27 mars  12:22 META-INF
$> 

Modification d'une archive Jar

Pour modifier une archive Jar, vous devez utiliser l'option -u.

Automatisation de la construction des archives Java

Il est possible d'automatiser la construction de vos archives Java. Effectivement, des outils de « build », tels que ANT ou Maven, peuvent invoquer l'outil jar à votre place, ce qui simplifiera votre travail. Ces deux outils sont développés par la fondation Apache.

Pour de plus amples informations sur ANT, vous pouvez aussi consulter mon support de cours sur le sujet.



Les droits d'accès en Java Les modules Java et l'outil jmod