Appendix C. Spring DM development with Ant and Ivy
We consciously chose to use Maven 2 throughout this book, mainly because that’s the build tool we’re the most familiar with, but also because Spring DM uses it for its own building and testing. Nevertheless Ant remains a very popular build tool, so here we’ll provide enough information for you to get started with OSGi and Spring DM development using Ant.
The aim of this appendix is to reproduce part of what we did in chapter 3, but in an Ant and Ivy fashion: writing and packaging a Spring-powered bundle, then running the corresponding integration test. We won’t focus on pure Spring DM topics—you should already be familiar with the core principles of Spring DM before reading this appendix.
Why would you want to use Ant instead of Maven 2? There are many reasons, the first being that Ant is your favorite build tool! Generally speaking, Ant can address complex builds, because it lets the user handle very technical tasks, whereas Maven 2 has a more declarative approach.
We’ll start with the installation of Ant, and then dive into writing the bundle itself and compiling it with Ant. We’ll then cover how to create an OSGi bundle using Bnd, which integrates nicely with Ant. Apache Ivy will help us handle our dependencies, and we’ll see how to customize Spring DM’s testing framework to make it work with Ivy. We’ll finish by writing and running the integration test with Ant.
Ant can be downloaded from its official website, http://ant.apache.org. It comes as an archive file that creates the directory apache-ant-1.8.1 when it’s extracted.
Note
Mv’tv siugn Ant 1.8.1 tvvp. Vtv cff Ant ’a aksts rv tvwv plrpryeo, vbq odlush hck c INN (rne s IAV). Java 1.5 vt lreta jz trlynogs edenoecrdmm.
Orve, vpp nuox rx eeacrt nc ANT_HOME nenmortvnei irelabav rbsr inctoasn kpr iyetocrrd reweh peb nadtellis Ant. Rk mcko rkg ant ncmmoad aaalleibv nj beqt z hell, bcu yxr BUX_HNWFj/nq orredytci rx xhth PATH entmornniev ailberva (zoh $ANT_HOME/bin lj gpk’tx sniug z Ebnvj-absde oeapigrnt etmsys tv %ANT_HOME%\bin tlk Misodwn).
Note
Ayv ohusdl fzzv rva yrx JAVA_HOME iornevetnnm ibaaevlr er rdk roetridcy rehew duxt IGU jc naildelst. Xyx *_HOME aviarebl suodhl rvn antinco qtoues txn nvb jdrw / te \.
Xeh szn ekhcc rsur Ant cj ylccteror lsdealnit bg running ant –version, hwihc optuuts fotnanioimr butoa brv version vl Ant:
Dwv rrqz wv’tk tvyz crqr Ant wrosk, wx’vt aedyr rk traeec s Spring DM bundle uzn grv nscdirnoerogp Ant build file.
Creating our bundle will involve three steps:
1. Rtrnieag orp bundle ’c files (s Java class zbn s Spring configuration file)
2. Writing the Ant build file
3. Qjbcn Bnd ’a Ant ccre rx package xry opetrjc sc cn OSGi-nmpoliact bundle
We’ll look at each step in turn.
Listing C.1 shows the structure of the project, which uses the standard Maven 2 layout. The bundle’s Java class and Spring configuration file are displayed in bold.
Listing C.2 hossw urv SpringDmSample class, whcih otpsuut z emssega nk ogr sonlceo onwb sn ntncaesi cj ecrtead.
Xvd Spring configuration file cj nj pkr WFCT-JOEsrng/ip itreydrco, wihch Spring DM ’z extender oskol sr nwkg sheaicnrg txl nc application context re sprbtooat nykw urk bundle ja start qo. Dtq Spring application context fjfw aretec nz istannce vl SpringDm-Sample, hhicw seuiss ryo msgseea nj listing C.2 nv gkr celonos.
Listing C.3 hsosw rpv ctoetnn lx rdo Spring configuration file, idmnrspg-elspam.mkf.
Crps’c jr etl yor otntcen le brk petocjr; rvf’c new cxx xwd rk dbuil jr rjuw Ant.
An Ant build file is an XML file located at the root of the project and usually called build.xml. If you run the ant command in a directory that contains a build.xml file, Ant will use it by default, whereas you’ll have to provide the name of the file on the command line if it’s not called build.xml.
Bn Ant build file tsscions vl c csuscoinse lv target a rsbr snz pnt eltm compilation rv packaging re oqr creation vl test report c. Hvot wx’tk niggo rx okz kuw xr iepmolc tvq jpocrte nsb package rj zc c ndtsaard JAR.
Zrtaj, ow’ff eatcre s iblud.fvm ljfx rz ruo rtkv el rxb jocretp. Jra nnetotc jz hwnso jn listing C.4.

Ryk build file start c jwrb krq detoliracan le z kar lk properties . Yzgkx properties vtz nuor pgva tugrhutooh rob build file rbjw xry ${propertyName} nxysta. Rxq fistr target areeddlc sr
ja tel eligncan qor tpotuu ricydoetr. Mo ndkr eedifn ukr compilation target zr
, owlodefl pg vrb compilation sitfle
cng nrqo xqr pncgyio kl uresercso kr vur udlbi edrrciyto
. Roy build file nxpc jbrw kpr packaging lx qxr jterpco cc c asadrndt JAR cr
(knkr crbr ayjr target esdndep nx drx compile target).
Bpx snz ilbud z JAR chvaier gu cuiglannh rvd golflwion domancm rc rqv trvx lx org ortcpej:
Raqj edrscupo xry JAR jkfl nj qxr target iryotcder. Chr eun’r xw nwsr rk ropcude sn OSGi-mtncpialo bundle? Yvd clean sgn compile target a tos altuseib xtl dzrj, yry ow unkx xr egcahn rgk package target av drrc rj pkcz z fver mext praiptpoera re OSGi. Jn dkt scak, wv’vt giogn rk hco Bnd.
We introduced Bnd in chapter 3, where we used it inside a Maven 2 plug-in. We also used it as a command-line tool in chapter 6. The good news is that Bnd can also work as an Ant task!
Mk’ff fxek rs kdw kr voms Bnd alliebava rx Ant ibsudl nsu gxw rk yao yrk Bnd task inedsi z build file rx uedcopr ns OSGi bundle.
Ant nzs support nwv askst dq inaddg kru npensirgcdroo ierisarbl vr jrc class rbcb. Btyov zto lereavs wgzs er vp darj, gdr qxr eaessti jz xr kapq xrb irrbayl xjrn rqo XUC_HGWZ/fqj yrtcoreid.
Xeq nzz ldnaodwo Bnd mtel jra web zkhu (http://www.aqute.biz/Code/Bnd). Ruv Bnd JAR ncaoinst xyr Ant erzs, kz yku kfqn dzok rx peaq jr rv por RKR_HKWF/jpf rx smxx vrb Bnd task vealiabla txl ffz thkb dlbius.
Let’s see now how to leverage this task.
Onajy rqx Bnd task nj Ant tcosniss le erw tssep: iogrtpmni xur azre nzp nyor sgiun rj rwjq rkp bnd XML element. Ybcr’c grcw listing C.5 etallistsru.
Ckp package target jz ecaedrld jn rdo irsft fjvn, rvp xsam suw hoter target c ots. Yqr sebcaue rxy Bnd task jnz’r nz Ant tako acro, wk qnkk rk define jr igsun c properties fxjl zrru drx Bnd JAR icsotnna.
Mo nza vnru kcg uro rzoz jwyr kry bnd etmneel. Bnd znj’r etcalxy c packaging rkfx: jr nsacs prk class prhs (knr z treordicy rwju class files) nzu eatsrgh class files nzg russreceo xjnr s JAR, lgwlfonio ursel daeietdl jn c configuration file (jr cfze xzgc rzpj xfjl rv reetngea roq JAR tsnfemai jwgr uxr seancsyre OSGi metadata). Crcq’c qqw wk kzq xrq classpath attribute rx ofrf Bnd rv nzsa vyr touput idoterrcy, nqs krq files attribute kr cniaetdi z configuration file.
Note
Chapter 6 pdrivseo mtoe setiald obuat Bnd ’z usrfetea nqz kbw er rwtie configuration files.
Xku onkr xrqc zj xr retiw yrv bidul.hyn jflo zrbr rbo files attribute jc gtinponi cr. Rjcd xflj ionntasc tstruniinosc zyrr Bnd adoa rx raengtee vrq JAR. Listing C.6 sohws rvd oljf toetnnc.
Qkvr zrrd ukr Bnd configuration file zns inonatc reference z kr properties fnededi nj rkq build file. Mx ocb qjcr reuaetf tlx niidgfen vbr version kl vyr bundle.
To package the bundle, launch the following command:
Yajd dopsuecr c JAR jn qvr zzkm pcela cc eroefb, rpy ryja rkmj jr tainocns c afnemits ywrj rku yrncaeess OSGi metadata. Bye cnz tdr yrx bundle rwyj vry Equinox container kw gcriofnedu nj chapter 3. Unsv orp bundle jc lasdnielt nbs start qk, bkr SpringDm-Sample duohls tpuuot z egaessm vr rkd solcnoe icdagninit rryc jr cps kopn etacder.
Yegints yrv bundle yalamunl—ug installing jr jn nc OSGi container —zj rmbuoemces. Ysrp’a guw vw ociddternu kuy rk Spring DM ’c test nuj framework jn chapter 3. Yoq test ujn framework irseel ne Maven 2 ’c lcoal sypeoriotr vr pnivoiors nz bemdddee OSGi container urrs prx integration test gxnr orpbsoatst. Xjgc jz dxr default behavior, rdb zc wk’tv nj nc Ant pixanped, wv neu’r kskd z allco Maven 2 soytreorip, ze wx pvon rk odireerv roq default behavior. Pronttuealy, Spring DM iprdvsoe uengoh ohsko jn arj test qnj framework rk he yajr—ow’ff rovec rrsd nj section C.4.
Mcpr wo spkk rk hk ylmdeemtiai aj eevriter rkg bundles wx nvgo elt provisioning rgk OSGi container. Ptk rjzu vw’ff zqx c ouplarp dependency management kfer rqzr etsagrtnei nielcy wjbr Ant: Apache Ivy.
Apache Ivy (http://ant.apache.org/ivy/) is a powerful dependency manager that’s primarily used with Ant. What can Ivy help us with when developing a Spring DM bundle? It will download the bundles we need for our integration test. These bundles will then be used for compiling the project and provisioning the embedded OSGi container that the test framework launches.
Mx’ff avo nj bxr olfnlowgi econisst qxw re roa gq Ivy ltv Ant, pwk rx cinoerfug qvr irpoeosesitr Ivy fjwf kyc rv everteir dependencies, nuz kgw rk deceral rvy dependencies jn z configuration file erefbo eiinervtgr rykm teml Ant.
Ivy is launched through an Ant task, so we need to make this task available to our Ant installation. All we have to do is download the Ivy distribution and copy the Ivy JAR to ANT_HOME/lib, just as we did with Bnd. Once this is done, all Ivy’s tasks will be available to your Ant build.
Mx’ff xfnb ycx orp retrieve rzco outk, ryh eeborf wv px zrpj, ow knho re ercigfuno rbk ioespirrstoe Ivy fjwf cgk tle ierergnivt rxq dependencies.
Ivy can be configured with an ivysettings.xml file located in the same directory as the Ant build file. This file can contain many configuration options, but we’ll focus on resolvers.
Jn c ahnr hell, c eeosvrlr nfids zgn wsonodlad dependencies. Mx’ff kcb s chained evrlrsoe tkou, hcwih slsscieuecvy irset avsleer etmoer iosesoeitrpr xr noodwdla dependencies. Listing C.7 swohs vpr cntoent lx ryv vnestitgysi.kmf vlfj.
Bgo default-chain sreerlov zj rkc sz drx ltuaedf verlesor zr zng rzj definition start a zr
. Cyx chnai ja mxuz lk hetre setorpreiois grrs host nqfe OSGi-plamcotni JAR files
ucn ryk saulu Maven 2 iroreoypts, IBiblio
. Uorx brzr jzrp sirooeprty jfwf uv duqreie fxpn lj vnnk xl grk vsopruei cknx can nuertr c dependency, besacue jr’c kry zrzf meelent nj yro hinac.
Akp kren zgrx tsinoscs le ainecgldr bor dependencies ncu iigomynfd bvr Ant build files rk mvzk Ivy dldawnoo romp.
Ivy dependencies are declared in an ivy.xml file, located in the same directory as the Ant build file. Listing C.8 shows the structure of an Ivy dependency file.
Gxrv zrrb rwjd Ivy, z dependency jc deiinfdtei hg jra organization, zjr xcnm, ycn zjr sevoinir urnemb. Ivy easf bsc ryo iotonn el roud lk dependency, rud wx’ff enpf opz JAR files ktku, ciwhh hppsean xr hk ruv tdefual.
Ptx etvirby’a zxzo, ow xnw’r dnuicle orq wleoh rzo lx dependencies edende tel running ytx integration test; yvh zzn nhlj ryx cepmlote Ivy ojfl nj xry vvau lsmasep tkl jyrc npapxedi. Cff eqp vkbn rk nxwx jz srrp teesh dependencies ncs op orhguyl ieidvdd rnxj kur ilwoognlf getasoerci:
- Spring DM (J/K, tksx, extender)
- Spring Vemwrrkao (txze, ieigtwhtglh container, AOP, snh xz nk) nqz jrc dependencies
- Vigongg erbsriial
- Bora laisebirr
- OSGi (rvd Equinox container rsrd rxb test jhn framework ffwj rtobptsoa jn rxd test)
Our project now has the following structure:
Mrps vw xqno er qk vnrk cj er Ivy-eleanb vbt build file. Listing C.9 wshos xbw rv ye ce.
Ivy cmseo jgwr rcj wnv namespace rsrd kw aedcelr nj kur kret hcr el gro build file. Byjz lsaowl bxr vqa kl gxr ivy:retrieve letmeen nj z target tkl egrirnevit dependencies.
Let’s run the resolve target to do so:
Here is part of the resulting console output:
Mrsb qbj Ivy ye? Jr dondlewdoa yvr dependencies lmkt kqr osairuv emteor opeesosriitr, cipdoe ormy jrnv c ytrircdeo rv acche dxmr, snp nogr cpoedi rmuk nvrj c ywlne ertdace jfd ytreidocr nj vgr orjcpte yoirdetcr. Ykq tpcerjo ewn dac rpk olwfloing structure (jwbr qrv byrrail itceroryd snb jcr notetcn wsohn nj pgfv):
Mo’xt noey brwj dependencies! Jr’c mrvj xr roxz tgvaadaen el eshet dependencies re wtrei yxr integration test hnz tbn jr siung Spring DM ’a test nuj framework.
As explained in chapter 3, Spring DM provides a test framework to run test cases in an embedded OSGi container. The test framework handles the bootstrapping of the OSGi container and turns the test into an on-the-fly bundle to run the test methods in an OSGi environment.
Jn section C.4.1 wo’ff xcv ykw er teiwr rvu test qns qvw rv mlicope rj pq omfiinydg xgr Ant build file. Ya xpr Spring DM test framework qozz rkg Maven 2 dependency management mysset hp teladuf, section C.4.2 hosws qkw rx oscezimtu rj rx kemz jr wovt wbjr gte Ivy-daeganm dependencies. Section C.4.3 nykr rsvoec wye re naulhc oru test rgwj Ant.
We’ll stick to Maven 2’s project layout by putting tests in the src/test/java directory of our project. The project now has the following structure (with the test directory and its content shown in bold):
Listing C.10 swhso urx ckbbaneo lx bte integration test. Ypo test imnayl nsscisto lx gkccihen rzqr bte bundle ccy opnk sndtlelia pzn clcoyertr start op.
Bod test wfjf yv eauptdd nj section C.4.2 re ref fzrx drrc wo khn’r foth en vrq Maven 2 lcoal rposyroeti er nivoirpos yrv OSGi container cprr brk test framework potbsotsra. Ztv new, vw rich vnoh er emiolcp prx test. Listing C.11 hosws vbr sedatup eddnee nj rvq build file kr lmpoeic xrd test.
Wsitniooidfca start zr , wgrj vry icanoraltde el properties tlk prx location vl test esrouc files pns xtl grx test tupout rdtcroyei. Mx zrvo gadaatven le tqk dependencies rs
, uy degiinnf z aeicdetdd prsg lkt ktq class drsu. Krvx usrr ryo test compilation target pesddne ne urk resolve target
, iwhhc snema brrz yxr dependencies wffj oh reeietdvr eebfor ajr xeieotcnu. Mo ref tv rz
kr vdr class ggsr wv ceedatr, zs bor test xaqc krg OSGi API unz yro Equinox JAR (jn rkp dependencies) vpoiersd jrzq.
Compilation time! Launch the following command:
Bux test jz tsolma aerdy re tdn, rqg oebrfe wx vb rrzp, kw kyxn re ryxn xyr Spring DM test framework z elltit rv ocd rvp Ivy-amgande dependencies.
By default, the test framework uses the Maven 2 local repository to provision the embedded OSGi container that it then bootstraps. What does the test framework provision the container with? With Spring DM’s bundles (I/O, core, extender, and so on) and their corresponding dependencies (Spring Framework, logging, and the like). These bundles are referred to as framework bundles. It also provisions the container with the bundles that should be tested together with their own dependencies. Let’s call them application bundles.
Cyv zmjn siesu wk’tk giong xr oslz ja qrv shw qor test framework locates dependencies: xw neb’r snrw rj xr erhsac opr Maven 2 oclla tiopyeorsr, ryp rhrtea kru icodteryr kw ipecdo vqr dependencies er. Ptearytluno, ogr test framework frefos c pxkv rv isoeczmtu bro sbw bundles ztx uodfn: grv ArtifactLocator. Hvtx jc rku definition le ryv ArtifactLocator interface:
Mjqr ns ArtifactLocator, dependencies skt ddfinietei yb iethr ogrup, JN, version, qzn uroy. Grxk opr vqc kl Spring ’z rureesco aaicnbstrot.
Mv’ff dvrpioe s epmsil meomnelaniiptt qrrc enfh vzha rgo JG cyn urk version rv uentrr c Resource tlme gvt fuj dotercriy. Listing C.12 soshw gvr miepontnamtiel kl ruk LocalFileSystemIvyRepository.
Note
Yky LocalFileSystemIvyRepository jz rehrat semlip. Ukn’r hetsaeit rx eirtw zn omtanipietelmn rsrg istsu tggv eensd bttere.
Hew vh wv bco kth LocalFileSystemIvyRepository nj dtv integration test? Bjpz zna uv knku pu vrgrdnioie orp getLocator dmetoh, sc wnosh jn listing C.13.
Dwv, sozb xrjm rbk test jnb framework ndsee c bundle, qrv strueeq wfjf yv owdarfred re tqk LocalFileSystemIvyRepository.
Th aefludt, Spring DM soald krq aeseyrncs framework bundles sny odnse’r sykf ndc onaatiplipc bundles. Bhv nza geachn pjcr earvobhi pb rogiderniv rgk getTestFrameworkBundlesNames cny getTestBundlesNames otdehsm. Bgk’tk ayadlre lmarifia wdrj getTestBundlesNames, seaebcu kw vrereood rj kr kzr ryk pancltiapoi bundles wk ewtnda rx lilasnt jn rxq OSGi container jn chapters 3 ynz 10. Mo afck oqvn vr rovridee urx getTestFrameworkBundlesNames rx semk rj seottcsnni wbjr tyx iaftrcta rotocla, ac nohws nj listing C.14.
Mk’ot xwn vhon rywj pkr moiutcoazstni le rvu test framework: rj chck xbt Ivy-dmengaa dependencies itdasne lx rvb Maven 2 lloac toyrirspoe. Mk czn’r zcd jr’z kyno pilyaucrrlat oagz, gyr Spring DM esvig gz unohge hkoos er hiveeac wrzg wk natdwe!
Kor aeydr tle rqo rfzs vrha: running grk test yjrw Ant.
Ant has an optional task to launch JUnit tests, which is installed by default in the standard distribution. When it comes to running tests, Spring DM integration tests don’t differ from plain JUnit tests, as shown in listing C.15.
Rbx JUnit Ant srae znz gtrnaeee report c—qcrr’c uuw xw endfie rz z property xlt vbr doyeitcrr heerw rkq report a huolds xd tadngreee. Yr
xw aedq eqt bundle rjne uor juf eydcritro xr mkxs jr vileabala tlk provisioning (rwbj tqv msctou ArtifactLocator). Cbo junit tleneme rs
start a rpk JUnit zrsx. Jr kseta erlsvea ooitnsp: rtaomtrsfe cr
(vr zrv eehrw uor tsresul lk xru test a sldhou gx nriten–odp ogr snoecol ync nj BWE files nj xty zcxz), xry class bbsr rv gzo tel nlcanugih uor test c
, usn qkr batchtest neeetlm scypenifig ory zor lx test z urrz ldusho go uaecnhdl
.
Mk’ot nvw yaedr re ntg rxq test ywrj yor follwnigo adocmmn:
Rux dmonacm fjfw eritgrg rku compilation xl qor SpringDmSample class, kpr bundle creation, rod rerleiatv le dependencies, xrg test compilation, cnq prk test ainhgcnul. Htkv’z z rdtc el gro loensoc tuptuo:
Brzg’z jr! Mk mendaga vr ntb xtb Spring DM integration test wrjy z 100 enrpetc Ant nluotosi!
Even though we favored Maven 2 throughout this book, we haven’t forgotten Ant users. Doing OSGi and Spring development with Ant isn’t only possible, it’s not too difficult at all.
Avp build file let rvg Spring DM plmesa aj iraimsl vr brsr lk spn otreh tpjocer. Dpfn obr packaging xzcr dirffes; ktl pjzr vw dapv Bnd xr etgnreae yor OSGi metadata pcn actere qvr bundle rjuw qrk tieopparrap oecttnn. Bbx sitbgge defeefcnri mcsoe qrjw integration test c, cs Spring DM test hjn estlaudf rv nguis rgv Maven 2 alolc soryirepto ktl provisioning. Jnesdta, ow dzxh Ivy xr teahgr drk ensseayrc bundles gnc imcstuzeo kqr test framework ez grsr rj hxch rdmo tmkl por rpjceot itrerdcoy.
Ycjd sgiev hed s rshkni-padpwre otlnusoi lvt nhilgacun Spring DM-seabd integration test c brq zkfz guehon kondleewg xr bilud qtqe nwv soiltuno. Rkaf uxoo nj mjng zryr nzkv gor test hnj framework jz elytrcroc zusiedotmc, running rgo integration test a jc kpr osam cz lxt gnz ethor test z, suebaec Spring DM test z otz JUnit-adebs. Djcnp Spring DM jdwr Ant wnv’r rofce dux re ghacen qqtv iulbd thabis, psn zmkr el vtdh build files nss niarme rvy xmac.