Java-code compileren

De JDT-plugins bevatten een incrementeel en een batchcompileerprogramma voor het bouwen van CLASS-bestanden op basis van Java-broncode. Door het compileerprogramma wordt geen directe API geleverd. Deze wordt als builder voor Java-projecten geïnstalleerd. De compilatie wordt gestart met standaardbouwmechanismen van het platform.

Het bouwmechanisme van het platform wordt uitvoerig beschreven in Incrementele projectbuilders.

Code compileren

U kunt de Java-bronbestanden van projecten met code compileren door middel van API.

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

Met de bovenstaande code wordt de incrementele Java-projectbuilder opgeroepen (samen met andere incrementele projectbuilders die aan de bouwspecificatie van het project zijn toegevoegd). De gegenereerde CLASS-bestanden worden naar de aangewezen uitvoermap geschreven. Aanvullende resourcebestanden worden ook naar de uitvoermap gekopieerd.  

Voor volledige als batch verwerkte bouwtaken geldt dat alle CLASS-bestanden in de uitvoermap mogelijk worden gewist om verouderde bestanden te voorkomen. U kunt dit gedrag beheren met een bouwoptie (CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER). Standaard worden de bestanden in de uitvoermap gewist. Tenzij de optie opnieuw wordt ingesteld, moet u ervoor zorgen dat u alle CLASS-bestanden waarvoor u niet over bijbehorende bronbestanden beschikt in een aparte klassenbestandsmap van het klassenpad plaatst en niet in de uitvoermap.

U kunt de incrementele en batchbuilders configureren met andere opties om de resources op te geven die naar de uitvoermap moeten worden gekopieerd. In het volgende voorbeeld ziet u hoe u een resourcefilter kunt instellen, zodat IGNORE-bestanden en mappen met de naam 'META-INF' niet naar de uitvoermap worden gekopieerd:

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

Bestandsnamen worden uitgefilterd als ze met een van de opgegeven zoekreeksen overeenkomen. Mappen worden uitgefilterd als de namen van de mappen overeenkomen met opgegeven mapnamen die op een padscheidingsteken eindigen.

De incrementele en batchbuilders kunt u ook zodanig configureren dat slechts één foutmelding wordt gegenereerd als CLASSPATH-bestanden fouten bevatten. Deze optie wordt standaard toegepast en voorkomt dat talrijke foutmeldingen worden gegenereerd. Raadpleeg Opties van de builder voor een volledig overzicht van de opties voor het bouwprogramma en de standaardwaarden van de opties.

U kunt het compileerprogramma ook configureren met behulp van JavaCore-opties. Zo kunt u bijvoorbeeld de severity definiëren die moet worden toegepast op verschillende fouten die tijdens de compilatie optreden. Raadpleeg Opties van het compileerprogramma voor een volledig overzicht van de opties voor het compileerprogramma en de standaardwaarden van de opties.

Als u de opties met code configureert, moet u het bereik van de opties aangeven. U wilt een resourcefilter bijvoorbeeld alleen op een bepaald project toepassen.

   
   Hashtable options = myProject.getOptions(false);  // alleen de opties van dit project ophalen
   options.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, "*.ignore,META-INF/");
   myProject.setOptions(options);

Het batchcompileerprogramma gebruiken

Het batchcompileerprogramma zoeken

De klasse van het batchcompileerprogramma bevindt zich in de interne klassen van de JDT Core-plugin. De naam van de klasse luidt org.eclipse.jdt.internal.compiler.batch.Main. De klasse is opgenomen in plugins/org.eclipse.jdt.core_3.2.0.jar. Vanaf 3.2 kunt u de klasse ook afzonderlijk downloaden. De naam van het bestand is ecj.jar. Bovendien is de bijbehorende broncode verkrijgbaar. Als u deze wilt ophalen, gaat u naar de downloadpagina en zoekt u naar het gedeelte JDT Core Batch Compiler. Het JAR-bestand bevat het batchcompileerprogramma en de Ant-adapter javac.

U kunt het dus als zelfstandige toepassing en in een Ant-build buiten Eclipse gebruiken.

Het batchcompileerprogramma uitvoeren

Overzicht van beschikbare opties

De opties die van een oranje achtergrond zijn voorzien, zijn optioneel.

Naam Gebruik
Klassenpadopties
-bootclasspath <dir 1>;<dir 2>;...;<dir P> Dit is een lijst met directory's of JAR-bestanden waarmee de CLASS-bestanden voor het compileerprogramma startbaar kunnen worden gemaakt. Standaard worden de bibliotheken van de actieve VM gebruikt. Gebruik het padscheidingsteken van het platform om de items van elkaar te scheiden.
Voor elke directory en elk bestand kunnen toegangsregels voor typen worden ingesteld tussen '[' en ']'.
-cp
-classpath <dir 1>;<dir 2>;...;<dir P>
Dit is een lijst met directory's of JAR-bestanden voor het compileren van de bronbestanden. De standaardwaarde is de waarde van de eigenschap "java.class.path". Gebruik het padscheidingsteken van het platform om de items van elkaar te scheiden.
Voor elke directory en elk bestand kunnen toegangsregels voor typen worden ingesteld tussen '[' en ']' (bijv. [-X] om geen toegang tot het type X te verlenen, [~X] om de toegang tot het type X af te raden, [+p/X:-p/*] om geen toegang tot alle typen van het pakket p te verlenen, behalve tot p/X).
-extdirs <dir 1>;<dir 2>;...;<dir P> Dit is een lijst met directory's voor het opgeven van de locatie van uitbreidende ZIP- of JAR-bestanden. Gebruik het padscheidingsteken van het platform om de items van elkaar te scheiden.
-endorseddirs <dir 1>;<dir 2>;...;<dir P> Dit is een lijst met directory's voor het opgeven van de locatie van goedgekeurde ZIP- of JAR-bestanden. Gebruik het padscheidingsteken van het platform om de items van elkaar te scheiden.
-sourcepath <dir 1>;<dir 2>;...;<dir P> Dit is een lijst met directory's waarin de bronbestanden zich bevinden. Gebruik het padscheidingsteken van het platform om de items van elkaar te scheiden.
Voor elke directory kunnen toegangsregels voor typen worden ingesteld tussen '[' en ']'.
-d <dir 1>|none Dit is de directory waarin de gegenereerde CLASS-bestanden moeten worden geplaatst. Als u de optie weglaat, wordt geen pakketdirectorystructuur gemaakt.
Gebruik -d none als u helemaal geen CLASS-bestand wilt genereren.
-encoding <coderingsnaam> Hiermee geeft u de standaard coderingsindeling van de broncode op. U kunt een aangepaste codering ook per bestand opgeven door [<coderingsnaam>] achter de namen van de invoerbestanden en -mappen te plaatsen (bijvoorbeeld X.java[utf8]).
Compatibiliteitsopties
-target 1.1|1.2|1.3|1.4|1.5|5|5.0|1.6|6|6.0 De doelinstelling voor de CLASS-bestanden. Geldige waarden:
  • 1.1 (hoofdversie: 45, subversie: 3)
  • 1.2 (hoofdversie: 46, subversie: 0)
  • 1.3 (hoofdversie: 47, subversie: 0)
  • 1.4 (hoofdversie: 48, subversie: 0)
  • 1.5, 5 of 5.0 (hoofdversie: 49, subversie: 0)
  • 1.6, 6 of 6.0 (hoofdversie: 50, subversie: 0)
Standaardwaarden:
  • 1.1 in de werkstand -1.3
  • 1.2 in de werkstand -1.4
  • 1.5 in de werkstand -1.5
  • 1.6 in de werkstand -1.6
-1.3 Compatibiliteitsniveau instellen op 1.3. Impliciet: -source 1.3 -target 1.1.
-1.4 Compatibiliteitsniveau instellen op 1.4 (standaard). Impliciet: -source 1.3 -target 1.2.
-1.5 Compatibiliteitsniveau instellen op 1.5. Impliciet: -source 1.5 -target 1.5.
-1.6 Compatibiliteitsniveau instellen op 1.6. Impliciet: -source 1.6 -target 1.6.
-source 1.3|1.4|1.5|5|5.0|1.6|6|6.0 Hiermee kunt u het bronniveau opgeven dat door het compileerprogramma wordt gehanteerd.
Geldige waarden:
  • 1.3
  • 1.4
  • 1.5, 5 of 5.0
  • 1.6, 6 of 6.0
Standaardwaarden:
  • 1.3 in de werkstand -1.3
  • 1.3 in de werkstand -1.4
  • 1.5 in de werkstand -1.5
  • 1.6 in de werkstand -1.6
In 1.4 wordt assert als sleutelwoord beschouwd. In 1.5 en 1.6 worden enum en assert als sleutelwoorden beschouwd.
Waarschuwingsopties
-warn:
allDeprecation
allJavadoc
assertIdentifier
boxing
charConcat
conditionAssign
constructorName
dep-ann
deprecation
discouraged
emptyBlock
enumSwitch
fallthrough
fieldHiding
finalBound
finally
forbidden
hiding
incomplete-switch
indirectStatic
intfAnnotation
intfNonInherited
javadoc
localHiding
maskedCatchBlocks
nls
noEffectAssign
null
over-ann
paramAssign
pkgDefaultMethod
raw
semicolon
serial
specialParamHiding
static-access
staticReceiver
suppress
synthetic-access
syntheticAccess
tasks(<task1>|...|<taskN>)
typeHiding
unchecked
unnecessaryElse
unqualified-field-access
unqualifiedField
unused
unusedArgument
unusedImport
unusedLabel
unusedLocal
unusedPrivate
unusedThrown
uselessTypeCheck
varargsCast
warningToken
Waarschuwingsniveau instellen.
bijvoorbeeld -warn:unusedLocal,deprecation

De standaardwaarden worden rood afgebeeld.

    -warn:none                                  alle waarschuwingen uitschakelen
    -warn:<door , gescheiden waarschuwingen>    de vermelde waarschuwingen inschakelen
    -warn:+<door , gescheiden waarschuwingen>   aanvullende waarschuwingen inschakelen
    -warn:-<door , gescheiden waarschuwingen>   specifieke waarschuwingen uitschakelen
allDeprecation depreciëren, zelfs in gedeprecieerde code
allJavadoc ongeldige of ontbrekende javadoc
assertIdentifier gebruik van assert als identificatie
boxing conversie voor automatisch in kader plaatsen
charConcat gebruik van een niet expliciet naar een tekenreeks geconverteerde tekenarray in een samenvoeging
conditionAssign mogelijk onbedoelde booleaanse toewijzing
constructorName methode zonder constructornaam
dep-ann ontbrekende @Deprecated-annotatie
deprecation gebruik van gedeprecieerd type of lid buiten gedeprecieerde code
discouraged typen die overeenkomen met een regel voor niet-aanbevolen toegang
emptyBlock niet-gedocumenteerde lege blokken
enumSwitch,
incomplete-switch
onvolledige enum switch-instructie
fallthrough mogelijk niet-afgebakende case-instructie
fieldHiding verborgen variabele door veld
finalBound typeparameter met eindgrens
finally onjuiste beëindiging van finally-blok
forbidden typen die overeenkomen met een regel voor niet-verleende toegang
hiding macro voor fieldHiding, localHiding, typeHiding en maskedCatchBlock
indirectStatic indirecte verwijzing naar statisch lid
intfAnnotation annotatietype gebruikt als superinterface
intfNonInherited compatibiliteit met niet-overgenomen interfacemethode
javadoc ongeldige javadoc
localHiding verborgen variabele door lokale variabele
maskedCatchBlocks verborgen catch-blok
nls tekenreeksliteralen die niet van het type nls zijn (ontbrekende tags //$NON-NLS-<n>)
noEffectAssign toewijzing zonder effect
null ontbrekende of overbodige controle op null
over-ann ontbrekende @Override-annotatie
paramAssign toewijzing aan parameter
pkgDefaultMethod poging tot vervanging van standaardmethode van pakket
raw onbewerkt type (in plaats van geparametriseerd type)
semicolon onnodige puntkomma of lege instructie
serial ontbrekend serialVersionUID
specialParamHiding verborgen veld door constructor of setter-parameter
static-access macro voor indirectStatic en staticReceiver
staticReceiver ophalen van statisch veld of aanroepen van statische methode door niet-statische ontvanger
suppress @SuppressWarnings inschakelen
syntheticAccess,
synthetic-access
synthetische toegang voor binnenklasse
tasks ondersteuning voor tasks-tags in broncode inschakelen
typeHiding verborgen type door typeparameter
unchecked niet-gecontroleerde bewerking van type
unnecessaryElse onnodige else-clausule
unqualified-field-access,
unqualifiedField
ongekwalificeerde verwijzing naar veld
unused macro voor unusedArgument, unusedImport, unusedLabel, unusedLocal, unusedPrivate en unusedThrown
unusedArgument niet-gebruikt methode-argument
unusedImport niet-gebruikte importeerverwijzing
unusedLabel niet-gebruikt label
unusedLocal niet-gebruikte lokale variabele
unusedPrivate niet-gebruikte declaratie van besloten lid
unusedThrown niet-gebruikte declaratie van verworpen uitzondering
uselessTypeCheck onnodige omzettings-/instanceof-bewerking
varargsCast varargs-parameter zonder expliciete omzetting
warningToken niet-afgehandeld waarschuwingstoken in @SuppressWarnings

-nowarn Geen waarschuwing (gelijk aan -warn:none)
-deprecation Gelijk aan -warn:deprecation.
Foutopsporingsopties
-g[:none|:lines,vars,source] Het niveau van de foutopsporingskenmerken instellen.
-g Alle foutopsporingsgegevens (gelijk aan -g:lines,vars,source)
-g:none Geen foutopsporingsgegevens
-g:[lines,vars,source] Selectieve foutopsporingsgegevens
-preserveAllLocals Het compileerprogramma expliciet verzoeken alle lokale variabelen te behouden voor foutopsporingsdoeleinden. Als u deze optie weglaat, worden niet-gebruikte lokale variabelen door het compileerprogramma verwijderd.
Genegeerde opties (voor compatibiliteit met javac-opties)
-J<optie> optie doorgeven aan de Virtual Machine
-X<optie> niet-standaard optie doorgeven. -Xemacs wordt niet genegeerd.
-X niet-standaard opties afdrukken en afsluiten
-O optimaliseren voor uitvoeringstijd
Geavanceerde opties
@<bestand> Opdrachtregelargumenten ophalen uit bestand.
-maxProblems <n> Maximumaantal problemen per compilatie-eenheid (standaard 100).
-log <bestandsnaam> Een logboekbestand opgeven waarnaar alle uitvoer van het compileerprogramma wordt weggeschreven. Gebruik deze optie vooral wanneer u fouten met het batchcompileerprogramma wilt opsporen of wanneer u een bestand wilt ophalen waarin alle fouten en waarschuwingen van een als batch verwerkte bouwbewerking zijn opgeslagen. Als de extensie .xml is, wordt het gegenereerde logboek als XML-bestand opgeslagen.
-Xemacs Fout- en waarschuwingsberichten in emacs-stijl in de console en gewone logboeken afbeelden. Deze optie is niet van invloed op XML-logboeken. Als deze optie actief is, ziet het bericht:
2. WAARSCHUWING in /workspace/X.java
(op regel 8)...

er als volgt uit:
/workspace/X.java:8: waarschuwing: de methode...
-proceedOnError Compilatie voortzetten bij fouten en klassenbestanden met foutieve methoden of typen dumpen. Stel deze optie alleen in als u de toepassing wilt kunnen uitvoeren met resterende fouten.
-verbose Opgevraagde/verwerkte compilatie-eenheden wegschrijven naar de console of het logboekbestand (mits opgegeven).
-referenceInfo Verwijzingsgegevens berekenen. Stel deze optie alleen in bij verwijzingen naar het bouwprogramma. Anders zijn de verwijzingsgegevens overbodig.
-progress Voortgang afbeelden (alleen met -log).
-time Snelheidsinformatie afbeelden.
-noExit System.exit(n) niet aanroepen bij beëindiging van de compilatie (n=0 bij geen fouten).
-repeat <n> Compilatieproces <n> keer herhalen (perf-analyse).
-inlineJSR JSR-bytecode integreren (impliciet met target >= 1.5).
-enableJavadoc Verwijzingen als interne javadoc-verwijzingen beschouwen.
Help-opties
-? -help Het Help-bericht afbeelden.
-v -version Het buildnummer van het compileerprogramma afbeelden. Gebruik deze optie vooral om fouten te rapporteren.
-showversion Het buildnummer van het compileerprogramma afbeelden en doorgaan. Gebruik deze optie vooral om fouten te rapporteren.

Voorbeelden

d:\temp -classpath rt.jar -time -g -d d:/tmp Alle bronbestanden in d:\temp en de submappen worden gecompileerd. Het klassenpad is rt.jar. Alle foutopsporingskenmerken worden gegenereerd en alle gegenereerde CLASS-bestanden worden in d:\tmp opgeslagen. De snelheid van het compileerprogramma wordt na afloop van de batchverwerking afgebeeld.
d:\temp\Test.java -classpath d:\temp;rt.jar -g:none Alleen Test.java en afhankelijke bestanden (indien aanwezig) worden gecompileerd. De afhankelijke bestanden worden uit d:\temp opgehaald. Het klassenpad is d:\temp, gevolgd door rt.jar. Alle benodigde klassen worden dus eerst opgezocht in d:\temp en vervolgens in rt.jar. Er worden geen foutopsporingskenmerken gegenereerd en alle CLASS-bestanden worden in d:\temp gedumpt.

De javac-adapter voor Ant gebruiken

U kunt het Eclipse-compileerprogramma in een Ant-script gebruiken met de javac-adapter. U hoeft dan alleen de eigenschap build.compiler te definiëren in het script. Een klein voorbeeld:
<?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> 
De syntaxis voor de javac-taak van Ant kunt u vinden in de documentatie. De huidige adapter ondersteunt alle versies van de javac-taak tussen 1.4.1 en 1.6.5.

Gebruikt u een latere versie dan 1.5.0, dan kunt u de geneste compileerparameter gebruiken om compileerspecifieke opties op te geven.

...
<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>
    <compilerarg compiler="org.eclipse.jdt.core.JDTCompilerAdapter" line="-1.5 -warn:+boxing"/>
</javac>		
...

Om compileerafhankelijke scripts te voorkomen, is het raadzaam het compileerargument in te stellen op org.eclipse.jdt.core.JDTCompilerAdapter. Anders is het script alleen geschikt voor het Eclipse-compileerprogramma. Is de optie wel ingesteld, dan wordt de geneste compileeroptie genegeerd als de naam verschilt van de compileerprogrammanaam uit de eigenschap build.compiler.

Problemen vaststellen

JDT Core definieert een gespecialiseerd merkteken (merktekentype "org.eclipse.jdt.core.problem") om compilatieproblemen aan te duiden. U kunt door het compileerprogramma herkende codeproblemen vaststellen door het standaardmerktekenprotocol van het platform te gebruiken. Raadpleeg Resourcemerktekens voor meer informatie.

In het volgende fragment worden alle merktekens van Java-problemen in een compilatie-eenheid opgespoord.

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

Java-probleemmerktekens worden door het bouwprogramma van het Java-project beheerd. Zodra een fout wordt opgelost en de Java-broncode opnieuw wordt gecompileerd, worden de merktekens gewist.

De waarde van het probleem-ID wordt ingesteld op een van de constanten die in IProblem zijn gedefinieerd. Het probleem-ID is onveranderlijk, maar het probleembericht kan worden vertaald. De constanten die in IProblem zijn gedefinieerd, zijn zelfbeschrijvend.

U moet een implementatie van IProblemRequestor definiëren om de problemen tijdens een Java-bewerking te kunnen verzamelen. U kunt probleemherkenning instellen voor actieve exemplaren als IProblemRequestor is opgegeven. Om dit te bewerkstelligen, kunt u de methode reconcile gebruiken. Hier volgt een voorbeeld:

  ICompilationUnit unit = ..; // een compilatie-eenheid ophalen
			
  // aanvraaginstructie voor probleemverzameling maken
  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; } // problemen herkennen indien actief
  };
    
  // werkexemplaar gebruiken om foutieve broncode vast te houden
  ICompilationUnit workingCopy = unit.getWorkingCopy(new WorkingCopyOwner() {}, problemRequestor, null);
  ((IOpenable)workingCopy).getBuffer().setContents("public class X extends Zork {}");

  // in overeenstemming brengen initiëren
  workingCopy.reconcile(NO_AST, true, null, null);
U kunt een actie voor de gerapporteerde problemen toevoegen met de methode acceptProblem(IProblem). In dit voorbeeld wordt gerapporteerd dat Zork (met ID IProblem.SuperclassNotFound) niet kan worden omgezet of geen geldige superklasse is.

Waarschuwingen onderdrukken met SuppressWarnings

Java 5.0 biedt de mogelijkheid compilatiewaarschuwingen van een subset van een compilatie-eenheid te onderdrukken met de annotatie java.lang.SuppressWarning.

	@SuppressWarning("unused") public void foo() {
		String s;
	}

Als de annotatie niet was toegepast, zou het compileerprogramma hebben gemeld dat de lokale variabele s helemaal niet wordt gebruikt. Met de annotatie wordt deze waarschuwing, die alleen lokaal voor de methode foo geldt, door het compileerprogramma genegeerd. Zo kunnen de waarschuwingen in andere locaties van dezelfde compilatie-eenheid of hetzelfde project behouden blijven.

Deze tokens kunnen met de annotatie SuppressWarning worden gebruikt: