Kompilace kódu Java

Mezi moduly plug-in JDT patří přírůstkový a dávkový kompilátor Java určený k vytváření souborů .class prostředí Java ze zdrojového kódu. Kompilátor neposkytuje žádné přímé rozhraní API. Instaluje se jako tvůrce do projektů Java. Kompilace se spouští standardními mechanizmy platformy.

Mechanizmus, který platforma používá k sestavení, je podrobně popsán v tématu Přírůstkoví tvůrci projektů.

Kompilace kódu

Zdrojové soubory Java projektů můžete kompilovat v rámci programu s použitím rozhraní API sestavení.

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

Pro projekt Java tento kód volá přírůstkového tvůrce projektu Java (společně s ostatními přírůstkovými tvůrci projektu, jež byly přidány do konfigurace sestavení projektu). Vygenerované soubory .class se zapisují do určené výstupní složky. Do výstupní složky se kopírují rovněž soubory dalších prostředků. 

V případě plně dávkového sestavení může dojít k vymazání všech stávajících souborů .class za účelem odstranění případných zastaralých souborů. Tuto funkci ovládá volba sestavení JDT Core (CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER).  Výchozím nastavením této volby je čištění výstupních složek.  Nemá-li tato volba výchozí nastavení, musíte zajistit ukládání všech souborů .class, pro které nemáte příslušné zdrojové soubory, do samostatné složky souborů tříd v cestě ke třídě, tj. nikoli do výstupní složky.

Přírůstkové a dávkové tvůrce lze konfigurovat ostatními volbami, jež určují, které prostředky se kopírují do výstupní složky.  Následující příklad objasňuje způsob vytvoření filtru prostředků, který do výstupní složky nezkopíruje soubory s příponou názvu '.ignore' a složky s názvem 'META-INF':

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

Názvy souborů jsou odfiltrovány porovnáváním se zadanými obecnými názvy. Pokud se název složky shoduje s některým ze zadaných názvů složek, který končí oddělovacím znakem cesty, je tato složka odfiltrována.

Přírůstkové a dávkové tvůrce lze nastavit rovněž tak, aby při výskytu chyb v souboru .classpath generovali pouze jediné chybové hlášení. Jde o standardní volbu, jež umožňuje potlačení velkého počtu chybových hlášení.  Kompletní seznam voleb tvůrce s jejich výchozími hodnotami viz Volby tvůrce JDT Core.

Kompilátor lze konfigurovat rovněž s použitím voleb JavaCore.  Například můžete definovat závažnost, která by měla být použita pro různé typy problémů rozpoznávaných během kompilace. Kompletní seznam voleb kompilátoru s jejich výchozími hodnotami   viz Volby kompilátoru JDTCore .

Chcete-li v programu konfigurovat volby tvůrce nebo kompilátoru, měli byste zadat rozsah této volby.  Například zřízení filtru prostředku má být pravděpodobně uplatněno pouze na určitý projekt:

   
   Hashtable options = myProject.getOptions(false);  // získat pouze volby nastavené v tomto projektu
   options.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, "*.ignore,META-INF/");
   myProject.setOptions(options);

Použití dávkového kompilátoru

Vyhledání dávkového kompilátoru

Třída dávkového kompilátoru je umístěna v interních třídách modulu plug-in jádra JDT Core. Název třídy je org.eclipse.jdt.internal.compiler.batch.Main. Je zabalen v plugins/org.eclipse.jdt.core_3.2.0.jar. Od verze 3.2 je k dispozici rovněž samostatně ke stažení. Soubor se jmenuje ecj.jar. K dispozici je rovněž zdroj odpovídající tomuto souboru. Chcete-li jej získat, navštivte stránku pro stažení a vyhledejte sekci Dávkový kompilátor jádra JDT. Tento soubor JAR obsahuje dávkový kompilátor a adaptér Javac Ant.

Proto lze použít jako samostatná aplikace i v rámci sestavení Ant mimo Eclipse.

Spuštění dávkového kompilátoru

