Kompilere Java-kode

JDT-plugin-moduler inneholder en trinnvis og satsvis Java-kompilator for bygging av *.class-filer for Java på grunnlag av kildekode. Det finnes ikke noe direkte API i kompilatoren. Den installeres som en bygger på Java-prosjekter. Kompilering utløses med plattformens standard byggemekanismer.

Plattformens standard byggemekanisme er beskrevet i detalj i Trinnvise prosjektbyggere.

Kompilere kode

Du kan programmatisk kompilere Java-kildefiler i et prosjekt med bygge-APIet.

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

For et Java-prosjekt aktiverer dette Javas trinnvise prosjektbygger (sammen med eventuelle andre trinnvise prosjektbyggere som er lagt til i prosjektets byggespesifikasjoner). De genererte *.class-filene skrives til definert utdatamappe. Andre ressursfiler kopieres også til utdatamappen. 

Ved full satsvis bygging kan alle *.class-filene i utdatamappen "renses" for å sikre at ingen filer forblir harske. Dette kontrolleres ved hjelp av en JDT-kjernebygger (CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER).  Standard for dette alternativet er å rense utdatamappene. Med mindre dette alternativet tilbakestilles, må du sørge for at du plasserer alle *.class-filer som du ikke har tilsvarende kildefiler for, i en egen klassefilmappe i klassebanen i stedet for i utdatamappen.

Trinnvise og satsvise byggere kan konfigureres med andre alternativer som styrer hvilke ressurser som kopieres til utdatamappen.  Eksempelet nedenfor viser hvordan du konfigurerer et ressursfilter slik at filer som slutter med '.ignore' og mapper kalt 'META-INF' ikke kopieres til utdatamappen.

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

Filnavn filtreres bort hvis de samsvarer med et av de oppgitte mønstrene. Hele mapper filtreres bort hvis navnet deres samsvarer med et av de oppgitte mappenavnene som slutter med et baneskilletegn.

Trinnvise og satsvise byggere kan også konfigureres til bare å generere enkeltfeil når *.classpath-filen har feil. Dette alternativet er definert som standard og utelukker en rekke feil.  Du finner en fullstendig liste over byggerrelaterte alternativer og deres standardverdier i Alternativer for JDT-kjernebygger.

Kompilatoren kan også konfigureres ved hjelp av JavaCore-alternativer. Du kan for eksempel definere alvorsgraden som skal brukes for forskjellige typer problemer som blir funnet under kompilering.  Du finner en fullstendig liste over kompilatorrelaterte alternativer og deres standardverdier i Alternativer for JDT-kjernekompilator.

Ved programmatisk konfigurering av alternativer for bygger eller kompilatoren må du bestemme virkeområdet til alternativet.  For eksempel kan konfigurering av et ressursfilter gjelde bare for et bestemt prosjekt:

   
   Hashtable options = myProject.getOptions(false);  // hent bare alternativer konfigurert i dette prosjektet
   options.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, "*.ignore,META-INF/");
   myProject.setOptions(options);

Bruke satsvis kompilator

Finne satsvis kompilator

Den satsvise kompilatorklassen befinner seg i de interne klassene til plugin-modulen for JDT-kjerne. Navnet på klassen er org.eclipse.jdt.internal.compiler.batch.Main. Den er pakket i plugins/org.eclipse.jdt.core_3.2.0.jar. Siden 3.2 har den også vært tilgjengelig som separat nedlasting. Navnet på filen er ecj.jar. Den tilhørende kilden er også tilgjengelig. Gå til nedlastingssiden og søk etter delen JDT Core Batch Compiler. Denne JAR-filen inneholder både den satsvise kompilatoren og javac ant-adapteren.

Dermed kan den brukes som en frittstående applikasjon, og innenfor et Ant-bygg utenfor Eclipse.

Kjøre satsvis kompilator

Hvilke alternativer er tilgjengelige?

Med oransje bakgrunn er dette de foreslåtte alternativene:

Navn Bruk
Klassebanealternativer
-bootclasspath <dir 1>;<dir 2>;...;<dir P> Dette er en liste over kataloger eller jar-filer som brukes til å primærlaste klassefilene som brukes av kompilatoren. Som standard brukes bibliotekene på VM som kjøres. Oppføringer atskilles med plattformens baneskilletegn.
Hver katalog eller fil kan angi tilgangsregler for typer mellom '[' og ']'.
-cp
-classpath <dir 1>;<dir 2>;...;<dir P>
Dette er en liste over kataloger eler jar-filer som brukes til å kompilere kildefilene. Standardverdien er verdien til egenskapen "java.class.path". Oppføringer atskilles med plattformens baneskilletegn.
Hver katalog eller fil kan angi tilgangsregler for typer mellom '[' og ']' (f.eks. [-X] for å forby tilgang til type X, [~X] for å fraråde tilgang til type X, [+p/X:-p/*] for å forby tilgang til alle typer i pakke p, men tillate tilgang til p/X).
-extdirs <dir 1>;<dir 2>;...;<dir P> Dette er en liste over kataloger som brukes til å angi plasseringen av zip-/jar-filer. Oppføringer atskilles med plattformens baneskilletegn.
-endorseddirs <dir 1>;<dir 2>;...;<dir P> Dette er en liste over kataloger som brukes til å angi plasseringen av støttede zip/jar-filer. Oppføringer atskilles med plattformens baneskilletegn.
-sourcepath <dir 1>;<dir 2>;...;<dir P> Dette er en liste over kataloger som brukes til å oppgi kildefilene. Oppføringer atskilles med plattformens baneskilletegn.
Hver katalog kan angi tilgangsregler for typer mellom '[' og ']'.
-d <dir 1>|none Denne brukes til å oppgi i hvilken katalog de genererte *.class-filene skal dumpes. Hvis den utelates, opprettes ingen pakkekatalogstruktur.
Hvis du ikke vil generere noen .class-filer, bruker du -d none.
-encoding <encoding name> Spesifiserer standard kildekodingsformat (tilpasset koding kan også spesifiseres for hver enkelt fil ved at hver inndatakildefil eller -mappenavn får [<kodingsnavn>] som suffiks, for eksempel X.java[utf8]).
Samsvarsalternativer
-target 1.1|1.2|1.3|1.4|1.5|5|5.0|1.6|6|6.0 Spesifiserer *.class-filmålets innstilling. Mulige alternativene er:
  • 1.1 (hovedversjon: 45 underordnet: 3)
  • 1.2 (hovedversjon: 46 underordnet: 0)
  • 1.3 (hovedversjon: 47 underordnet: 0)
  • 1.4 (hovedversjon: 48 underordnet: 0)
  • 1.5, 5 eller 5.0 (hovedversjon: 49 underordnet: 0)
  • 1.6, 6 eller 6.0 (hovedversjon: 50 underordnet: 0)
Standardverdier er:
  • 1.1 i -1.3-modus
  • 1.2 i -1.4-modus
  • 1.5 i -1.5-modus
  • 1.6 i -1.6-modus
-1.3 Definer samsvarsnivå til 1.3. Implisitt -source 1.3 -target 1.1.
-1.4 Definer samsvarsnivå til 1.4 (standard). Implisitt -source 1.3 -target 1.2.
-1.5 Definer samsvarsnivå til 1.5. Implisitt -source 1.5 -target 1.5.
-1.6 Definer samsvarsnivå til 1.6. Implisitt -source 1.6 -target 1.6.
-source 1.3|1.4|1.5|5|5.0|1.6|6|6.0 Dette brukes for å angi kildenivået som forventes av kompilatoren.
Mulige alternativene er:
  • 1.3
  • 1.4
  • 1.5, 5 eller 5.0
  • 1.6, 6 eller 6.0
Standardverdier er:
  • 1.3 i -1.3-modus
  • 1.3 i -1.4-modus
  • 1.5 i -1.5-modus
  • 1.6 i -1.6-modus
I 1.4 behandles assert som et nøkkelord. I 1.5 og 1.6 blir enum og assert behandlet som nøkkelord.
Advarselsalternativer
-warn:
allDeprecation
allJavadoc
assertIdentifier
ruting
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
Definer advarselsnivå.
f.eks. -warn:unusedLocal,deprecation

I rødt er standardverdiene:

    -warn:none                               deaktiver alle advarslerdisable all warnings     -warn:<warnings separated by ,>    aktiver nøyaktig de opplistede advarslene
    -warn:+<warnings separated by ,>   aktiver tilleggsadvarsler
    -warn:-<warnings separated by ,>   deaktiver spesifikke advarsler
allDeprecation Forelding selv inne i foreldet kode
allJavadoc Ugyldig eller manglende Javadoc
assertIdentifier Forekomst av assert brukt som identifikator
ruting Autorutingskonvertering
charConcat Når en tegnmatrise brukes i en strengsammensetning uten eksplisitt konvertering til streng
conditionAssign Mulig uheldig boolsk tildeling
constructorName Metode med konstruktørnavn
dep-ann Manglende @Deprecated-annotasjon
deprecation Bruk av foreldet type eller medlem utenfor foreldet kode
discouraged Bruk av typer som tilsvarer en frarådet tilgangsregel
emptyBlock Udokumentert tom blokk
enumSwitch,
incomplete-switch
Ufullstendig enum-bryter
fallthrough mulig fallthrough-tilfelle
fieldHiding Felt som skjuler en annen variabel
finalBound Typeparameter med finalBound (endelig bundet)
finally finally-blokk som ikke fullføres normalt
forbidden Bruk av typer som tilsvarer en forbudt tilgangsregel
hiding Makro for fieldHiding, localHiding, typeHiding og maskedCatchBlock
indirectStatic Indirekte referanse til statisk medlem
intfAnnotation Annotasjonstype brukt som supergrensesnitt
intfNonInherited Metodekompatibilitet ikke arvet fra grensesnitt
javadoc Ugyldig Javadoc
localHiding Lokal variabel skjuler en annen variabel
maskedCatchBlocks Skjult catch-blokk
nls Ikke-nls-strengkonstanter (mangler koder //$NON-NLS-<n>)
noEffectAssign tildeling uten virkning
null Manglende eller overflødig nullkontroll
over-ann Manglende @Override-annotasjon
paramAssign tildeling til en parameter
pkgDefaultMethod Forsøk på å overstyre package-default-metode
raw bruk av en ubehandlet type (i stedet for type med parameter)
semicolon Unødvendig semikolon eller tom setning
serial Manglende serialVersionUID
specialParamHiding Konstruktør eller setter-parameter skjuler et annet felt
static-access Makro for indirectStatic og staticReceiver
staticReceiver Hvis en ikke-statisk mottaker brukes til å hente et statisk felt eller kalle opp en statisk metode
suppress Aktiver @SuppressWarnings
syntheticAccess,
synthetic-access
Ved utførelse av syntetisk tilgang for indre klasse
tasks Aktiver støtte for tasks-koder i kildekode
typeHiding Typeparameter skjuler annen type
unchecked Usjekket typeoperasjon
unnecessaryElse Unødvendig else-ledd
unqualified-field-access,
unqualifiedField
Ukvalifisert referanse til felt
unused makro for unusedArgument, unusedImport, unusedLabel, unusedLocal, unusedPrivate og unusedThrown
unusedArgument Ubrukt metodeargument
unusedImport Ubrukt importreferanse
unusedLabel ubrukt etikett
unusedLocal Ubrukt lokal variabel
unusedPrivate Ubrukt privat medlemsdeklarasjon
unusedThrown Ubrukt deklarert kastet unntak
uselessTypeCheck Unødvendig cast/instanceof-operasjon
varargsCast varargs-argument trenger eksplisitt cast
warningToken Ubehandlet advarselssymbol i @SuppressWarnings

-nowarn Ingen advarsel (tilsvarer -warn:none)
-deprecation Tilsvarer -warn:deprecation.
Feilsøkingsalternativer
-g[:none|:lines,vars,source] Definer feilsøkingsattributtnivå
-g All feilsøkingsinfo (tilsvarer -g:lines,vars,source)
-g:none Ingen feilsøkingsinfo
-g:[lines,vars,source] Selektiv feilsøkingsinfo
-preserveAllLocals Be eksplisitt kompilatoren om å bevare alle lokale variabler (til feilsøkingsformål). Utelates denne, vil kompilatoren fjerne ubrukte lokale.
Ignorerte alternativer (for kompatibilitet med javac-alternativer)
-J<alternativ> overfør alternativ til den virtuelle maskinen
-X<alternativ> angi ikke-standard alternativ. -Xemacs blir ikke ignorert.
-X skriv ut ikke-standard alternativer og avslutt
-O optimaliser for utføringstid
Avanserte alternativer
@<file> Les kommandolinjeargumenter fra fil
-maxProblems <n> Maks antall problemer per kompileringsenhet (100 er standard)
-log <filnavn> Oppgi en loggfil der alle utdata fra kompilatoren dumpes. Dette er svært nyttig hvis du vil feilsøke satskompilatoren eller hente en fil som inneholder alle feil og advarsler fra en satsvis bygging. Hvis filtypen er .xml, vil den genererte loggen være en xml-fil.
-Xemacs Bruk emacs-stil for å presentere feil og advarselplasseringer i konsollen og regulære tekstlogger. XML-logger blir ikke påvirket av dette alternativet. Hvis dette alternativet er aktivert, vil meldingen:
2. WARNING in /workspace/X.java
(at line 8)...

vises som:
/workspace/X.java:8: warning: The method...
-proceedOnError Fortsett kompilering ved feil, idet klassefiler med problemmetoder eller problemtyper dumpes. Dette anbefales bare hvis du ønsker å kunne kjøre applikasjonen selv om det er gjenværende feil.
-verbose Skriv ut brukte/behandlede kompileringsenheter i konsollen eller loggfilen om spesifisert.
-referenceInfo Beregn referanseinfo. Nyttig bare om koblet til byggeren. Referanseinfo er ubrukelig ellers.
-progress Vis fremdrift (bare i -log-modus).
-time Vis hastighetsinformasjon.
-noExit Ikke kall opp System.exit(n) ved avslutningen av kompileringen n=0 hvis det ikke er feil).
-repeat <n> Gjenta kompileringsprosess <n> ganger (utfør analyse).
-inlineJSR Bygg inn JSR-bytekode (implisitt hvis mål >= 1.5).
-enableJavadoc Vurder referanser i javadoc
Hjelpealternativer
-? -help Vis hjelpemeldingen.
-v -version Vis byggenummeret til kompilatoren. Svært nyttig ved rapportering av feil.
-showversion Vis byggenummeret til kompilatoren og fortsett. Svært nyttig ved rapportering av feil.

Eksempler

d:\temp -classpath rt.jar -time -g -d d:/tmp Kompilerer alle kildefiler i d:\temp og undermapper. Klassebanen er bare rt.jar. Den genererer alle feilsøkingsattributter, og alle genererte *.class-filer dumpes i d:\tmp. Kompilatorens hastighet blir vist så snart satsprosessen er fullført.
d:\temp\Test.java -classpath d:\temp;rt.jar -g:none Kompilerer bare Test.java og eventuelle avhengige filer fra d:\temp. Klassebanen er d:\temp fulgt av rt.jar, hvilket betyr at alle nødvendige klasser søkes først i d:\temp og deretter i rt.jar. Den genererer ingen feilsøkingsattributter, og alle genererte .class-filer dumpes i d:\temp.

Bruke AntJavac-adapter

Eclipse-kompilatoren kan brukes inne i et Ant-skript som bruker Javac-adapteren. For å bruke Eclipse-kompilator definerer du bare egenskapen build.compiler i skriptet. Her er et lite eksempel:
<?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>
Syntaksen som brukes til Javac-Ant-oppgaven, kan du finne i Ant-Javac-oppgavedokumentasjonen. Gjeldende adapter støtter Javac-Ant -oppgave versjon 1.4.1 til og med 1.6.5.

Hvis du bruker en versjon over 1.5.0, kan du bruke det nestede kompilatorargumentelementet til å spesifisere kompilatorspesifikke alternativer.

...
<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>		
...

For å forebygge kompilatorspesifikke skripter anbefaler vi at du bruker kompilatorargumentet satt til org.eclipse.jdt.core.JDTCompilerAdapter. Hvis dette ikke er definert, kan skriptet brukes bare med Eclipse-kompilatoren. Hvis det er definert, ignoreres det nestede kompilatorargumentet dersom navnet er forskjellig fra kompilatornavnet spesifisert ved egenskapen build.compiler.

Feilsøking

JDT-kjernen definerer et spesialisert merke (merketype "org.eclipse.jdt.core.problem") til å betegne kompileringsproblemer. Hvis du vil oppdage problemer som kompilatoren finner, programmatisk, kan du brukes den standard plattformmerkeprotokollen. Du finner en oversikt over bruk av merker i Ressursmerker.

Følgende snutt finner alle Java-problemmerker i en kompileringsenhet:

   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-problemmerker vedlikeholdes av Java-prosjektbyggeren og fjernes automatisk idet problemer løses og Java-kilden kompileres.

Problem-ID-verdien defineres som en av konstantene som er definert i IProblem . Problemets ID er pålitelig, men meldingen er lokalisert og kan derfor endres avhengig av standard språkmiljø. Konstanter som er definert i IProblem, er selvforklarende.

En implementering av IProblemRequestor bør defineres for å samle inn problemer som oppdages under en Java-operasjon. Arbeidskopier kan avstemmes mot problemoppdaging hvis en IProblemRequestor er oppgitt for arbeidskopiopprettelse. For å gjøre det kan du bruke metoden reconcile. Her er et eksempel:

  ICompilationUnit unit = ..; // get some compilation unit
			
  // create requestor for accumulating discovered problems
  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; } // will detect problems if active
  };
    
  // use working copy to hold source with error
  ICompilationUnit workingCopy = unit.getWorkingCopy(new WorkingCopyOwner() {}, problemRequestor, null);
  ((IOpenable)workingCopy).getBuffer().setContents("public class X extends Zork {}");

  // trigger reconciliation			
  workingCopy.reconcile(NO_AST, true, null, null);
Du kan legge til en handling i de rapporterte problemene i metoden acceptProblem(IProblem). I dette eksempelet vil det rapporterte problemet være at Zork kan ikke løses, eller det er ikke en gyldig superklasse, og IDen er IProblem.SuperclassNotFound.

Utelater advarsler med SuppressWarnings

Java 5.0 gir deg muligheten til å deaktivere kompileringsadvarsler som gjelder et delsett av en kompileringsenhet med annotasjonen java.lang.SuppressWarning.

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

Uten annotasjonen ville kompilatoren gi en advarsel om at den lokale variabelen s aldri blir brukt. Med annotasjonen ignorerer kompilatoren denne advarselen lokalt i foo-metoden. Dette gjør at advarslene kan beholdes på andre steder i den samme kompileringsenheten eller det samme prosjektet.

Listen over symboler som kan brukes i en SuppressWarning-annotasjon er: