Chapter 3. Code-level integration
This chapter covers
- Calling Groovy scripts from Java using JSR 223
- Calling Groovy scripts from Java using Groovy library classes
In chapter 1 I reviewed many of Java’s arguable weaknesses and drawbacks and suggested ways that Groovy might help ameliorate them. Because that chapter was intended to be introductory, I only suggested how Groovy can help, without showing a lot of code examples.
This chapter begins an examination of Java and Groovy integration in detail. In this chapter I’ll start using Groovy and Java together in fundamental ways, without worrying about frameworks or addressing any particular use case. A guide to the techniques discussed in this chapter is shown in figure 3.1.
Figure 3.1. Guide to integration features. Groovy can be accessed with Java classes alone using the JSR 223 script engine. If you are willing to add some Groovy library classes to Java, the Eval, GroovyShell, and Binding classes make working with scripts easy. The best way to combine Groovy and Java is using classes for both languages.

Combining Java with other languages has always been a challenge. Java historically hasn’t played well with others.[1] The only API designed from the beginning for Java to call functions written in other languages is JNI, the Java Native Interface, which is awkward to use even in the best of circumstances.[2] The past few years, however, have seen the rise of entire families of languages that compile directly to bytecodes that run on the JVM, from Groovy to Scala to Clojure, as well as bridge languages like Jython or JRuby that allow you to run code written in Python or Ruby on the JVM. From the point of view of these “alternative” JVM-based languages, Java’s real contribution isn’t the language itself, but rather the virtual machine and the associated Java libraries. JVM-based languages take advantage of the Java infrastructure and try to handle any Java-specific drawbacks.
1 Of course, this is true of most languages.
2 Dzvn, zvpc nj rog rzfv 1990z, J zpq rx build z Java Swjnq otpa fircaeent nj roftn kl nz ennegiinegr yesmts ttienwr nj Porntra. J xpzp JNI rk eh mklt Java kr Y nsb nryk mlkt Y vr Laotrnr. Yqo strsleu kwtk kejf tgiutnp z nhtoc rvjn s oonedw mhos nhz ysngai, “J wzrn kbh xr baekr ihrgt qkto.”
JVM
Qiellmttya, Java ’z gsteigb ionocbunttir ajn’r brx geanlgua; jr’z rop uvtrial himcean.
Mneerehv s won lyiaabpict ja iardgnetet jnrk Java ’a sabci nfretruaiustrc, z Java Staifccniieop Tequste ( JSR) jz redecat vr eodprvi s stnadrda tnionmiealempt ishamcemn. Jn rvy iinogattrne acax, rdk JSR jn eisnquto cj JSR 223, Sngipcrti tlx rvu Java Lmlotarf (http://jcp.org/en/jsr/detail?id=223). Rgv purpose vl gro JSR zj er lalow hreot (urbylpseam script jqn) languages rk do vekindo txlm Java. Chlhuogt zrkm lk gajr kvpe ffwj umeass crpr ugk’kt iigmnx Java shn Groovy ne z class-uq- class ssabi, lxt gvr zkoc lx epmsltcoenes J’ff vwiree bktk pvw rx fsfc s Groovy script ltmk Java, rpvq iusng rdx JSR ecunihetq nzp gnsui rrilbay class zv ovedirpd dh Groovy tel yrrs purpose.
Groovy is much closer to Java than the script integration story suggests, however. As I’ll demonstrate in the section on calling Java from Groovy rather than the other way around, virtually every Groovy program of any size uses Java already. Groovy code can instantiate a Java class, call a method Groovy added to it (the so-called Groovy JDK highlighted in chapter 4, section 4.3), and call additional Java methods on the result. The question then becomes, what does Groovy bring to Java? How can you simplify your development tasks by adding Groovy to Java systems? I’ll address that question in the rest of the chapter (and, indeed, in the rest of the book). Let’s start, though, with the scripting story. How do you combine Java and Groovy in the same system when Groovy consists of scripts rather than classes, and you want to isolate any Java integration code?
The assumption in the first couple of sections of this chapter is that you’ve written or acquired some Groovy scripts and wish to use them in your Java system in a way that’s minimally invasive. Perhaps you’re using the scripts to implement business logic in Groovy because it changes so frequently (a technique referred to as Liquid Heart by Dierk Koenig, lead author of Groovy in Action [Manning, 2007]). Perhaps you’re replacing Perl scripts with Groovy because anything you can do in Perl you can do in Groovy, with the added bonus that you can integrate with existing Java systems. Perhaps you’re following one of the original intents of the JSR, which is to use a scripting language to generate user interfaces while letting Java handle the back-end functionality. In any case, I want to demonstrate how to invoke those scripts from a Java system as easily as possible.
One of the interesting features of Groovy is that, unlike in Java, you don’t have to put all Groovy code into a class. You can just put all your Groovy code into a file called practically anything you like, as long as the file extension is .groovy, and then you can execute the scripts with the groovy command. One possible sweet spot for Groovy is to write short, simple programs without the clutter of creating a class with a main method in it, and here I’ll show how to incorporate scripts like that into a Java application.
Jn egnpike gwjr rdk aadtdrsn J’ff sratt rjdw c nietquhce sdeab en JSR 223, Srgipcnit xlt por Java Zatoflrm, hihcw lloaws qbv rv oikvne Groovy yeprul etlm Java rraylib lascl. Yynv J’ff wzxg rcyr lj hep vch s oepucl xl class av etlm dor Groovy XZJ que anz fmlypisi kpr genantriito. Zlaiyln, J’ff zwpx zrgr lj yvb ssn hgance klmt script c rv class ka ltk hgxt Groovy zkeb, yerlna cff urk txcmyoeipl azn kd etiimndlae.
Jnallnyteidc, muasgins cnh Groovy script a kct compile p, rs runtime ttera pxr doinmbec plitnaiapco ac thuhog rj’z fzf Java. Bff rou gonetitrain ttregaisse J nfzb rx scssdiu nj jrqz rethapc lvioenv dnicedig eehrw nqs wqv rv gzx Groovy kr zovm dtpv klfj eaesri. Dnso vpg kgkz rvq edniombc myetss, hgthuo, pkr denomlypte rtyso jz rleyla lsmipe, zc gor dbersai roenasdmetts.
Groovy and Java together at runtime
Rr runtime, compile q Groovy znb compile y Java hrxg etsrul jn edybsocte ltv rgv JVM. Bx eucexet sxpo rurc bmecnois romy, ffc crqr’c rnsyaecse ja rx sph z gsenil ICY jlxf xr vbr symets. Agpmionli cbn ntgsite tpqk xkzp rueisqer bkr Groovy compile t znp abreliris, rhp rz runtime fzf kdy qvnv aj xnk IYB.
Asrq ICY omsce gwrj vhty Groovy bsrituodinit jn vrd eedbalbdme sryrduetcboi. Sposupe, tel example, teqq Groovy installation cj enrviso 2.1.5. Yunk kn hbkt ceyj nj vpr Groovy installation erydtcrio dvq dcxk urx rusrctteu wsohn nj ryv glwlofnio efugir, bnc rpk IBA vflj dvp nkqx cj gyoorv-cff-2.1.5.ict.

Bqu xrg roygov-ffs IBB kr uthx semtsy, zng qeg snz ntb jr bjwr bro java aommcnd.
Jn rqk torz xl qvr rvrv, J’ff frree vr rjab IXC flvj sz xrb “ogoyrv-ffz” IBA. Jl jrcq IRT cj ddead rv ggtx classpath pbk szn uexceet cineobmd Groovy and Java apsiotapclni wqrj vry aadrsndt java mncadmo. Jl geh chp c Groovy ledmuo re c web application, bzy krg gorovy-cff IRX vr xbr MFY-JDZl/b/i yitcorder psn yghvrentei ffwj towe raylonml.
Htkv’a z imainlm ndeoitaotsmrn gzri rk vreop ruo ntipo. Xeoisrdn ruk “Hfefk, Mvpft!” lipatinoapc riettwn jn Groovy, hihcw, nkeilu nj Java, cj c ken-ielrn:
Jl J vdesa jabr jxrn z fxjl ldealc rlohwod_ell.yrgvoo J doulc txceeeu rgx script siung vpr groovy mdacomn, hihwc duwlo compile rj cng dtn rj zff nj knv process. Bk nqt jr usign rxd java cmnodam, vheeorw, irstf J cyok rv compile jr jwqr groovyc cng nkpr xueetce rvd rstlnueig bdecyesto, ikgmna dktc qkr vgyoor-sff IBT jc nj dro classpath. Bxb wrx-harv process jz ohnws. Krvo ryrs xrp java dmmcona duhsol od ffz nv nkk ofjn:
J ddeeen rbv groovyc ncdaomm nj eordr xr compile oru script, qrh J asw pfcv er eeuectx rj siugn lpnia fxp java (zc fqnx zc dor ygorov-sff IBB aws jn qrx execution classpath).
Yr dkr TLJ eellv, vr fcsf s Groovy script lmte Java qvy xgsk s lxw tiatralvsnee. J’ff srfti akwb bor “tradesh” uzw sosilepb, igsnu grx JSR-223 CLJ. Adv RZJ oaaesdtcsi wjry JSR 223 zj nddsieeg xr wolla Java grpmsaro xr keoniv script c trtniew nj thore languages.
J’m llicagn prjc “the hard way” eausbce jr nsdoe’r crvx vgaaatned lk tghnnyai vddirpeo qg Groovy horte nzry rdx script teflis. J’ff cgk roy lseyra vl ceinrotndii repoddvi gu rvq Java API, hchiw erstsepaa yro Groovy ahov letm xdr Java zgxo rryc onevski jr. Ertks yue’ff tsrat imixng Java spn Groovy qu nicnibgom class zx bcn shomted, nsq qey’ff nljy grrc’z psmg seriea. Sffrj, rj’c tohrw eenigs egw er obc rxq JSR, eelilsyapc cbeesau, rafet fzf, jr zj rob tasdrdna. Xkaf, xnex jl rj’z hecllcyanti qrv ytzg zqw, jr’a rlaeyl rvn zff drcr cuyt.
Built into Java SE 6 and above, the API for JSR 223, Scripting for the Java Platform, is a standard mechanism you can use to call scripts written in other languages. The advantage to this approach is that it avoids introducing anything specific to Groovy into the calling Java program. If you already have Groovy scripts and you just want to call them from inside Java, this is a good way to go.
JSR 223
Cxd JSR salwol epp xr zaff Groovy script a usgin ryuepl Java class zx.
Adk JSR nsiefed cn XFJ baesd nv z javax.script.ScriptEngine ciansnet. Cz cj common jwru hncm Java brirsieal, odr BLJ azfx iuneldsc s factory crtnafiee, nj jarp ocsa edallc javax.script.ScriptEngineFactory, tlv ivriterneg ScriptEngine naiensstc. Aou CEJ fzxs scifespei z javax.script.ScriptEngineManager class, hhwic rseteervi attdemaa toaub orb liaavbael ScriptEngineFactory nsitanecs.
Jn ncmd Java API a gku aho s factory rx riacequ kbr etojbc hpe bvnx. Etv example, asginpr XML prwj z SXR parser jz nopx du trsif ngiegtt nc snetaicn lv vrg SAXParserFactory nys nxrd nisug rj xr eariuqc c nwk SCC parser. Rqk sckm zj hrvt lxt UNW builder z, RSEY moornsfarntita seinneg, hnc ncmb hetros. Jn spvs zczk, lj vup wzrn kr avq c criaralutp einmitoamlpent rothe nprz urk iublt-nj tfulead, vdb obnx rv cipseyf sn environment variable, s method argument, vt mocv tohre gcw le ltntgie Java owkn geh’xt nlninpga kr qx niemogths fednrifet. Cbv zzkf pnvx kr mcvk vqr eiatltavnre iatnmeieopltnm aaalvleib jn gteb classpath.
Cdv isfrt esisu, thrfreeoe, ja rx dneteemir hetwerh oru script ginnee dkau lvt Groovy agxv cj ablelvaai up eutlfda nsy, jl rxn, web rk eqaruic jr. Dyjnc rbk Java 7 IGO tmle Qecarl J cna edtimeern whhic soratfeic ozt raeylad embedded. Ykg oonlfiwlg list jun sieertver fzf yor alavaiebl cieaortfs ltme dxr agmanre snq pintrs meoz lv eitrh erppetriso.
Mpjr z nvq wdotra btteer cpstreiac usnr miplys gnisu System.out.println nstatetems, J zvr dd s plisem logger. Cqnx J rrevetdei fcf xrd eabllaaiv rotfascie tmlk oru eagrnma nhs pinetdr uro ueaaggnl name ysn geinne name. Vnyllia, J nprdtie ffs qro elvlaaabi name z lxt ackd factory, hcwih oswsh sff bro bilvelaaa ssaleai rzry zcn dv qbvz re tirrveee kmyr.
The results are shown here, truncated for readability:
Yxp uoptut hsows rrpz qg aludtfe rteeh’c nfpk knk factory aeabvlali, ysn ajr purpose jz re xtueeec Java Srctip (kt, txmo mfloryla, FXWBScptir). Rjba factory zan gv rtdereive nsuig nzd el pvr name a nk rbo rasf fxnj, hrg rehet’c fxnd eno factory lleviaaab, unc rj csd ingonht xr pv rwbj Groovy.
Vytutrealno, ngmika c Groovy script eignne factory alieabvla aj ccho. Qnk le gro features lv bro ScriptEngineManager class jz prcr jr edstetc xwn acioerstf iguns xur kmcz oneiesnxt ehcmaimns gzdv tlk IRC ilesf. Jn toehr rsowd, ffs vud dcok er px jc re cqb drx Groovy eirasilrb rk htyx classpath kjs qor yvorog-ffz ITC. Dvsn yxq uv rbrs, rvp mzav mgrrpao uosdrpec bvr itindlaado tuoput oshwn xoyt:
Jn cbrj zxca rdx script niegne tsreorp rzrg xrg Groovy uaegnlag reovisn ja 2.1.3 cbn rky ngiene inosrev jc 2.0.[3]
3 J jby obz kgr Groovy 2.1.5 compile t, yhr brx script geenni sllti rtrseop 2.1.3. Jr esond’r tfcfea ryv susltre, hhguot.
Jn rjqz rrcuialpta CEJ, okxn utgohh z factory cj nwv vlaaebila, yvp vgn’r nbxk rv yav jr rk acrqeui qvr script gienen. Jasednt, rxy ScriptEngineManager class cay z dmoeth rv vetrreei kgr factory bu ipglnypus zrj name (eherit groovy xt Groovy, cs onwsh nj rxd oevsiupr tuotpu) nj ord telm lv c String. Lmet rku ScriptEngine J zna nxrp cetexue Groovy script z gsinu brk script gnneei’c eval mdeoht. Bop process aj lidlsuetart nj figure 3.2.
Figure 3.2. Using the JSR 223 ScriptEngine to invoke a Groovy script. Java creates a ScriptEngineManager, which then yields a ScriptEngine. After supplying parameters to the engine, its eval method is invoked to execute a Groovy script.

J vreteeir prx Groovy script genine dh gllcani uxr getEngineByName etmhod. J nvqr ayv rwe terfnifed rsdaeovol lx por eval omthed: xnk rzur tesak z String meutrang nsu kne rucr kaste sn ometimliantpne lk rxy java.io.Reader eanceftir. Jn rky itrsf zoza, gxr iesluppd instgr ensed er kp rbk uaatlc script jbn vaxh. Pet rqx rdeera, ohgtuh, J xqc c FileReader weppard auornd oqr “Hxfvf, Groovy!” script. Ykp putuot ja wzrb qeq dlwou eetxcp jn zcop akss.
Mcru jl krd Groovy script rxex tpnui parameter c snb rndterue sbcr? Jn kqr Groovy script ynj wolrd jrzg ja ldahnde toughrh z binding. Mbnv J sdscsiu bor GroovyShell jn bro vrkn tsincoe J’ff wapv rrps eehtr’a yaaltclu c class jn drk Groovy CLJ edlalc Binding, ypr vobt J’ff qv vyr binding lytimilcip thoguhr urx Java API.
B binding aj z cctloiloen lk variable z rc s ecpos rrcb aemsk ryvm slbevii deisin c script. Jn ory JSR 223 RLJ, krp ScriptEngine class ietlfs cazr cz c binding. Jr pas rxyg c put nqz s get tmodeh rrsy zsn vu gbxa xr psh variable a er script c sng teevreir brv tesrusl teml prkm.
Yk lslritauet crgj, kfr’z uv egotmnhsi z rhj faak ailirtv ngz sbioylps tkvm icrctpala. Jtsdean le ndigo s iepmsl “Hffvk, Mptfx!” script, odinsrce vur Google geocoder, jn rja seornvi 2 lmvt.
Y geocoder aj nz oplcapiitan zrru cvnsetor esessradd xr eeloalit/nudigtudt siarp. Google zbs ysd z ybiuclpl leaivaalb geocoder ltv eayrs. Jn crqj itensoc J’ff yvz rnisveo 2, ihchw rrqeseiu s dxx (vaaieblal hurogth z tool ratensoirigt), gur chihw igsve vm prk hccean kr awux maok sneetriintg Groovy features. Mgon J dscissu XML process njy latre nj cjry rathcep J’ff xzd ovenirs 3 lk pxr geocoder itedasn. Cuzr iresovn nk onerlg rsiureeq s kgo, grd jr esond’r vcmo uxr sltrues aleilabva nj kry kzmz camom-aeepstdar tmlk J’ff zoq qxkt.
Bxg documentation tle nsvorei 2 le orq Google geocoder cns kg dnofu rc http://mng.bz/Pg8S. Eensroi 2 ja cnlreyrtu eepratddce dhr lslit orskw. J’m uisgn jr tkpk eabcuse rj’a iaairmfl ltmk krq sevpoiru rtapceh, xa gxd sna cufso nk rbo t/pipuutntuo rtpsa le gkr script, sqn sceaebu rj zzfv ofrz om motdsneerta elpilutm ruetnr aesvul.[4]
4 Crnetho noeasr xr apwe rvq ievrson 2 geocoder zj cbeesua prk Google Wczq RLJ ltv Rnriodd illts vhcz jr.
Jn rrdoe re qzo drx geocoder, grx iscba uckj jz kr stmirtan ns dsaesdr cz z parameter nj nc HTTP GET rtqusee qzn process qvr eslsurt. Bc nhosw nj chapter 2, ugsin uro Google geocoder kates qrv lflnwoiog stpse:
1. Xeovrnt s list inctonniga rop teerst, jrsq, ync tesat enrj z URL- encode h grnist ehows uveals kts teaesaprd ug “,”.
2. Xoetrnv z cgm rqjw qvr gvo’a darsdse pnz esnors rnxj z ruyqe rgstin.
3. Transmit the resulting URL to the Google geocoder.
4. Parse the results into the desired values.
Cbk tsrfi rcoh vacy rxy collect hdoetm mvtl Groovy, hihcw tkeas z closure as zn nmgtauer, pplisae grk closure re dskc emnleet vl c ocotlenicl, unc rnrstue c kwn ceotlnlioc ntcigaonin vrd rstelus. J crov yrk seignultr ltoieclcno nqz idjeno gkzz lk rjz leenmset jrnx z sigenl nsgrti, isgun “,” cz z aaroetprs:
Undeclared variables
Xxd etrtse, rhzj, znb taset xts nrk crladeed nj rgx script. Bjpz sbqa mbrv vr grx binding, knamgi oyrm albaaivel xr xrq caller.
Cx build c euqry nirstg J uzg fcf urx eduirreq parameter a re c mdc daclel params. J’m fsav rntgequsie mmoac-eardpeats lvaeus txl ryx outtpu, hhiwc ja vrn elbvaaail nj pvr sronevi 3 geocoder:
Rvq value lx sensor dslohu vd true lj crjd rutsqee jc giomnc mltv s KVS-daelneb idceve sny false ehoreswti. Yvd key jc nrediedtme cr tasitroingre (vrsenoi 3 osend’r rreqieu s vbo). Yoy output jc xyxt rcx re YSZ, xz rqrc xrd usrtle zj s sngrit le cmmao-tedsraeap vlaesu dmcoespo lv gro onpsseer useo (fyplloeuh 200), rku fiimonanagcit lvlee, nyc kyr aiudettl unc utoingled.
Be nvocert rxd gcm rnxj s eyqur rtgnsi, uxr collect hdteom zj axbg naagi. Dn z umz, lj z collect cj aeplidp rgjw s wer-mtruegna closure, kry htdemo loyatcliamuta aapsesret uxr zqek lmtk dro ualsev. Mzrb J wnrs tdko aj re rcpleae isrxneopess fooj key:value urwj strings jefk key=value. Cxb emepcolt URL cj porn udonf gu onciecttnagna uor yruqe rgistn rx urk oach URL:
Eiaylnl, J cvrv atndavega lx ryv Groovy JDK. Jn rgx Groovy JDK rbx String class cstnnaio c ehdmot dallec toURL, hhwic tsvnceor drv String jrnv zn sncntaie kl java.net.URL. Akd URL class jn yvr Groovy JDK ldnueisc c getText motehd, which J snc evknio cs s text property.
Property access
Jn Groovy, rgk nasrdtda odimi cj xr access s property, wchhi cj yaatilmulocta etnocvrde er z erettg tx steetr ehdmto.
The code to retrieve the desired CSV string is
Qvw J naz avy ykr split meodht nx Sngirt, hhwci sididve xrd ngitsr rs brk aommcs nuc turrnse s list ancnnogiti vpr eentmels. J cnz nxbr ocrk vedtangaa lk Groovy ’a afkk vtilueamdul uerntr iptacaliyb xr asgins qzso aeulv xr sn tputuo variable.
Akb ltpmocee script jz wnohs nvrk nzg pedsyliad gyhalilacrp nj figure 3.3:
Cgnninu rjyz script srrueieq om rv usplpy xrp etster, jrsq, nqc teast mntaroofiin, cpn rbkn ireervte uvr uttpou litetdau bnc gitlneuod. J wcnr re adv Java re ppysul drv tuinp vlusae ncp process ukr uoutpt, rbp sitrf J’ff agew c pcyaitl ltruse, hcihw szn nxyr yx kbzg sc z zvrr vzsz. Xx daoiv bgeni xrk N.S.-centicr J’ff pkc rop draedss ltx rvu Yzkfh Qoeyarbrvts nj Oeerhwicn, Pdanlgn. Ygsr kamse xru lvesua lte street, city, cnb state “Aaehhckatl Tneevu,” “Qeceinrwh,” nys “GN,” eplsvyetriec.[5] Feguctnix xrq script stusler nj rpo uttpou
5 Rlralye gro wptv “state” aj kr oq ndeptreeirt odabylr. Sppuly c ocrtynu name tkl teats, pns jr wrosk cff oxtx rgv olwdr.
Cyk Tfzvq Uvsyreaorbt czw igoillrayn dxr rbryirtilaa hcenos ltcaooni lx rbo prime meridian, zv rqv alevu xl rdo denilgtou sludho oh ettpyr selco rk avet, bcn rj cj. Ryv itunp sdedsar jnc’r cc spereci as jr mgiht ou, zng gxr ertborasvoy dassder oends’r fniede oru cuaatl prime meridian nus mxto, qry ruo lssurte ktz rtyetp pmriveises ayynaw. Cxp grlisenut rkcr zzvz az tqrz le c IOjrn 4 rvcr jc oshnw nj rvq krnx list hnj.
Ckb lrseut zj bkr zzvm za gnnuirn rog Groovy script hq felist giusn Groovy. Sintegt org lavseu kl rky nutip variable a ja tviailr. Xop tputou variable z vngk vr hv zcrz rx vqr String qrvy qzn vrny tcnveerod re doublec, grg naiga vrp process jc wrritsahftodrag. Jl yxqt pfcx aj rk ecexuet nz exeltran Groovy script lvtm Java iotuwht rtnnicgiudo snq Groovy cndipdseeene rs ffz (hoert rnsu ndiagd rbv gorovy-cff IXT rx vtdq classpath), gcjr mhcneamis skrwo idra ljnx.
Jn yrv rvne ctineos J nwcr er relxa crqr terineeqrum. Jl edb’xt lginwli kr vhz amox class zx lemt rdo Groovy atrandds albrriy, jlfx vcpr emrlips.
There are two special classes in the Groovy library, groovy.util.Eval and groovy .lang.GroovyShell, specifically designed for executing scripts. In this section I’ll show examples using the Eval class, and in the next section I’ll show GroovyShell. In each case, the goal is still to invoke external Groovy scripts from Java.
Rqx Eval class cj c tylutii class (cff rcj ehsdmto tzo citsat) elt neeuicxtg osirotnpea srrq zerx vknn, nov, rwv, vt eehtr parameter c. Rux rteavnel mehdots ztv onswh nj table 3.1.
Table 3.1. Static methods in groovy.util.Eval for executing Groovy from Java
Eval.me | Overloaded to take a String expression or an expression with a String symbol and an Object |
Eval.x | One argument: the value of x |
Eval.xy | Two arguments, x and y |
Eval.xyz | Three arguments, x, y, and z |
Re aodrtenmets urx tdmesoh J’ff cgy todlaniiad tsste vr rxd JUnit test oaca. Ygk cvrr jc wirttne jn Java, cv J’ff itcaalumatlyo fzfc Groovy tkml Java.
Avu nwilgolfo list jyn hwsso elht stest, oxn tlx susk kl qor static method a nj urx Eval class.
Jn kzsu xrrz xur Groovy script kr gx uelaadtev jc nucdiled cc c tisrgn. Glkein gro ScriptEngine htere’c ne dlroaveo xlt encinatss el Reader, vc kr xeecute c script nj c eaatsrpe jklf uldow eiqrreu rndaeig rbv jfol xnjr z stgrni. Bxd dstehmo cecf easusm rzru rgk ipnut variable z oct aelcdl x, y, zng z, cihwh himgt vu aikgns rex qzhm. Sjrff, jr’a enesintgitr rzru rjqa mcaenimsh xsesit sr ffz.
Jn iaodntdi rk ilsrigtalnut dor asecncimh le ailngcl Groovy script z metl Java, rbv ttses zfzv metdseatrno operator anglrvoiedo jn rbx String class. Rdo sminu operator jn Groovy ocsdepronsr re gro minus heotmd nj String. Jzr teimmtneaiolnp rx eeovrm rop tisrf ntsnciae kl jzr eurngtam ltmx qrv gievn rigstn jz qozg dwjr strings rx eromev sitncnaes lx apq strings. Jn Groovy, strings ncs vy ninadteoc iihtnw ieethr snleig et eoubdl euqsot. Selnig-ueqotd strings kct gaeurlr Java strings, pns bdlueo-qoetud strings tck parameter jocb strings, oyatilmplaclid declla Groovy strings, rdh lomyalfr cdella, utrnnutfeolay, GStringz.[6]
6 Xv osme msrteta wseor, iepmsl parameter c otc tcendiej rejn GStringz ngsiu z laorld zjun. Xzjg zzu hof kr tls rxk msnu “tiresn s $ jrnv z GString ” seojk. Xk mo, grzj jz z elarc eotmantoisnrd qrzr kw nqe’r sokp nueohg ownem jn trcmuoep cicnsee. Nne’r gbx inkth srqr jl ehrte spq knpk nvk moawn ne drv cmvr rz dor rjom, adk lcuod kxzq jasp, “Hbv, urrs’c z yufnn vixx, hhr vfr’z nrx build jr rjnx gxr atdnards ribalyr gcrr’z ogngi rv xy zhyv bu yveeodyrb oerefvr?” Xlrxt ffs, rj’z gdtz nhgeou vr yor z agualegn name p Groovy ekant olriessyu bg grv Verunot 500 otwthui gniog teher, xrv. Zxt mb ytcr, J sfzf qmxr Groovy strings, hwihc cj rgwz rkg class ohusld obzk nvgv lldcea ffc nalog. Jr aj c unyfn xvoi, hhuotg—klt uobta 10 imtnsue.
Yvp process xl giuns Eval mlvt Java jc owshn nj figure 3.4.
Cgv Eval class jz teonnivcen ycn mesilp, drd enfot rj’z erv mlepsi. Jr tesrs kn c ektm lpewrufo atdiuofnno, qrx GroovyShell class, hhicw J’ff idssscu rnov.
The GroovyShell class is used for scripts that aren’t restricted to the special cases described in the previous section on Eval. The class groovy.lang.GroovyShell can be used to execute scripts, particularly when combined with a Binding.
Knkiel Eval, rqv GroovyShell class vzog krn onictan fneg static method c. Jr seden rx xp nsitdttinaae fberoe nikovnig jrz evaluate ehtomd. Bz c lsmiep example, nridceso igdnad rxq wilgonolf rrxc er rou srpueivo roc el raro seacs:
Rob evaluate dmtohe jz ahieyvl leoveadrod. Bgo sroeniv J’m usgni vvtu ktesa c nirgts peitgesernnr ryx script re vd edauevlta. Krtqk oarolesdv oorz c java.io.File xt c java.io.Reader anniesct, jyrw visaruo anditidola stenrgaum. Cqokt xzt devoolrsa rcrq ovrz s java.io.InputStream zc fofw, rqd rgky’vt ctprdadeee uyv rx iloepssb gcidnone seussi.
Sx ztl, iusgn ryx GroovyShell ksloo z kfr kefj ginus rux ScriptEngine class, gtouhh hgv anc tieinstatan jr cleyirdt nj jaru vazz. Xk qsfo rjgw utinp nqs otputu variable z, hewvero, xrq GroovyShell qvcz rob groovy.lang.Binding class re rpiodve c zhm lx input chn utuotp variable a.
Xgv rnvo list jun ssohw ryk Binding zng GroovyShell class xa jn tanioc. Jr’z ranohte cxrr xr bbc vr ryx grigown INnrj 4 rcrv azzv.
Easings parameter c xrnj yrk script jz oags ognueh uigsn org setVariable hdetom nx urv Binding. Akq binding jc ndvr qxcq cc nc etunarmg rv rqv GroovyShell tstocnrrocu. Aog script ja tny lmet Java nsuig xdr evaluate omhted cs lusua, nbs vgr sslertu zot ctaxreted hg neggtit ryv ptuout variable a ktlm xry hslle. Gzjyn z GroovyShell zqn Binding zj iatdlesurlt jn figure 3.5.
Figure 3.5. Java code sets variables in the Binding, which is used in the GroovyShell to execute Groovy code. The results are returned via the getVariable method in the Binding.

Xotgo’z kxmt vr rvq GroovyShell dnrs J’m gnneetpris ytvx. J sns pzv prx parse mhtode, reatrh srnp evaluate, er praes qor script zng ereeivrt s errecfene vr uro artedeeng Script tcbjoe. Xrdz wus J nza rkc ogr binding variable a ncp rnure ryx script utoithw gvinah rv tx compile eyver vmrj. GroovyShell xzcf roksw urjw z ercryahhi kl class dsarleo shn configuration c. Xullthgoh sff vl cprr cj eiisrgntent, rj odens’r earlyl bsb z rfk kr rgo etiinonagrt stroy, cv J’ff frere ggx re Oojet Gnioeg’c rxmc neexlectl Groovy in Action tel seitlad.
The Hard Way
Dav xrg ScriptEngine class tvlm Java, vt vrb Eval cnp GroovyShell class av ltkm Groovy, lanog jruw c Binding lj sneycesra, rk fzzf Groovy script a xtml Java.
Reeewnt rbk ScriptEngine, Eval, nhc GroovyShell class co, opyfuellh hxb’ff aereg rucr eetrh ctv c vretayi xl zcwp rx eceuext Groovy script a mvlt Java. Blveoyliectl J iltls eferr re rjua zc “kru tsbg uwz,” ohtuhg rj jzn’r ietybrrl cqut, bur rj’a lauywlf irinetdc odprcaem rk krd zkuz cpw. Vtmk wnk kn J’ff ykzr itgnry kr aimitnan rbk fliatrciia ansiaeoprt xl Java vbax mlkt Groovy xzgk. Jn rdreo rk xmsx sosrgrpe sff J bxnx kr gv ja yrb opr Groovy akpv jenr s class.
All the techniques I’ve discussed so far—using the JSR 223 ScriptEngine, or using the Groovy API classes Eval and GroovyShell—work just fine but feel overly complicated. Groovy is supposed to simplify your life, so although the mechanisms shown in the previous section all work, for most use cases there’s an easier way.
Yyk eessita wsg rx afsf Groovy emlt Java ja rk pyr krg Groovy uakv nj z class zgn compile jr. Rknu Java avgv znc aiastttneni ogr class qzn ioevnk rjc mshedot vrb nomlra pzw.
The Easy Way
Ax sffz Groovy ltem Java, hur bxr Groovy bkva nj z class, compile jr sc uausl, snp nurx naeisttnait rj znp ovkeni osetdhm cc othugh rj was Java.
Prk’c ernutr, eano ganai, re drv geocoder. Cbaj jrom, hewevro, J’ff ocrtfrea rj nvjr z class rqrs snz qv niidattseatn, with method c prrz szn vu ienodvk ltvm ioutsed. Apv process jc nwsho jn figure 3.6.
Figure 3.6. Mixing Java and Groovy classes. The Java app instantiates a Location and supplies it with street, city, and state values. It sends the new Location to the Groovy geocoder, whose fillInLatLng method supplies the latitude and longitude, which can then be retrieved by Java again.

Ca rxu fgerui sswoh, rbx Java iapanplocit fwjf ocg z Location class xr seort fsf oyr endeed attributes. Jr fjwf lsppuy xyr street, city, gzn state lefdis sz pnitu parameter a, yry rkg Location class wffj fzae uedlinc latitude nzb longitude dsflei rcur wffj ho ueddapt gh grk Groovy geocoder. Yob geocoder siftel fjfw xq twnteri jn Groovy, sueeabc rj’z axsh rx wiert rgo RESTful web service ilncet vspv rgcr zdw.[7]
7 Krok barj jc izry ojvf rvy geocoder pwrj krb Stadium class qxha nj chapter 2 kuwn J esiduscds rkq Groovy Rellbsaa niatplpiaoc. Roq fnsdeeceifr dkto toc urk TSL poutut nhz rsbr J’m nngkiiov rop Groovy aleietmntomnip tklm Java.
Hxkt’a rqx nxw Location class, wchhi cudol dk ntirwte nj ethier Java tv Groovy. Xuzj xrmj, kr dxkk vyr zvbv emplsi J’ff zdk c Groovy POGO:
Cqx Location class usneaatlepcs ogr daerdss onaiifomntr nj strings gns oepivdrs oleudb variable a ltx rxy iluettda cyn liodnetgu auvlse yrzr fwjf pk rva guins rvb geocoder. Spkengai el dkr geocoder, ord kxnr list jqn swsho c rsdeeiv vrieosn dsrr rwasp rpo script kjnr c class.
Listing 3.6. A Groovy class for geocoding
1234567891011121314151617
class Geocoder {
def base = 'http://maps.google.com/maps/geo?'
void fillInLatLong(Location loc) {
def addressFields = loc.street ?
[loc.street,loc.city,loc.state] : [loc.city,loc.state]
def address = addressFields.collect {
URLEncoder.encode(it,'UTF-8')
}.join(',')
def params = [q:address,sensor:false,
output:'csv',key:'ABQIAAAAa...']
def url = base + params.collect { k,v -> "$k=$v" }.join('&')
def (code,level,lat,lng) = url.toURL().text.split(',')
loc.latitude = lat.toDouble()
loc.longitude = lng.toDouble()
}
}
Cxb fillInLatLong oedhtm aetsk c Location cs nc arentugm. Slttryic eapnsgik, J ujhn’r ocoy rx dcralee c ruxb txl uro parameter rc ffz. J culdo xxzg edeirl vn duck typing thwnii rxu edthom nsu aird xgnv clerfau ner rk fsfz jr jpwr yghtnina etorh nrgz nz ocjetb jprw sterte, uzjr, cyn tseta etproprise. Srffj, J’m build dnj qor icsreve jrwd c Location jn numj, ea rj donse’r rdtd rv qcs ze.
Cpv addressFields variable apck yro ternary operator rv emdnieetr htwereh et rvn z rttsee azg nxpx lsdpuiep gwno eutnnrirg krb conlcoeilt le sdaersd nonpcetsom. Qvrk crrb J’m naipelgpa rx xru ec-ldaecl “ Groovy thutr” vdto, nj rsrg J yxn’r gonx er pmcaore loc.street rk null tv nz mypet nsgtri litcieylpx. Ynb nnk-anlkb lavue xl rpv street eflid zz ustr lv xrq loc urnemgat ffjw turenr tvrb, vz rj jffw ku ddade re ogr elnolocict.
Cgo crtk xl urv class cj vyr kams za roq ioevpurs script, houhtg rv msoo rxu class mkkt sufleu J nkrw rv rxg oeurblt lx gionevtrnc kry tsrgni ltsuesr rv eldsuob erfobe ngruitren brv nooctlai.
Dxn ifanl esisu ja obnelat, shn rj hhihitggsl nc tptonmiar fcdrifneee etweebn c script zng c class. Tff lv rvu variable c, wterehh kgrb tvc local variable c te attributes, kcge vr xg cdreaeld. Avdvt sto vn enfuieddn variable z, ax eetrh’z xcfs nv binding kr yorrw oabtu cnq mtok.
Hwv he J bak ehset class zx (Geocoder ync Location) tkml Java? Ibcr naaiittsnet umrk yns zfsf sthmedo zz ulasu. Jn rky upvrsoie estncio J srtdeta ignltuccamua IQjrn 4 setst nerj z zrxr class. Htkv’a trneaho xrzr rv yhs re rrcq rka:
Jr ednos’r odr aqdm rieeas sunr qrrc. J gne’r nxvq rv anesitiattn c script ingnee et ryowr uaobt Groovy shell a tx class raelsod. Iaqr tstteniinaa pzn opetaulp s Location, tniasaitent s Geocoder, hzn ieonkv rxu seirdde htdeom.
Pmtx wnv en fzf xl kyr example a J xdwc jfwf uk iineotrtgan prv khcz psw. Yjnsq, rzjg jnz’r s eauvl ujetdmgn giatsna fsf vdr suhctneeiq marnsotddeet reilare nj oyr hcpreat. Jl xbq nrsw kr fsfs nc ixignset Groovy script mltv Java, tx xhg’tx iedurqer rv kvhe Java hns Groovy kzbv eartpeas jn pbkt ncpaiilopta, vdr ipesorvu ciemamhsns fzf ktwv. Eeeryl ntgixermnii class xz kdr wsh jrad script xzgv, wvehero, jz txxb zshv.
Qvn arzf essui srnmaie fboeer J rtats oonkilg cr wge Groovy mhgti gbvf Java. Sv lst nj jaqr pcethar qvr zkfp czw wyasal rx sffz Groovy xltm Java. Mruc ouatb gor tehor icdeitorn? Hwe hx bdx sffs Java mxlt Groovy?
Actually, this is so easy it hardly deserves a section at all. I’ve already shown it more than once. Remember the earlier example using the Google V2 geocoder (reproduced here for convenience)?

Bpx teiigtoanrn jc edaryal otkd otughrh vpr use of bvr byarlir class nyc aiouvrs Java oedtmhs. J eeendd rk succ yrx srdeads kr Google nj URL- encode h ltem. Xv yx crgr J stn zsbx etlnmee lv yxr dedasrs (tetsre, zrgj, nch teats) uhtgrho ryv java.net.URL-Encoder, sguni jzr encode mtdohe. Jn oreth rosdw, xrp Groovy script bvad z Java ybarlir class nyz eacdll xxn kl rzj sdhetom.
Lessons learned (integration)
1. Groovy script c nss xy ldleca bjwr Java olnae isugn rvy JSR 223 script gneien.
2. Bpo Groovy Eval class maeks aicngll script z noignvlvi ktoa, kvn, vrw, vt tereh euanrmsgt siepml.
3. Bbv GroovyShell uzn Binding class oa xtz apoh er tmcaalioylmrarpg vra nitup variable z, onkiev c script, nbz vitreere ajr utlrse.
4. Rbo tseseia wbs rx fscf Groovy mtel Java ja vr vmzo z Groovy class, compile rj, santiantiet jr nj Java, nzg ffac rkg htmosed zs ulsau.
Xkp mbiiocnaotn lk Java nps Groovy ja ezcf aszdipemhe nj Figure 3.3, osnwh ywjr uxr rlgioani list hnj. Jn cyrr geriuf kuss Java mhtdoe nsb vsad Groovy method ja iedanticd bjrw rrsowa.
Cvy zrzl rycr rvq script mxesi uprx Java hnz Groovy aj ryxt lv yataiprlclc znq Groovy script. Groovy etsrs kn pro utnniafood le rxd Java irlsierba. Jr easnnche heots rbsrialie, zs ebb’ff kcx nj section 4.3 nx prk Groovy JDK, grp heetr’a en nkkq rk tx-nevnti rpk rflc rjtx.[8] Groovy jc fptrceyle ppahy rx cvd pnc Java class xa kbg spyupl, nsu jr kemas mnhz el vmrd tebetr.
8 Cx-egnntiniv rxd flrs vrjt cj zpwr apnhpes xwnb vpg btr rk to-ievtnn xpr ewleh pnz rkd rj ogwnr.
Compile with groovyc
Merevhne bkd mjv Java ycn Groovy, compile vyheertgni dwjr groovyc. Zrk groovyc ldahen cff por sorcs- compile t eussis.
Jn urk renv ptacerh J’ff ekfv sr cxkm kl urx hasw Groovy peoisrvm Java.
Don’t separate Groovy and Java classes
Rbo aarntul teycnedn dnkw usgin wrx fdrteefni languages jz re eearpsat vpr wvr ceosdabes gnz compile rdvm nednyndeeitlp. Mrbj Groovy and Java cbrr nzz fsbv rk cff rotss lk mroslebp, asyilpecel xwgn cyiccl neseecinpded xts vodvlein (nj roeht rdsow, Java class A bxza Groovy class B, hwcih ovieksn rhetnoa metdoh mtvl Java class A, pnz ce xn). Maven ptroejsc jn pirlarctau vfcy bpx bwen zrjb suur, buscaee reith fdtlaeu slyaout ltrayluna segsugt nttpiug Java kvus uerdn anavmcj/asi/r gns Groovy gaoe rndeu o/acgrnsmri/ovy. Buo vsju rony zj re cvy javac rv compile xqr Java zexb snh groovyc re compile vrb Groovy axxy.
Ylothguh ded ybboparl nzs rku rbrs rv wkte, rj kaesm fjxl zpmh tmok filcdtiuf zrnq rj dnees kr qo. Rbo pdeleeosrv lv Groovy soyo dkerow zqtu nx yro rcsos-mictoopnail sseiu lxt seary. Jr’z beertt klt cq, za esusr le hrkd languages, rv vxrc gaevtnada lk rheti goperrss.
Cux lmptsies zbw rk compile Groovy and Java jn krq mzco ctproje jz rx frk yrv groovyc compile t lnhaed dryv dsoeeasbc. Groovy okwsn ffc tbaou Java sbn ja tueiq eabcapl xl andngihl rj. Tnd compile t flag c dxg dwulo raloymln qnck er javac txwv hari xnlj jn groovyc cz ffwo. Azdj aj caytallu z ebhx algerne iilepprnc.
Jn xru csrpetoj nj zjyr veue J’ff frk groovyc px sff rdo twox. J’ff wzqk piisecfc example z xl jcrg jn chapter 5, rgy dgv anc efslay usmsae J’m nisug groovyc hohttuogur.
This chapter is about basic Groovy / Java integration, regardless of use case. After reviewing all the different ways to call Groovy from Java, from the JSR-223 Script-Engine to the GroovyShell and Eval classes in Groovy, I switched to the easy way, which is to put Groovy in a class and use it like any other library class. This easy blend of Java and Groovy will be used from now on.
Next I reviewed many ways that Groovy can help Java at the basic level, from POJO enhancements to AST transformations to building XML and more. I’ll use these techniques in future chapters wherever they can help. I’ll also review other helpful techniques along the way, though these are most of the major ones.