Compilation de code Java

Les plug-in de JDT comprennent un compilateur Java incrémentiel et par lots qui sert à compiler des fichiers .class Java à partir d'un code source. Le compilateur ne fournit pas d'API directe. Il est installé comme compilateur dans les projets Java. La compilation est déclenchée au moyen des mécanismes de génération standard de la plateforme.

Le mécanisme de compilation de la plateforme est détaillé à la rubrique Compilateurs de projet incrémentiels.

Compilation du code

Grâce à l'API de compilation, vous pouvez compiler les fichiers source Java d'un projet par programme.

   IProject myProject;
   IProgressMonitor myProgressMonitor;
   myProject.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, myProgressMonitor);

Pour un projet Java, cette instruction appelle le compilateur de projet incrémentiel Java (avec les autres compilateurs de projet incrémentiels qui ont éventuellement été ajoutés à la spécification de compilation du projet). Les fichiers .class générés sont enregistrés dans le dossier de sortie indiqué. Les fichiers de ressources supplémentaires sont également copiés dans le dossier de sortie. 

Dans le cas d'une compilation par lots complète, tous les fichiers .class du dossier de sortie peuvent être vérifiés pour s'assurer qu'aucun fichier périmé ne sera trouvé. Cette opération est contrôlée par une option du compilateur de l'API principale de JDT (CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER).Par défaut, cette option vide les dossiers de sortie. A moins que l'option soit réinitialisée, vous devez veiller à placer tous les fichiers .class pour lesquels vous ne disposez pas des fichiers source correspondants dans un dossier de fichiers classe distinct sur le chemin de classe et non dans le dossier de sortie.

Les compilateurs incrémentiels et par lots peuvent être configurés avec d'autres options qui contrôlent les ressources copiées dans le dossier de sortie. L'exemple suivant montre comment configurer un filtre de ressources de sorte que les fichiers se terminant par '.ignore' et les dossiers nommés 'META-INF' ne soient pas copiés dans le dossier de sortie :

   Hashtable options = JavaCore.getOptions();
   options.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, "*.ignore,META-INF/");
   JavaCore.setOptions(options);

Les noms des fichiers sont filtrés s'ils correspondent à l'un des modèles spécifiés. Des dossiers entiers sont filtrés si leur nom correspond à l'un des noms de dossier spécifié se terminant par un séparateur de chemin.

Vous pouvez également configurer les compilateurs incrémentiels et de lots pour ne générer qu'une seule erreur lorsque le fichier .classpath contient des erreurs. Cette option est définie par défaut et élimine la spécification de plusieurs erreurs. Pour obtenir la liste complète des options relatives au compilateur et leurs valeurs par défaut, reportez-vous à la rubrique Options du compilateur de l'API principale de JDT.

Le compilateur peut être également configuré à l'aide des options JavaCore. Par exemple, vous pouvez définir la gravité devant être utilisée pour les différents types de problèmes rencontrés au cours de la compilation. Pour obtenir la liste complète des options relatives au compilateur et leurs valeurs par défaut, reportez-vous à la rubrique Options du compilateur de l'API principale de JDT.

Lors de la configuration par programme des options du compilateur, vous devez déterminer la portée de l'option. Par exemple, la configuration d'un filtre de ressources peut s'appliquer uniquement à un projet particulier. L'exemple suivant configure le même filtre de ressources que présenté précédemment, mais ne le définit que pour un projet individuel.

   
   Hashtable options = myProject.getOptions(false);  // obtention des options configurées dans ce projet uniquement
   options.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, "*.ignore,META-INF/");
   myProject.setOptions(options);

Utilisation de l'adaptateur Ant javac

Vous pouvez utiliser le compilateur Eclipse dans un script Ant utilisant l'adaptateur javac. Pour ce faire, il suffit de définir la propriété build.compiler dans votre script. En voici un petit exemple.
<?xml version="1.0" encoding="UTF-8" ?>
<project name="compile" default="main" basedir="../.">

	<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>

	<property name="root" value="${basedir}/src"/>

	<property name="destdir" value="d:/temp/bin" />

	<target name="main">
		<javac srcdir="${root}" destdir="${destdir}" debug="on" nowarn="on" extdirs="d:/extdirs" source="1.4">
		    <classpath>
		      <pathelement location="${basedir}/../org.eclipse.jdt.core/bin"/>
		    </classpath>
		</javac>		
	</target>
</project>
La syntaxe utilisée pour la tâche Ant javac se trouve dans la documentation sur les tâches Ant javac. L'adaptateur actuel prend en charge la tâche Ant Javac 1.4.1. La version 1.5 sera disponible lorsqu'Ant 1.5 sera publié.

Identification des problèmes

L'API principale (core) du JDT définit un marqueur spécialisé (type "org.eclipse.jdt.core.problem") pour indiquer les incidents de compilation. Pour découvrir par programme les problèmes détectés par le compilateur, vous devez utiliser le protocole de marqueurs standard de la plateforme. Pour plus d'informations sur l'utilisation des marqueurs, reportez-vous à la rubrique Marqueurs de ressources.

Le fragment de code suivant localise tous les marqueurs de problèmes Java dans une unité de compilation.

   public IMarker[] findJavaProblemMarkers(ICompilationUnit cu) 
      throws CoreException {
      IResource javaSourceFile = cu.getUnderlyingResource();
      IMarker[] markers = 
         javaSourceFile.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER,
            true, IResource.DEPTH_INFINITE);
   }

Les marqueurs de problèmes Java sont gérés par le compilateur de projet Java. Ils sont supprimés automatiquement à mesure que les problèmes sont résolus et que la source Java est recompilée.

La valeur de l'ID du problème est définie par l'une des constantes indiquées dans IProblem . L'ID du problème est fiable mais le message est traduit et peut par conséquent changer selon l'environnement local par défaut. La description des constantes définies dans IProblem est explicite.

Une implémentation d' IProblemRequestor doit être définie pour regrouper les incidents détectés lors d'une opération Java. Les copies de travail peuvent être adaptées à la détection des incidents si un élément IProblemRequestor a été fourni pour leur création. Pour ce faire, vous pouvez utiliser la méthode reconcile. Exemple :

  ICompilationUnit unit = ..; // obtention d'une unité de compilation
			
  // création d'un demandeur pour le regroupement des incidents détectés
  IProblemRequestor problemRequestor = new IProblemRequestor() {
    public void acceptProblem(IProblem problem) {
      System.out.println(problem.getID() + ": " + problem.getMessage());
    }
    public void beginReporting() {}
    public void endReporting() {}
    public boolean isActive() {	return true; } // détecte les incidents si actif
  };
    
  // utilisation de la copie de travail pour conserver la source contenant l'erreur
  IWorkingCopy workingCopy = (IWorkingCopy)unit.getWorkingCopy(null, null, problemRequestor);
  ((IOpenable)workingCopy).getBuffer().setContents("public class X extends Zork {}");

  // déclenchement de la réconciliation
  workingCopy.reconcile(true, null);
Vous pouvez ajouter une opération sur les incidents détectés dans la méthode acceptProblem(IProblem). Dans cet exemple, l'incident détecté est le suivant : Zork ne peut pas être résolu ou n'est pas une superclasse valide et son ID est IProblem.SuperclassNotFound.

Copyright IBM Corporation and others 2000, 2003. All Rights Reserved.