Jaké volby jsou k dispozici?

Při oranžovém pozadí jsou navrženy tyto volby.

Název Použití
Volby cesty ke třídě
-bootclasspath <dir 1>;<dir 2>;...;<dir P> Toto je seznam adresářů souborů JAR použitých k samozavedení souborů tříd používaných kompilátorem. Ve výchozím nastavení jsou použity knihovny spuštěného systému VM. Položky jsou odděleny oddělovačem cesty k platformě.
Jednotlivé adresáře či soubory mohou určovat pravidla přístupu pro typy v závorkách '[' a ']'.
-cp
-classpath <dir 1>;<dir 2>;...;<dir P>
Toto je seznam adresářů nebo souborů JAR použitých ke kompilaci zdrojových souborů. Výchozí hodnota je hodnota vlastnosti "java.class.path". Položky jsou odděleny oddělovačem cesty k platformě.
Jednotlivé adresáře nebo soubory mohou určovat pravidla přístupu pro typy v závorkách '[' a ']' (např. [-X] pro zákaz přístupu k typu X, [~X] pro nastavení nevhodnosti přístupu k typu X, [+p/X:-p/*] pro zákaz přístupu ke všem typům v balíčku při povolení přístupu k p/X).
-extdirs <dir 1>;<dir 2>;...;<dir P> Toto je seznam adresářů použitých k určení umístění souborů s příponou názvu zip/jar. Položky jsou odděleny oddělovačem cesty k platformě.
-endorseddirs <dir 1>;<dir 2>;...;<dir P> Toto je seznam adresářů použitých k určení umístění schválených souborů zip/jar. Položky jsou odděleny oddělovačem cesty k platformě.
-sourcepath <dir 1>;<dir 2>;...;<dir P> Toto je seznam adresářů použitý k určení zdrojových souborů. Položky jsou odděleny oddělovačem cesty k platformě.
Jednotlivé adresáře mohou určovat pravidla přístupu pro typy v závorkách '[' a ']'.
-d <dir 1>|none Používá se k určení, do kterého adresáře by se měly vypisovat vygenerované soubory .class. Pokud to vynecháte, nebude vytvořena adresářová struktura balíčku.
Pokud nechcete generovat soubory .class, použijte -d none.
-encoding <encoding name> Určete výchozí formát kódování zdroje (rovněž lze pro jednotlivé soubory určit vlastní kódování použitím přípony názvu souboru/složky [<název kódování>], například X.java[utf8]).
Volby shody
-target 1.1|1.2|1.3|1.4|1.5|5|5.0|1.6|6|6.0 to určuje cílové nastavení souboru .class. Možné hodnoty jsou:
  • 1.1 (hlavní verze: 45 vedlejší: 3)
  • 1.2 (hlavní verze: 46 vedlejší: 0)
  • 1.3 (hlavní verze: 47 vedlejší: 0)
  • 1.4 (hlavní verze: 48 vedlejší: 0)
  • 1.5, 5 nebo 5.0 (hlavní verze: 49 vedlejší: 0)
  • 1.6, 6 nebo 6.0 (hlavní verze: 50 vedlejší: 0)
Výchozí nastavení jsou:
  • 1.1 v režimu -1.3
  • 1.2 v režimu -1.4
  • 1.5 v režimu -1.5
  • 1.6 v režimu -1.6
-1.3 Nastavte úroveň shody na 1.3. Implicitně -zdroj 1.3 -cíl 1.1.
-1.4 Nastavte úroveň shody na 1.4 (výchozí). Implicitně -zdroj 1.3 -cíl 1.2.
-1.5 Nastavte úroveň shody na 1.5. Implicitně -zdroj 1.5 -cíl 1.5.
-1.6 Nastavuje úroveň shody na 1.6. Implicitní -source 1.6 -target 1.6.
-source 1.3|1.4|1.5|5|5.0|1.6|6|6.0 Toto se použitá k určení úrovně zdroje očekávané kompilátorem.
Možné hodnoty jsou:
  • 1.3
  • 1.4
  • 1.5, 5 nebo 5.0
  • 1.6, 6 nebo 6.0
Výchozí nastavení jsou:
  • 1.3 v režimu -1.3
  • 1.3 v režimu -1.4
  • 1.5 v režimu -1.5
  • 1.6 v režimu -1.6
Ve verzi 1.4, se s assert nakládá jako s klíčovým slovem. V 1.5 a v 1.6 jsou enum a assert klíčovými slovy.
Volby varování
-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
Nastavte úroveň varování.
např. -warn:unusedLocal,deprecation

Výchozí nastavení jsou červená.

    -warn:none                           deaktivuje veškerá varování
    -warn:<varování oddělená ,>    zpřístupnit přesně vypsaná varování
    -warn:+<varování oddělená ,>   zpřístupnit dodatečná varování
    -warn:-<varování oddělená ,>   znepřístupnit určitá varování
allDeprecation nepřípustnost i uvnitř nepřípustného kódu
allJavadoc neplatný nebo chybějící dokumentace javadoc
assertIdentifier výskyt assert použit jako identifikátor
boxing konverze automatického uzavírání
charConcat pokud je ve zřetězení řetězce pole char použito bez výslovné konverze na řetězec
conditionAssign možné nechtěné logické přiřazení
constructorName metoda s názvem konstruktoru
dep-ann chybí anotace @Deprecated
deprecation použití nepřípustného typu nebo členu mimo nepřípustný kód
discouraged použití typů, jež odpovídají pravidlu přístupu Nevhodné
emptyBlock nedokumentovaný prázdný blok
enumSwitch,
incomplete-switch
nekompletní přepínač výčtu
fallthrough možný případ neúspěchu příkazu case
fieldHiding pole zakrývající jinou proměnnou
finalBound parametr typu s konečnou mezí
finally blok finally není normálně ukončen
forbidden použití typů, jež odpovídají pravidlu přístupu Zakázáno
hiding makro pro fieldHiding, localHiding, typeHiding a maskedCatchBlock
indirectStatic nepřímý odkaz na statický člen
intfAnnotation typ anotace používaný jako nadřízené rozhraní
intfNonInherited kompatibilita metody nezděděné z rozhraní
javadoc neplatná dokumentace javadoc
localHiding lokální proměnná zakrývající jinou proměnnou
maskedCatchBlocks skrytý zachytávací blok
nls řetězcové literály jiné než nls (postrádající značky //$NON-NLS-<n>)
noEffectAssign přiřazení bez účinku
null chybějící nebo nadbytečná kontrola nuly
over-ann chybí anotace @Override
paramAssign přiřazení parametru
pkgDefaultMethod pokus o vyřazení výchozí metody balíčku
raw použití přímého typu (místo parametrizovaného typu)
semicolon nepotřebný středník, prázdný příkaz
serial chybí serialVersionUID
specialParamHiding konstruktor nebo parametr metody setter skrývá jiné pole
static-access makro pro indirectStatic a staticReceiver
staticReceiver pokud se nestatický příjemce použije k získání statického pole nebo volání statické metody
suppress zpřístupnit @SuppressWarnings
syntheticAccess,
synthetic-access
při provádění syntetického přístupu pro vnitřní třídu
tasks zpřístupnit podporu pro značky úloh ve zdrojovém kódu
typeHiding parametr typu zakrývá jiný typ
unchecked nekontrolovaná operace s typem
unnecessaryElse nadbytečná klauzule else
unqualified-field-access,
unqualifiedField
nekvalifikovaný odkaz na pole
unused makropříkaz pro unusedArgument, unusedImport, unusedLabel, unusedLocal, unusedPrivate a unusedThrown
unusedArgument nepřečtený parametr metody
unusedImport nepoužitý odkaz importu
unusedLabel nepoužitý štítek
unusedLocal nepřečtená lokální proměnná
unusedPrivate nepoužitá deklarace soukromého členu
unusedThrown nepoužívaná deklarovaná nastalá výjimka
uselessTypeCheck nepotřebná operace cast/instanceof
varargsCast argument varargs vyžaduje explicitní přetypování
warningToken neošetřený varovný token v @SuppressWarnings

-nowarn Bez varování (rovnocenné s -warn:none)
-deprecation Rovnocenné s -warn:deprecation.
Volby ladění
-g[:none|:lines,vars,source] Nastavte úroveň atributů ladění
-g Všechny informace o ladění (rovnocenné s -g:lines,vars,source)
-g:none Žádné informace o ladění
-g:[lines,vars,source] Selektivní informace o ladění
-preserveAllLocals Výslovně požadovat, aby kompilátor zachoval všechny lokální proměnné (pro účely ladění). Je-li vynechána, kompilátor nepoužité lokální proměnné odstraní.
Ignorované volby (z důvodu kompatibility s volbami javac)
-J<volba> předává volbu virtuálnímu stroji
-X<volba> určuje nestandardní volbu. -Xemacs není ignorována.
-X vytisknutí nestandardních voleb a konec
-O optimalizovat pro dobu provádění
Rozšířené volby
@<file> Načíst argumenty příkazového řádku ze souboru
-maxProblems <n> Maximální počet problémů na kompilační jednotku (standardně 100)
-log <filename> Určete protokolový soubor, do kterého budou vypisovány veškeré výstupy z kompilátoru. To je skutečně užitečné, pokud chcete ladit dávkový kompilátor nebo získat soubor, který obsahuje všechna chybová hlášení a varování z dávkového sestavení. Je-li přípona názvu .xml, vygenerovaný protokol bude souborem ve formátu XML.
-Xemacs Použít styl emacs k zobrazení umístění chyb a varování v konzole a v řádných textových protokolech. Protokoly XML tato volba neovlivňuje. Je-li tato volba aktivní, zpráva:
2. VÝSTRAHA v /workspace/X.java
(řádek 8)...

se zobrazuje tímto způsobem:
/workspace/X.java:8: výstraha: Metoda...
-proceedOnError Nezastavovat kompilaci při výskytu chyb, vypsat soubory tříd s problémovými metodami nebo typy problémů. To se doporučuje pouze, pokud chcete mít možnost spouštět aplikaci, i když zůstávají chyby.
-verbose V případě určení tisknout kompilační jednotky, ke kterým se přistupuje nebo které se zpracovávají, do konzoly nebo protokolového souboru.
-referenceInfo Určit referenční informace. To je užitečné pouze při připojení k tvůrci. Referenční informace jsou jinak neupotřebitelné.
-progress Zobrazit průběh (pouze v režimu -log).
-time Zobrazit informaci o rychlosti.
-noExit Nevolat System.exit(n) na konci kompilace (n=0, pokud nedojde k žádné chybě).
-repeat <n> Opakovat proces kompilace <n> krát (analýza perf).
-inlineJSR Vložený bajtový kód JSR (implicitní pokud cíl >= 1.5).
-enableJavadoc Zvážit odkazy v dokumentaci Javadoc.
Volby nápovědy
-? -help Zobrazit zprávu nápovědy.
-v -version Zobrazit číslo sestavení kompilátoru. To je velmi užitečné při hlášení chyby.
-showversion Zobrazit číslo sestavení kompilátoru a pokračovat. To je velmi užitečné při hlášení chyby.

Příklady

d:\temp -classpath rt.jar -time -g -d d:/tmp Zkompiluje všechny zdrojové soubory v d:\temp a podsložkách. Cesta ke třídě je jednoduše rt.jar. Vygeneruje všechny atributy ladění a všechny vygenerované soubory .class jsou vypsány do d:\tmp. Rychlost kompilátoru se zobrazí po dokončení dávkového procesu.
d:\temp\Test.java -classpath d:\temp;rt.jar -g:none Zkompiluje pouze Test.java a případné závislé soubory, přičemž závislé soubory načte z adresáře d:\temp. Cesta ke třídě je složka d:\temp následovaná názvem souboru rt.jar, což znamená, že veškeré nezbytné třídy jsou vyhledávány nejprve v adresáři d:\temp a poté v souboru rt.jar. Negeneruje žádné atributy ladění a všechny vygenerované soubory .class jsou zapisovány do adresáře d:\temp.

Použití adaptéru Ant javac

Kompilátor Eclipse lze prostřednictvím adaptéru javac použít i uvnitř skriptu Ant. Chcete-li použít kompilátor Eclipse, definujte ve svém skriptu vlastnost build.compiler. Následuje krátký příklad.
<?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> 
Syntaxi použitou pro úlohu javac Ant lze nalézt v Dokumentaci úlohy Ant javac. Aktuální adaptér podporuje úlohu Javac Ant verze 1.4.1 až 1.6.5.

Pokud používáte verzi vyšší než 1.5.0, můžete použít vnořený prvek argumentu kompilátoru k určení voleb specifických pro kompilátor.

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

Abyste zabránili kompilátoru v načtení závislých skriptů, doporučujeme vám použít argument kompilátoru nastavený na org.eclipse.jdt.core.JDTCompilerAdapter. Pokud nebude toto nastavení provedeno, skript bude možné používat pouze s kompilátorem Eclipse. Pokud bude nastaveno, vnořený argument kompilátoru bude ignorován, pokud se jeho název liší od názvu kompilátoru určeného ve vlastnosti build.compiler.

Určení problému

JDT Core definuje speciální značkovač (typ značkovače "org.eclipse.jdt.core.problem ") pro účely popisu kompilačních problémů. Chcete-li programem zkoumat problémy odhalené kompilátorem, použijte standardní protokol značkovačů platformy. Přehled použitých značkovačů viz Značkovače prostředků.

Následující úsek zdrojového kódu vyhledává všechny značkovače problémů Java v kompilační jednotce.

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

Značkovače problémů Java jsou udržovány tvůrcem projektu Java. Po vyřešení problémů a opětovné kompilaci zdroje Java dochází k jejich odstranění.

Hodnota Id problému je nastavena na některou z konstant v IProblem. ID problému je spolehlivé, avšak zpráva je lokalizována, a proto ji lze měnit v závislosti na výchozím národním prostředí. Konstanty definované v IProblem mají názvy odpovídající obsahu.

Měla by být definována implementace IProblemRequestor pro účely sběru problémů odhalených během činnosti prostředí Java. Pracovní kopie lze srovnávat s detekcí problémů, pokud byl pro vytvoření pracovní kopie poskytnut IProblemRequestor. Pro tento účel můžete použít metodu reconcile. Zde je příklad:

  ICompilationUnit unit = ..; // získat kompilační jednotku
			
  // vytvořit klienta pro sběr zjištěných problémů
  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; } // je-li aktivní, detekuje problémy
  };
    
  // použít pracovní kopii k zachování zdroje s chybou
  ICompilationUnit workingCopy = unit.getWorkingCopy(new WorkingCopyOwner() {}, problemRequestor, null);
  ((IOpenable)workingCopy).getBuffer().setContents("public class X extends Zork {}");

  // odsouhlasení spouštěče
  workingCopy.reconcile(NO_AST, true, null, null);
Do metody acceptProblem(IProblem) můžete přidat akci pro nahlašované problémy. V tomto příkladu bude nahlášen problém Zork nelze interpretovat nebo nejde o platnou supertřídu a ID tohoto problému je IProblem.SuperclassNotFound.

Vyloučení varování pomocí SuppressWarnings

Java 5.0 umožňuje uživateli deaktivovat varování kompilace týkající se podmnožiny kompilační jednotky pomocí anotace java.lang.SuppressWarning.

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

Bez anotace by kompilátor oznámil, že lokální proměnná s není použita. S anotací kompilátor tuto výstrahu tiše ignoruje lokálně v metodě foo. Toto umožňuje zachování varování v jiných umístěních téže kompilační jednotky nebo téhož projektu.

Seznam tokenů, které lze použít uvnitř anotace SuppressWarning: