Intéressé par des cours d'informatique en ligne ?
Visitez mon nouveau site https://www.yesik.it !

Cet article est une reprise de l'article Créer une archive JAR avec Ant que j'avais précédemment publié sur http://wiki.esicom-st-malo.fr

Pour faciliter la distribution des applications Java, il est possible de réunir tous les fichiers qui la composent dans une archive .jar. Le JDK fourni un utilitaire spécifique (jar) pour cette tâche. Mais il est également possible de l'automatiser. Nous allons donc voir dans ce tutoriel comment créer une archive JAR avec Ant.

Objectifs A la fin de ce tutoriel, vous saurez:
  • Utiliser la tâche jar dans un fichier build.xml,
  • Utiliser Ant pour construire une archive .jar.
Prérequis
Moyens


Pourquoi empaqueter une application?

Réunir tous les fichiers (.class et fichiers de données) qui composent une application dans une seule et même archive offre plusieurs avantages. En particulier, cela:

On peut également noter que les archives étant compressées, elles réduisent les besoins en bande passante pour le transfert d'application. Enfin, elles peuvent également être signées numériquement, ce qui renforce la sécurité.

Créer une archive .jar

Dans le tutoriel précédent, nous avons réalisé une petite application Java, et utilisé Ant pour la compiler.

Si vous avez suivi ce tutoriel, vous devez déjà disposer de ces fichiers. Sinon, reportez-vous y pour récupérer les fichiers Banque.java, Compte.java et build.xml.

La cible dist

Dans le JDK, l'utilitaire jar permet de créer une archive .jar. Nous n'allons pas l'utiliser directement ici, mais au travers de l'outil Ant.

Pour créer une archive, il nous faut donc ajouter une nouvelle cible à notre fichier build.xml. Cette cible utilisera la tâche jar:

<target name="dist" depends="compile">
        <jar destfile="${dist.dir}/app.jar" basedir="${build.dir}" />
</target>

jar ou jar?

Ne confondez-pas:

  • La commande jar du JDK qui permet de créer une archive
  • La tâche jar de Ant qui permet de créer une archive
  • Le fichier .jar qui est l'archive elle-même

Deux choses à noter ici:

<property name="dist.dir" value="dist" />

Puisque nous introduisons un nouveau répertoire, il nous faut également modifier les cibles init et clean respectivement pour créer et supprimer ce répertoire:

<target name="init">
        <mkdir dir="${build.dir}" />
       <mkdir dir="${dist.dir}" />
</target>
<target name="clean" description="Fait le menage">
        <delete dir="${build.dir}" />
        <delete dir="${dist.dir}" />
</target>

Construire l'archive

Maintenant que le fichier build.xml a été modifié, contruire l'archive se fait simplement en utilisant la commande ant à partir du répertoire racine du projet:

 sh$ ant dist
Buildfile: build.xml

init:
    [mkdir] Created dir: /Users/sylvain/ProjetBanque/build
    [mkdir] Created dir: /Users/sylvain/ProjetBanque/dist

compile:
    [javac] Compiling 2 source files to /Users/sylvain/ProjetBanque/build

dist:
      [jar] Building jar: /Users/sylvain/ProjetBanque/dist/app.jar

BUILD SUCCESSFUL
Total time: 4 seconds

On peut facilement vérifier que l'archive a bien été produite:

 sh$ ls dist
 app.jar

Puisque l'interpréteur Java est capable d'exécuter un programme stocké dans une archive JAR, nous pouvons tenter d'exécuter notre programme:

 sh$ cd dist
 sh$ java -jar app.jar
 Failed to load Main-Class manifest attribute from
 app.jar

Oups! Visiblement, quelque chose manque...

Le manifeste

En plus des fichiers spécifiques à notre projet, une archive jar doit toujours contenir un manifeste. C'est un fichier spécial qui fourni des informations sur l'archive (des méta-informations). Par exemple, c'est le manifeste qui indique à l'interpréteur java quelle est la classe principale (celle qui contient le main) d'une application.

