dagblog.
← Archiv

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 Foo
Something fishy
Vý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 Foo
Something fishy
Mí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.java
import 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.

Verze na Medium

Související články

Související epizody CZ Podcastu