JavaSvet - otvorena java zajednica

 
glavna stranica arr2javasvet  english version arr2java.net

Ant v1.6 novosti

Igor Spasić
16 Jul 2004

Ant v1.6 donosi novine koje mogu promeniti dosadašnji način njegovog korišćenja. Za razliku od prethodnih verzija, nove funkcionalnosti u verziji 1.6 dodate radi velikih ili kompleksnih projekata donose i novi mogući način struktuiranja samog build-procesa. Reč je o tri nova taska: <macrodef>, <import> i <subant>.

Makroi

Pojam makroa nije nov i bilo je pitanje vremena kada će ovakva funkcionalnost biti uključena među Ant taskove. Reč je, dakle, o ponovnom korišćenju sličnih kombinacija taskova koje se međusobno vrlo malo razlikuju.

Sledeći primer prikazuje definisanje makroa i način njegovog korišćenja:

<macrodef name="foo"> <attribute name="val" default="NOT SET"/> <element name="some-tasks" optional="yes"/>dd <sequential> <echo>val = @{val}</echo> <some-tasks/> </sequential> </macrodef> <foo val="Foo task"> <some-tasks> <echo>foo task test</echo> </some-tasks> </foo>

Prva polovina ovog primera definiše makro foo. Ovaj makro ima jedan atribut (val) i jedan tkzv. ugnježdeni (nested) element. Samo telo makroa je definisano u sequential bloku.

Atribut makroa se definiše pri njegovom pozivu, a u telu makroa se dobija slično standardnim Ant parametrima, osim što se koristi znak @ umesto $. Atribut može da bude obavezan i/ili da ima default vrednost ukoliko nije naveden. U telo makroa je moguće koristiti i spolja definisane Ant parametre. Važan je redosled razvijanja (ekspandovanja) atributa i parametara: atributi se razvijaju PRE propertija! Tako je sledeći primer validan i upotrebljiv:

${@{src}.parent}

Znači, ovde se prvo razvija atribut src, a zatim parametar čije ime zavisi od vrednosti atributa i koji se završava na '.parent'. Na ovaj način mogu definisati paramteri na osnovu vrednosti atributa, što je do sada bilo nemoguće jer su Ant propertiji globalni i nepromenjivi (imutabilni).

Ugnježdeni element se isto definiše pri pozivu makroa, a predstavlja ceo blok koji će se umetnuti na njegovo mesto. Na ovaj način je moguće da se pri svakom pozivu makroa definiše složeni blok tj. skup taskova koji nije isti za različite upotrebe makroa, a koga nije moguće definisati i upravljati njime samo pomoću fiksnih parametara. Trenutno ovaj način stvaranja propertija praktično kreira grupu novih propertija. Za očekivati da će buduće verzije Anta doneti propertije definisane samo u oblasti važenja makroa.

Donja polovina primera predstavlja poziv makroa i prikazuje kako se koriste parametri i ugnježdeni elementi. Rezultat rada ovog primera je:

[echo] val = Foo task
[echo] foo task test

Pažljiviji čitaoci će možda primetiti da se u prethodnim verzijama Anta ovakva funkcionalnost makroa mogla donkle simulirati korišćenjem <antcall> taska. Iako je to tačno, dalja upotreba <antcall> se nikako ne preporučuje, jer je ovaj task značajno sporiji, a novi pristup daje build fajl koji je lakši za čitanje i održavanje.

Import

Deljenje jednog Ant build fajla na više manjih tj. uključivanje drugih build fajlova u jedan glavni je takođe poznata funkcionalnost, koja je konačno uključena u Ant. Trivijalna upotreba ove funkcionalnosti bi bila u slučaju kada se ima veliki build fajl koji se ovako može podeliti na više manjih fajlova - celina, čineći održavanje i korišćenje build fajlova lakšim.

Uključivanje drugih fajlova u Ant build fajl je i do sada bilo moguće, zahvaljujući XML-u, a ne samom Antu, na sledeći način:

<!DOCTYPE mainBuildFile [ <!ENTITY extFile SYSTEM "file:./extFile1.xml"> ]>

Samo uključivanje se kasnije radi jednostavnim navođenjem &extFile;. Međutim, ovaj pristup ima svojih mana. Prvo, XML fajl koji se ukjlučuje predstavlja bukvalno isečak XML koda koji treba da dođe na mesto uključivanja, pa njegova strutkura, ako se fajl posmatra zasebno, ne odgovara standardnoj XML strukturi, nema root elemenat, što sve može da oteža njegovo editovanje pomoću raznih XML alata. Važniji nedostatak je nemogućnost korišćenja Ant propertija za definisanje imena uključenog fajla, pa se ono mora hard-kodovati.

Ant v1.6 import tag konačno donosi mogućnost deljenja sličnih funkcionalnosti i uključivanje fajlova. Evo najjednostavnijeg primera korišćenja:

... <import file="${external.file}"/> ...

Pošto je u pitanju Ant task, mogu se koristiti sve mogućnosti Anta za definisanje lokacije fajla koji se uključuje. Taj eksterni fajl sada mora da bude validan Ant fajl, što znači da će imati root element i validnu XML strukturu, posmatran zasebno.

Lokacija fajla koji se uključuje se zadaje relativno u odnosu na glavni build fajl, a ne u odnosu na radni folder odakle se skript izvršava. Ovo ne utiče na rad sa build fajlom sve dok basedir atribut projekta nije setovan na neku vrednost ili na '.'. I u ovakvim slučajevima je moguće odrediti apsolutnu poziciju fajla na osnovu radnog folder (basedir) na sledeći način:

<property name=exFile" location="exFile1.xml"/> <import file="${exFile}"/>

Import task se jedino može koristiti kao top-level task, što znači da ga nije moguće koristiti unutar target taskova.

Postoje još dve funkcionalnosti koje se tiču import taska.

Kada se importuje neki fajl, Ant automatski definiše specijalni properti ant.file.IME gde je IME u stvari vrednost name atributa projekta. Slično kao properti ant.file, ovi specijalni propertiji imaju za vrednost putanju do uključenog fajla.

Druga važnija funkcionalnost je definisanje targeta istog imena u glavnom build fajlu i u fajlu koji se uključuje (target overriding). U ovom slučaju target definisan u glavnom build fajlu ima prednost i on će biti taj koji će se izvršavati. Međutim, target definisan u externom fajlu je i dalje je dostupan kao: IME.target_name gde je IME vrednost name atributa projekta uključenog fajla.

To znači da će u slučaju kada se u glavnom build fajlu definiše target istog imena kao i uključenom fajlu postojati oba targeta: target_name i IME.target_name, iz glavnog i uključenog fajla respektivno. Primer glavnog build fajla:

<project name="m2"> <import file="m2e.xml"/> <target name="foo"> <echo>m2 foo target ${ant.file}</echo> </target> </project>

i primer fajla koji se ulkjučuje:

<project name="m2ext"> <target name="foo"> <echo>m2e foo target</echo> </target> <target name="foo2"> <echo>m2e foo2 target</echo> </target> </project>

Pozivom foo targeta izvršava se target definisan u glavnom fajlu. Pozivom m2ext.foo targeta izvršava se target definisan u externom fajlu. Pozivom foo2 targeta izvršava se target definisan u externom fajlu. Ne postoji target m2ext.foo2 (pošto nema definicije za 'foo2' u glavnom fajlu).

Import funkcionalnost je jako korisna kada postoji slična struktura u build fajlovima. Oni se mogu refaktorisati tako da se zajednička funkcionalnost 'izvuče' u jedan ili više zajedničkih build fajlova, koji se zatim uključuju u glavni i gde se koristi opisan target overriding.

Subant

Subant task služi za izvršavanje datog targeta za sve definisane subtaskove. On se može koristiti za rad sa folderima, da izvršava build fajl koji se nalazi u različitim direktorijuma, na dva načina.

Prvi način je izvršavanje istog build fajla sa korišćenjem različitih osnovnih foldera. Primer iz Ant dokumentacije:

<subant target="compile" genericantfile="/opt/project/build1.xml"> <dirset dir="." includes="projects*"/> </subant>

Ako se predpostavi da postoje podfolderi projects1, projects2, projects3 gornji deo ant koda će izvršiti target "compile" fajla "/opt/project/build1.xml" setujući basedir atribut na vrednosti projects1, projects2, projects3.

Drugi, možda korisniji, način korišćenja subant taska omogućava izvršavanje buildfajla istog imena koji se nalazi u skupu definisanih foldera:

<target name="build-all"> <subant target="foo"> <fileset dir="." includes="module-*/build.xml"/> </subant> </target>

Ovaj primer će automatski locirati sve build fajlove za sve module koji su odvojeni u podfolderima i izvršiti ih. Dodavanje novog modula neće zahtevati izmene ovog dela skripta. Naravno, moguće je i tačno definisati koje build fajlove treba izvršiti što čini upotrebu subant taska sličnu korišćenju ant taska. Ipak, subant nudi veće mogućnosti u definisanju skupa potrebnih skriptova koje treba izvršiti.

Ostalo

Prikazani novi Ant taskovi predstavljaju značajnu novinu koja doprinosi kreiranju Ant skriptova koje je moguće ponovo i višestruko koristiti (reusable). Naravno, Ant v1.6 donosi i razne druge nove mogućnosti koje proširuju ili nadopunjuju dosadašnje funkcionalnosti. Od interesantnih novina tu je i <scriptdef> task kojim se može kreirati custom task bez pisanja posebnog Java modula.

download: primer koji prati članak.