Ant a malá “zrada” kompilace
Tento příspěvek mám v hlavě již delší dobu, jenom nebyl čas se podělit o zajímavou
true story. Bylo nebylo, Hloupý Honza vyrazil na instalaci aplikačního serveru spolu
s nejnovější verzí softwaru společnosti Pohádka s.r.o. Jelikož byl Honza hloupý a nikoliv líný
vše si pečlivě připravil. Úhledně připravený distribuční balíček, byl vytvořen z posledního
stavu v CVS, pomocí mravenečka jménem Ant.
Posílen buchtami od maminky, vyrazil na cestu do království za sedmero řekami a horami. Honzův úkol v podobě nainstalování se povedl na výbornou. Drak na obloze objevil se při testování funkčnosti. Marně sváděl
udatný bojovník souboj s Drakem, ostrý meč v podobě aktuálních zdrojů jenž platil na cvičišti nepomáhal. S nepořízenou se domů Honzík vrátil. Zrada se ukázala druhý den, ten mrzký sluha Ant byl vinen, on zradil pána svého.
Po této pohádkové vložce se přesuneme k problému. Máme třídu Foo a třídu Constant. Třída Constant obsahuje pouze konstanty, které využivá třída Foo.
public class Constant {
public static final String SOMETHING_FISHY = "Something fishy";
}public class Foo {
public static void main(String args[]){
System.out.println(Constant.SOMETHING_FISHY);
}
}Pro kompilaci máme antovský task.
Build task pustíme a necháme si zdrojové kódy zkompilovat. Zkompilovaný prográmek pustíme
java FooSomething fishyVýsledek zcela očekávaný. Uděláme malou úpravu zdrojového kódu a hodnotu konstanty SOMETHING_FISHY změníme.
public class Constant {
public static final String SOMETHING_FISHY = "Kim Philby";
}Znovu pustíme build task a zkompilovaný prográmek.
java FooSomething fishyMísto očekávaného Kima Philbyho máme na výstupu Something fishy, kde je chyba? Bohužel to není chyba, ale je to vlastnost. Ant se rozhodne třídu zkompilovat pokud nemá odpovídající class soubor a nebo pokud je class soubor starší než třída resp. zdrojový soubor. To v našem případě sice platí, ale kompilátor z důvodu optimalizace přikompiluje obsah konstanty do třídy Foo. O tom se můžeme přesvědčit dekompilací.
// Decompiled by DJ v3.5.5.77
// Copyright 2003 Atanas Neshkov Date: 24.11.2004 8:22:41
// Home Page : http://members.fortunecity.com/neshkov/dj.html
// - Check often for new version!
// Decompiler options: packimports(3)
// Source File Name: Foo.javaimport java.io.PrintStream;public class Foo
{public Foo()
{
}public static void main(String args[])
{
System.out.println("Something fishy");
}
}Spásou by mohl být antovský depend task, žel bohu na konci jeho popisu najdeme v sekci Limitations následující odstaveček
The most obvious example of these limitations is that the task can’t tell which classes to recompile when a constant primitive data type exported by other classes is changed. For example, a change in the definition of something like
public final class Constants {
public final static boolean DEBUG=false;
}will not be picked up by other classes.
Co dodat závěrem kromě toho, že mě alias Hloupého Honzu to pěkně vypeklo? Snad jen radu, přidejte si na první místo build war tasku smazání cílového adresáře pro classes. Pokud si chcete ověřit chování, zdrojové kódy jsou k dispozici.
Související články
Související epizody CZ Podcastu
- #261 · Leadership
O vedení lidí a týmů.
- #3 · Java 6 SE, Vývoj webových aplikací
Dagi a Filemon o novinkách v Javě 6 a webových frameworcích.
- #1 · Vývojová prostředí v Javě
První díl CZ Podcastu se věnuje vývojovým prostředím pro Javu.