Programmation Java/JDK

Un livre de Wikilivres.
Aller à la navigation Aller à la recherche

Le JDK est un ensemble d'outil permettant de développer en Java.

Pour obtenir la liste des options d'un outil, il suffit de lancer l'outil sans aucun argument.

Compiler le code[modifier | modifier le wikicode]

javac est le compilateur qui convertit le code source .java en fichier .class (contenant le bytecode Java).

Supposons que vous avez :

  • un dossier « src » qui contient vos sources (tous vos fichiers .java) ;
  • un dossier « bin » où vous placerez tous les fichiers compilés (les fichier .class correspondant).
# compile seulement la classe Exemple et place le résultat dans bin
javac -d bin src/Exemple.java

# compile toutes les sources trouvées dans src et les place dans bin
javac -d bin src/**/*.java

Si la compilation échoue parce que votre code utilise des classes que javac ne connait pas (erreur Unable to find symbol), vous devez préciser à javac un classpath comme expliqué plus loin.

Lancer l'application[modifier | modifier le wikicode]

java permet une dans lancer une application java en ligne de commande, il faut passer en paramètre le nom complet (pleinement qualifié) de la classe.

java org.wikibooks.fr.Exemple argument_1 argument_2

La ligne de commande ci-dessus appel la méthode public static void main(String[] args) de la classe Exemple du package org.wikibooks.fr avec args, un tableau à deux éléments : "argument_1" et argument_2".

javaw permet une application Java sans console (interface graphique seule).

javaw org.wikibooks.fr.Exemple

Une archive java (*.jar) avec l'option -jar, un petit fichier (appelé « Manifest ») contenu dans le jar indique lui-même le nom de la classe principale à lancer.

java -jar chemin/vers/le/fichier.jar

Préciser le CLASSPATH[modifier | modifier le wikicode]

Dans toutes les commandes ci-dessus, il faut permettre à java de trouver tous les fichiers compilés nécessaire à l'exécution du code (les fichiers *.class générés avec javac). Pour cela, il faut préciser à java les répertoires ou celui-ci pourra trouver les classes et les packages nécessaires à l'application.

Pour cela, il faut définir ce qu'on appelle le « CLASS PATH », c'est une simple chaîne qui définit plusieurs chemins pour trouver des .class séparés par ":" sous Linux ou ";" sous Windows. Les chemins peuvent être des chemins vers des fichiers .jar ou vers des répertoires contenant des fichiers .class. Il y a deux façons de préciser le CLASSPATH à java, la première est d'utiliser le paramètre -classpath de ligne de commande.

Sous Linux, les chemins sont séparés par le caractère deux-points :

java -classpath chemin/vers/une/premiere/bibliotheque.jar:chemin/vers_une_autre/bibliotheque.jar:bin org.wikibooks.fr.Exemple

Sous Windows, les chemins sont séparés par le caractère point-virgule :

java -classpath X:\chemin\vers\une\premiere\bibliotheque.jar;Y:\chemin\vers_une_autre\bibliotheque.jar;bin org.wikibooks.fr.Exemple

Ici, java essaiera de trouver le fichier Exemple.class dans les deux jars donnés puis dans le dossier bin. Si le fichier n'est trouvé dans aucun de ces éléments, il y aura une erreur (Class not found exception).

La seconde façon de préciser le CLASSPATH est de définir une variable d'environnement système. Sous Linux :

export CLASSPATH="chemin/vers/une/premiere/bibliotheque.jar:chemin/vers_une_autre/bibliotheque.jar"

Sous Windows :

SET "CLASSPATH=X:\chemin\vers\une\premiere\bibliotheque.jar;Y:\chemin\vers_une_autre\bibliotheque.jar"

Attention à ne pas confondre java -jar fichier.jar et java -cp fichier.jar, la première commande permet de lancer le programme qui se trouve dans fichier.jar et fonctionne ; la seconde précise que des classes peuvent être chargée depuis fichier.jar mais oublie de préciser quelle classe il faut lancer : java indiquera qu'un paramètre est manquant. Enfin, sachez que vous pouvez remplacer « -classpath » par « -cp ».

jar[modifier | modifier le wikicode]

L'outil jar permet de regrouper les classes (fichiers *.class) et ressources d'une application en une seule archive exécutable. Cette archive est au format ZIP mais possède l'extension .jar. Dans cette archive, un répertoire spécial situé à la racine nommé META-INF contient des fichiers d'information et de configuration pour la machine virtuelle Java, dont notamment le fichier MANIFEST.MF (fichier manifest, MF = Meta File).

Une archive JAR peut être exécutable si la classe principale (contenant une méthode statique nommée main) de l'application est spécifiée dans ce fichier MANIFEST.MF. Dans ce cas, l'application peut se lancer avec la commande suivante :

java -jar chemin_de_l_archive.jar ...arguments passés à l'application si besoin...

Ce fichier manifest est au format texte. Exemple :

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 19.1-b02 (Sun Microsystems Inc.)
Main-Class: org.wikibooks.fr.ApplicationExemple
Class-Path: .

Il possède différents champs. Chaque champ possède un nom, suivi de deux-points et de sa valeur. Si une valeur est longue, elle peut être répartie sur plusieurs lignes, chaque ligne additionnelle commençant alors par au moins un caractère espace.

Pour plus de détails sur les fichiers manifest voir http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html

Logo

Le champ Class-Path dans une archive JAR diffère du paramètre classpath passé aux outils Java :

  • Il ne peut contenir que des chemins relatifs à d'autres archives Java (*.jar) ; les répertoires ne sont pas supportés ;
  • Le séparateur est un caractère espace. Les fichiers référencés ne peuvent donc en contenir dans leur nom.

Pour créer une archive JAR à partir d'un répertoire contenant les classes et ressources (les sous-répertoires devant correspondre aux packages), et d'un fichier texte pour le fichier manifest :

jar cfm mon_archive.jar mon_manifest.txt -C répertoire .

Quel que soit le nom et l'extension du fichier source pour le manifest, il sera nommé MANIFEST.MF dans l'archive.

Les arguments de la commande sont décrits ci-dessous :

cfm
Une série de caractères dont le premier spécifie l'action principale :
  • c Créer une archive (Create).
  • t Afficher le contenu de l'archive (Table of content).
  • x Extraire les fichiers de l'archive (eXtract files).
  • u Mettre à jour l'archive existante (Update archive).
Les caractères suivants donne l'ordre des arguments qui suivent :
  • f Le nom du fichier archive (archive File).
  • m Le nom du fichier manifest à utiliser (Manifest file).
mon_archive.jar
Le nom du fichier archive.
mon_manifest.txt
Le nom du fichier manifest à utiliser.
-C répertoire
Précise le chemin du répertoire pour les chemins relatifs
.
Inclus le fichier spécifié (. désignant le répertoire courant sous la plupart des systèmes d'exploitation).

Eclipse possède une interface interactive pour générer un fichier JAR à partir des classes d'un projet Java, ou d'une configuration d'exécution.

javadoc[modifier | modifier le wikicode]

L'outil javadoc est le générateur de documentation, qui génère automatiquement de la documentation à partir des commentaires du code source.

Voir le chapitre sur les commentaires pour plus de détails sur l'outil et son utilisation.

jdb[modifier | modifier le wikicode]

le débogueur

javah[modifier | modifier le wikicode]

javah permet de générer un fichier d'en-tête C (*.h) contenant la déclaration des fonctions correspondantes aux méthodes natives de la classe compilée spécifiée.

javah -classpath directory-list classname

javap[modifier | modifier le wikicode]

javap permet de lister les membres et désassembler la classe compilée spécifiée.

javap -c -classpath directory-list classname

Options[modifier | modifier le wikicode]

-help
--help
-?
Afficher les options possibles.
-version
Information de version.
-v
-verbose
Afficher toutes les informations supplémentaires.
-l
Afficher les numéros de ligne et les tables de variables locales.
-public
N'afficher que les classes et membres publics.
-protected
Afficher les classes et membres publics ou protégés.
-package
Afficher les classes et membres publics, protégés ou paquetage (par défaut).
-p
-private
Afficher toutes les classes et tous les membres.
-c
Désassembler le code.
-s
Afficher les signatures des types internes.
-sysinfo
Afficher les informations systèmes (chemin, taille, date, MD5) des classes traitées.
-constants
Afficher les constantes finales et statiques.
-classpath chemin
-cp chemin
Spécifier le chemin où trouver les classes.
-bootclasspath chemin
Redéfinir le chemin des classes bootstrap.

Exemple avec désassemblage du code[modifier | modifier le wikicode]

La classe désassemblée dans cet exemple est produite à partir de ce fichier source :

package org.wikibooks.fr;

/**
 * Une classe simple à désassembler.
 * @author fr.wikibooks.org
 */
public class Addition
{
	public static Integer somme(Integer a, Integer b)
	{
		if (a==null) return b;
		if (b==null) return a;
		return a + b;
	}

	public static void main(String[] args)
	{
		// null équivaut à 0 pour la méthode somme
		System.out.println("Somme 1+2 = "+somme(1,2));    // -> 3
		System.out.println("Somme  +2 = "+somme(null,2)); // -> 2
	}
}

L'option verbose permet d'afficher toutes les informations sur le fichier .class :

> javap -cp W:\Programme\TestJava\bin -v org.wikibooks.fr.Addition
Classfile /W:/Programme/TestJava/bin/org/wikibooks/fr/Addition.class
  Last modified 31 mai 2022; size 1117 bytes
  MD5 checksum 0a72b766cde42eff71b4b8f7f4a67266
  Compiled from "Addition.java"
public class org.wikibooks.fr.Addition
  SourceFile: "Addition.java"
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Class              #2             //  org/wikibooks/fr/Addition
   #2 = Utf8               org/wikibooks/fr/Addition
   #3 = Class              #4             //  java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Methodref          #3.#9          //  java/lang/Object."<init>":()V
   #9 = NameAndType        #5:#6          //  "<init>":()V
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lorg/wikibooks/fr/Addition;
  #14 = Utf8               somme
  #15 = Utf8               (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;
  #16 = Methodref          #17.#19        //  java/lang/Integer.intValue:()I
  #17 = Class              #18            //  java/lang/Integer
  #18 = Utf8               java/lang/Integer
  #19 = NameAndType        #20:#21        //  intValue:()I
  #20 = Utf8               intValue
  #21 = Utf8               ()I
  #22 = Methodref          #17.#23        //  java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
  #23 = NameAndType        #24:#25        //  valueOf:(I)Ljava/lang/Integer;
  #24 = Utf8               valueOf
  #25 = Utf8               (I)Ljava/lang/Integer;
  #26 = Utf8               a
  #27 = Utf8               Ljava/lang/Integer;
  #28 = Utf8               b
  #29 = Utf8               StackMapTable
  #30 = Utf8               main
  #31 = Utf8               ([Ljava/lang/String;)V
  #32 = Fieldref           #33.#35        //  java/lang/System.out:Ljava/io/PrintStream;
  #33 = Class              #34            //  java/lang/System
  #34 = Utf8               java/lang/System
  #35 = NameAndType        #36:#37        //  out:Ljava/io/PrintStream;
  #36 = Utf8               out
  #37 = Utf8               Ljava/io/PrintStream;
  #38 = Class              #39            //  java/lang/StringBuilder
  #39 = Utf8               java/lang/StringBuilder
  #40 = String             #41            //  Somme 1+2 =
  #41 = Utf8               Somme 1+2 =
  #42 = Methodref          #38.#43        //  java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
  #43 = NameAndType        #5:#44         //  "<init>":(Ljava/lang/String;)V
  #44 = Utf8               (Ljava/lang/String;)V
  #45 = Methodref          #1.#46         //  org/wikibooks/fr/Addition.somme:(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;
  #46 = NameAndType        #14:#15        //  somme:(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;
  #47 = Methodref          #38.#48        //  java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
  #48 = NameAndType        #49:#50        //  append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
  #49 = Utf8               append
  #50 = Utf8               (Ljava/lang/Object;)Ljava/lang/StringBuilder;
  #51 = Methodref          #38.#52        //  java/lang/StringBuilder.toString:()Ljava/lang/String;
  #52 = NameAndType        #53:#54        //  toString:()Ljava/lang/String;
  #53 = Utf8               toString
  #54 = Utf8               ()Ljava/lang/String;
  #55 = Methodref          #56.#58        //  java/io/PrintStream.println:(Ljava/lang/String;)V
  #56 = Class              #57            //  java/io/PrintStream
  #57 = Utf8               java/io/PrintStream
  #58 = NameAndType        #59:#44        //  println:(Ljava/lang/String;)V
  #59 = Utf8               println
  #60 = String             #61            //  Somme  +2 =
  #61 = Utf8               Somme  +2 =
  #62 = Utf8               args
  #63 = Utf8               [Ljava/lang/String;
  #64 = Utf8               SourceFile
  #65 = Utf8               Addition.java
{
  public org.wikibooks.fr.Addition();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 7: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lorg/wikibooks/fr/Addition;

  public static java.lang.Integer somme(java.lang.Integer, java.lang.Integer);
    descriptor: (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: ifnonnull     6
         4: aload_1
         5: areturn
         6: aload_1
         7: ifnonnull     12
        10: aload_0
        11: areturn
        12: aload_0
        13: invokevirtual #16                 // Method java/lang/Integer.intValue:()I
        16: aload_1
        17: invokevirtual #16                 // Method java/lang/Integer.intValue:()I
        20: iadd
        21: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        24: areturn
      LineNumberTable:
        line 11: 0
        line 12: 6
        line 13: 12
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      25     0     a   Ljava/lang/Integer;
            0      25     1     b   Ljava/lang/Integer;
      StackMapTable: number_of_entries = 2
           frame_type = 6 /* same */
           frame_type = 5 /* same */


  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=4, locals=1, args_size=1
         0: getstatic     #32                 // Field java/lang/System.out:Ljava/io/PrintStream;
         3: new           #38                 // class java/lang/StringBuilder
         6: dup
         7: ldc           #40                 // String Somme 1+2 =
         9: invokespecial #42                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
        12: iconst_1
        13: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        16: iconst_2
        17: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        20: invokestatic  #45                 // Method somme:(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;
        23: invokevirtual #47                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
        26: invokevirtual #51                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        29: invokevirtual #55                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        32: getstatic     #32                 // Field java/lang/System.out:Ljava/io/PrintStream;
        35: new           #38                 // class java/lang/StringBuilder
        38: dup
        39: ldc           #60                 // String Somme  +2 =
        41: invokespecial #42                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
        44: aconst_null
        45: iconst_2
        46: invokestatic  #22                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        49: invokestatic  #45                 // Method somme:(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;
        52: invokevirtual #47                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
        55: invokevirtual #51                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        58: invokevirtual #55                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        61: return
      LineNumberTable:
        line 19: 0
        line 20: 32
        line 21: 61
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      62     0  args   [Ljava/lang/String;
}

Informations générales[modifier | modifier le wikicode]

public class org.wikibooks.fr.Addition
  SourceFile: "Addition.java"
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER

La première partie indique la version de java utilisée pour compiler la classe (52.0 supportée par Java 8). La classe est publique (ACC_PUBLIC) et a une classe de base (ACC_SUPER) ; seule la classe java.lang.Object n'en a pas.

Pool de constantes[modifier | modifier le wikicode]

Les constantes litérales sont regroupées en un seul endroit du fichier de classe et numérotées. Elles proviennent du code source mais aussi des constantes implicites utilisées en interne, comme par exemple le nom de la classe de base java/lang/Object quand aucune n'est spécifiée explicitement.

Constant pool:
   #1 = Class              #2             //  org/wikibooks/fr/Addition
   #2 = Utf8               org/wikibooks/fr/Addition
   #3 = Class              #4             //  java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Methodref          #3.#9          //  java/lang/Object."<init>":()V
   #9 = NameAndType        #5:#6          //  "<init>":()V

Chaque constante a un type (Class, Utf8, Methodref) et une ou deux valeurs associés. La valeur peut faire référence à d'autres constantes définies ailleurs, auquel cas la référence est suivi d'un commentaire donnant la valeur référencée.

Quelques types de constantes
Type Description
Utf8 Chaîne de caractères encodées en UTF-8.
String Référence à une chaîne de caractères (Utf8) initialisant un objet de type java.lang.String.
Class Référence à une chaîne de caractères (Utf8) donnant un nom de classe.
NameAndType Références à une chaîne de caractères (Utf8) donnant un nom de membre et à une autre chaîne de caractères donnant la signature de son type.
Methodref Références à une classe (Class) et un de ses membres (NameAndType) méthode de la classe.
Fieldref Références à une classe (Class) et un de ses membres (NameAndType) attribut de la classe.


Voir aussi[modifier | modifier le wikicode]