JAR

Portabilité du code grâce aux archives Java

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com

En PHP pour inclure un fichier ou un groupe de fichier on doit utiliser soit la fonction include, soit require (avec ses variantes _once pour l'inclusion unique). En Java la portabilité du code peut être organisée grâce aux packages. C'est beaucoup plus pratique que les inclusions manuelles en PHP.

L'inclusion des classes et fichiers en Java peut s'effectuer grâce aux packages avec l'extension JAR. Ils ressemblent énormément aux archives compressés et peuvent contenir plusieurs classes Java ainsi que d'autres types de fichiers (images, configuration etc.). Regardons comment générer un simple JAR avec la commande native Java :

public class TestJar {
    public static void main(String[] args) {
        System.out.println("TestJar : main method called");
    }
}

Voici le code qui sert à créer le package :

jar cmf ./MANIFEST.MF TestJar.jar TestJar.java

On y remarque la présence d'un ./MANIFEST.MF. Il s'agit d'un fichier qui définit certaines propriétés du package. Dans notre exemple, on y renseigne juste le nom de la classe principale avec ces lignes :

Main-Class: TestJar
Class-Path: .

Il est important que le fichier manifeste se termine par un saut à la ligne vide. Comme on peut analyser la suite de la commande, le deuxième paramètre correspond au nom du fichier sortant. Le dernier signifie le ou les fichiers contenus dans le package.

Cependant, cette méthode est parfois trop robustie pour être facilement utilisable dans les applications plus grandes. Une bonne alternative à elle est proposée par Apache et sa librairie ANT (Another Neat Tool).

Utiliser ANT pour générer un JAR

Plusieurs outils externes à Oracle existent pour générer un package JAR. L'un des plus connus est ANT qui permet de construire des packages facilement, grâce à la configuration comprise dans un fichier XML.

Apache ANT est une librairie Java qui permet d'exécuter plusieurs tâches depuis la ligne de commande. Grâce à elle, on peut essentiellement construire un package pour le code Java. La construction s'opère grâce à la spécification définie dans un fichier XML. Une tâche supplémentaire pouvant être effectuée est l'exécution des tests unitaires avec la librairie JUnit. Regardons comment deployer un package JAR grâce à l'ANT, tout d'abord sur un fichier XML, nommé build.xml :

<?xml version="1.0" encoding="UTF-8" ?>
<project name="antTest" default="usage" basedir=".">
  <!-- @properties -->		
  <property name="src.dir"          value="${basedir}/src"/>
  <property name="build.dir" 	    value="${basedir}/tmp/classes"/>
  <property name="lib.dir"          value="${basedir}/lib"/>
  <property name="conf.dir"         value="${basedir}/conf"/>

  
  <path id="classpath">
    <fileset dir="./lib">
      <include name="**/*"/>
    </fileset>
    <dirset dir="./conf">
      <include name="**/*" />
    </dirset>
  </path>

  <!-- @targets -->
  <target name="jar" >
    <mkdir dir="${basedir}/tmp/classes"/>
    <javac srcdir="${src.dir}" destdir="${build.dir}" debug="on" debuglevel="lines,vars,source" encoding="UTF-8" source="1.5" target="1.5" >
      <compilerarg value="-Xlint:deprecated"/>
      <classpath refid="classpath"/>
    </javac>
    <jar jarfile="${basedir}/antTest.jar" basedir="${build.dir}" >
      <manifest>
        <attribute name="Main-Class" value="testant.TestAnt"/>
      </manifest>
      <fileset dir="./conf">
    </jar>
  </target>
</project>

Voici les fichiers qu'on va compiler :

TestAnt.java

package testant;

import org.apache.axis.client.*;
import testant.TestAntString;

public class TestAnt {
    public static void main(String[] args) {
        System.out.println("TestAnt : main method called");
        TestAntString tas = new TestAntString();
    }
}

TestAntString.java

package testant;

public class TestAntString {
    public TestAntString() {
        System.out.println("TestAntString constructor called");
      }
}

conf/project.properties

project.name = ANT TEST

En plus de cela, on a rajouté un fichier axis-1.4.jar dans le répertoire lib.

Voici la commande qui permet d'exécuter le créer le JAR : ant jar

Et le résultat d'exécution du JAR avec la commande java -jar antTest.jar est le suivant :

TestAnt : main method called
TestAntString constructor called

Expliquons maintenant de différentes parties du fichier build.xml en se référant à des annotations précédés par @ :
- @properties : cette partie définit les répertoires qui seront utilisés plus loin dans le fichier build.xml . On y retrouve par exemple le dossier contenant les sources de classes (src), un autre avec les librairies externes (lib), un troisième avec les fichiers de configuration (config). Un dernier dossier définit la source de compilation des fichiers contenus dans src.dir.
- @paths : ici on retrouve la construction du CLASSPATH. Comme on le constate sur cet exemple, on utilise deux balises, <fileset /> et <dirset />. La première correspond à la liste des fichiers qu'on veut récupérer (les dossiers seront alors omis). La deuxième illustre les fichiers et les répertoires à récupérer dans CLASSPATH.
- @targets : dans la dernière partie on définit ce qu'on veut recevoir. En occurrence, il s'agit d'un package JAR. C'est défini dans la balise <jar />. Elle contient déjà mentionné le fichier de manifeste. Mais juste avant elle se trouve la balise <javac />. Son rôle est de spécifier la configuration pour les fichiers compilés.

Une question ? Une remarque ?

*

*

Un conseil Symfony2

Un problème filemtime()

Si pendant le développement de votre projet Symfony2 vous rencontrez un problème avec fonction filemtime, il peut s'agir d'un dysfonctionnement temporaire. Warning: filemtime() [function.filemtime]: stat failed for C:\Program Files (x86)\EasyPHP-5.3.5.0\www\gagu\src\Bun\DleBundle/Resources/views/Bundle/show.html.php in C:\Program Files (x86)\EasyPHP-5.3.5.0\www\appli\app\cache\dev\classes.php line 2064 Pour résoudre ce problème, vous pouvez être amenés à supprimer le cache du répertoire dev (si vous êtes en mode développement).