Si l'on regarde à l'aide de la commande jar le contenu de notre archive, nous pouvons constater qu'un fichier MANIFEST.MF a automatiquement été généré dans le sous-répertoire META-INF:

 sh$ jar tvf app.jar
     0 Sat Oct 06 22:01:26 CEST 2007 META-INF/
   106 Sat Oct 06 22:01:24 CEST 2007 META-INF/MANIFEST.MF
     0 Sat Oct 06 22:01:24 CEST 2007 fr/
     0 Sat Oct 06 22:01:24 CEST 2007 fr/esicom/
     0 Sat Oct 06 22:01:24 CEST 2007 fr/esicom/exemples/
   513 Sat Oct 06 22:01:24 CEST 2007 fr/esicom/exemples/Banque.class
   568 Sat Oct 06 22:01:24 CEST 2007 fr/esicom/exemples/Compte.class

Lors de la création de l'archive, Ant a généré un manifeste par défaut. Nous pouvons en visualiser le contenu:

 sh$ jar xf app.jar META-INF/MANIFEST.MF
 sh$ cat META-INF/MANIFEST.MF
 Manifest-Version: 1.0
 Ant-Version: Apache Ant 1.7.0
 Created-By: 1.3.1_03-74 ("Apple Computer, Inc.")

Tout ce qui manque à ce manifeste pour permettre à l'interpréteur java d'utiliser notre archive est l'information qui précise que la classe principale de notre programme est fr.esicom.exemples.Banque. Il existe plusieurs manières de fournir cette information, mais le plus simple est de l'indiquer à Ant, dans la tâche jar. La cible dist devient alors:

<target name="dist" depends="compile">
        <jar destfile="${dist.dir}/app.jar" basedir="${build.dir}">
                <manifest>
                        <attribute name="Main-Class"
                            value="fr.esicom.exemples.Banque" />
                </manifest>
        </jar>
</target>

Nous pouvons maintenant reconstruire notre archive (en faisant avant un peu de ménage pour effacer les fichiers que nous avons laissé traîner dans build):

 sh$ cd...
 sh$ ant clean dist
 Buildfile: build.xml
 
 clean:
    [delete] Deleting directory /Users/sylvain/ProjetBanque/build
    [delete] Deleting directory /Users/sylvain/ProjetBanque/dist
 
 init:
     [mkdir] Created dir: /Users/sylvain/ProjetBanque/build
     [mkdir] Created dir: /Users/sylvain/ProjetBanque/dist
 
 compile:
     [javac] Compiling 2 source files to /Users/sylvain/ProjetBanque/build
 
 dist:
       [jar] Building jar: /Users/sylvain/ProjetBanque/dist/app.jar
 
 BUILD SUCCESSFUL
 Total time: 4 seconds

Un coup d'oeil dans le manifeste de l'archive nous confirme que la classe principale est bien indiquée:

 sh$ cd dist
 sh$ jar xf app.jar META-INF/MANIFEST.MF
 sh$ cat META-INF/MANIFEST.MF
 Manifest-Version: 1.0
 Ant-Version: Apache Ant 1.7.0
 Created-By: 1.3.1_03-74 ("Apple Computer, Inc.")
 Main-Class: fr.esicom.exemples.Banque

Maintenant que cette information est présente, l'interpréteur java peut exécuter le programme stocké dans l'archive:

 sh$ java -jar app.jar
 Le solde du compte est de 1800.0

Et voilà! Nous disposons d'une archive qui contient tous les fichiers nécessaires pour faire fonctionner notre application. Pour la diffuser ou la déployer, il suffit maintenant de fournir le fichier app.jar.

De plus, comme l'archive est générée par Ant, reconstruire l'archive tout en s'assurant qu'elle contiendra bien la toute dernière version des fichiers compilés se fait simplement en tapant ant dist à l'invite du shell.

Voir aussi