0 оценок0% нашли этот документ полезным (0 голосов)
27 просмотров85 страниц
Ant is a popular and widely used open source build tool, written in Java. It helps you transorm the source code, libraries, and other iles that ma!e up your pro"ect into a deliverable sotware pac!age. It is platorm neutral and can handle platorm speciic properties such as ile separators.
Ant is a popular and widely used open source build tool, written in Java. It helps you transorm the source code, libraries, and other iles that ma!e up your pro"ect into a deliverable sotware pac!age. It is platorm neutral and can handle platorm speciic properties such as ile separators.
Ant is a popular and widely used open source build tool, written in Java. It helps you transorm the source code, libraries, and other iles that ma!e up your pro"ect into a deliverable sotware pac!age. It is platorm neutral and can handle platorm speciic properties such as ile separators.
Ant is a popular and widely used open source build tool, written in Java. Indeed, it is probably the most widely used build tool in the Java world. It is supported by virtually all modern IDEs, and (being a Java application) runs on almost any Java-riendly platorm. In a nutshell, Ant helps you transorm the source code, libraries, and other iles that ma!e up your pro"ect into a deliverable sotware pac!age. And, more importantly, it helps you do this in an orderly, repeatable manner. I you design your build script well, you can also ensure that it will behave the same way on any machine. #his leads the way to automatic builds, which can be run on a remote machine with little or no human intervention. Ant is a highly le$ible tool%you can ma!e it do pretty much anything you want. &owever, this le$ibility can come at a cost o comple$ity. 'ood Ant build scripts are written in a way that will be easy to read and maintain in a year(s time. Features of Apache Ant Ant is the most complete Java build and deployment tool available. Ant is platorm neutral and can handle platorm speciic properties such as ile separators. Ant can be used to perorm platorm speciic tas!s such as modiying the modiied time o a ile using )touch) command. Ant scripts are written using plain *+,. I you are already amiliar with *+,, you can learn Ant pretty -uic!ly. Ant is good at automating complicated repetitive tas!s. Ant comes with a big list o predeined tas!s. Ant provides an interace to develop custom tas!s. Ant can be easily invo!ed rom the command line and it can integrate with ree and commercial IDEs Installing Ant It is assumed that you have already downloaded and installed Java Development .it (JD.) on your computer
Apache Ant is distributed under the Apache /otware ,icense, a ully-ledged open source license certiied by the open source initiative. #he latest Apache Ant version, including ull-source code, class iles and documentation can be ound at http://ant.apache.org. 1. Ensure that the JA0A1&2+E environment variable is set to the older where your JD. is installed. 3. Download the binaries rom http455ant.apache.org 6. 7n8ip the 8ip ile to a convenient location using 9in8ip, win:A:, ;-8ip or similar tools, say c4< older. =. >reate a new environment variable called A?#1&2+E that points to the Ant installation older, in this case c4<apache-ant-@.;.A-bin older. B. Append the path to the Apache Ant batch ile to the CA#& environment variable. In our case this would be the c4<apache-ant-@.;.A-bin<bin older 2nce this is done, you should be able to run Ant rom the command line4 D Ant -version Apache Ant version @.;.A compiled on July @@ 3AA; Introduction to Ant Ant is an e$tremely powerul tool, and e$perienced users can really ma!e it sing. 9e will start o simply, going through how to set up a small Java pro"ect with Ant. Basic Ant Concepts Ant build iles are written in *+,, using a -uite readable set o tags. #he overall struc- ture o an Ant ile is relatively straightorward and spontaneous. An Ant build ile describes how to build one (and only one) project. A build pro"ect is made up o targets and tasks. A target is a goal that you want your build process to achieve. /uch a goal might be to compile your application code, run your tests, or prepare a production-ready release pac!age. Eou can (and usually do) deine several targets in your build ile, which you may run on dierent occasions. A target can also depend on other targets. #his lets you ensure that certain targets are always e$ecuted beore others. For e$ample, you might want to ensure that your unit test(s target is always run beore you prepare a new release. Eou do this by declaring dependencies between your targets. A task lets you deine a piece o wor! you want done. #his might be compiling some Java source code using javac, running a set o unit tests using J7nit, or generating a production-ready JA: ile using the jar utility. #his is where the wor! actually gets done. For e$ample, the junit tas!, which runs J7nit test cases, is an op- tional tas! because it re-uires the J7nit library to be supplied separately. Finally, Ant allows you to deine and use a set o properties. In Ant, a property can be used as a way to ma!e your build script simpler and easier to understand, and also to access system-level properties such as user.dir (the current wor!ing directory) or os.name (the name o the operating system). . A Simple Ant Build File Directory structure for our project Directory src test lib build build5classes Contents Application source code 7nit test code Cro"ect dependencies Any iles generated by the build process >ompiled Java classes build5test-classes >ompiled unit tests dist Distribution iles, such as bundled JA: or 9A: iles &aving a clean, well-deined directory structure is important or any pro"ect, and is particularly important i you are using a tool li!e Ant. A clear directory layout ma!es the build script easier to write and understand. /eparating compiled classes rom source code, or e$ample, ma!es it easier to do a clean recompile simply by deleting the target directory, and ma!es it easier to place source code (and only source code) under version control. 7sing a lib directory to store your dependencies is one commonly used approach in Ant pro"ects, though it is not the only solution to this problem. #his is not the only way to store dependencies. Indeed, !eeping them in the lib direc- tory may mean that your JA:s end up being stored in your version control system. #his is not always ideal. +aven uses a dierent approach, where JA: iles are stored on a central repository, and dependencies are listed in the build ile, instead o in one o the pro"ect directories. +aven uses a similar standardi8ed directory structure which can also be used or Ant pro"ects. For our irst e$ample, we will be wor!ing with a simple one-class application that displays some inormation about the installed J0+ and operating system. #his re- mar!ably useul piece o code is shown here4 pac!age com.it.ta$calculatorG public class +ain H public static void main(/tringIJ args) H /tring "vm K /ystem.getCroperty(L"ava.versionL)G /tring os?ame K /ystem.getCroperty(Los.nameL)G /tring os0ersion K /ystem.getCroperty(Los.versionL)G /ystem.out.println(L:unning Java L M "vm M L on L M os?ame M L (version L M os0ersion M L)L)G N N ?ow let(s see how you could use Ant to build this application. At this stage, we "ust want to compile our code and bundle up a JA: ile containing the compiled classes. Eou could do this with a build.$ml ile, along the ollowing lines4 OP$ml versionKL@.AL PD Opro"ect nameKLta$-calculatorL deaultKLpac!ageLD Otarget nameKLinitLD Om!dir dirKLbuild5classesL 5D Om!dir dirKLdistL 5D O5targetD Otarget nameKLcompileL dependsKLinitL descriptionKL>ompile Java codeLD O"avac srcdirKLsrcL destdirKLbuild5classesL5D O5targetD Otarget nameKLpac!ageL dependsKLcompileL descriptionKL'enerate JA: ileLD O"ar destileKLdist5ta$-calculator."arL basedirKLbuild5classesL5D O5targetD Otarget nameKLcleanL descriptionKLDeletes generated directoriesLD Odelete dirKLbuildL 5D Odelete dirKLdistL 5D O5targetD O5pro"ectD ,et(s go through this build ile, and see how it uses the basic concepts we discussed earlier. ,i!e all Ant build scripts, the root element is called <project>. #he main role o the <project> element is to act as a container or the other build elements such as properties, targets, and tas!s. It also lets you deine an (optional) deault target. Each target uses various built-in Ant tas!s. #he irst thing we need to do in our build process is create any missing directories. Eou need to ma!e sure these directories have been created beore compiling your classes. /o, the irst target, called Qinit,R simply creates the build and dist directories using the mkdir tas!4 Otarget nameKLinitLD Om!dir dirKLbuild5classesL 5D Om!dir dirKLdistL 5D O5targetD 9e don(t need to create the QbuildR directory beore the Qbuild5classesR directory be- cause Ant will do this automatically or us. ?e$t we need to compile our classes. #he QcompileR target uses javac (or, more pre- cisely, the javac Ant tas!) to compile the source code in the src directory and place the compiled classes in the build5classes directory4 Otarget nameKLcompileL dependsKLinitL descriptionKL>ompile Java codeLD O"avac srcdirKLsrcL destdirKLbuild5classesL5D O5targetD #he Qpac!ageR target creates a JA: ile in the dist directory containing all o the com- piled classes in the build5classes directory4 Otarget nameKLpac!ageL dependsKLcompileL descriptionKL'enerate JA: ileLD O"ar destileKLdist5ta$-calculator."arL basedirKLbuild5classesL5D O5targetD Finally, the QcleanR target simply deletes the generated directories using the delete tas!4 Otarget nameKLcleanL dependsKLinitL descriptionKLDeletes generated directoriesLD Odelete dirKLbuildL 5D Odelete dirKLdistL 5D O5targetD Running Ant 9e are now ready to run this build script. Eou can do so by running Ant in the root directory o your pro"ect. I you run Ant with no arguments, Ant will invo!e the deault target, which is Qpac!ageR or this pro"ect4 $ ant Suildile4 build.$ml init4 Im!dirJ >reated dir4 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5build5classes Im!dirJ >reated dir4 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5dist compile4 I"avacJ >ompiling @ source ile to 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo 5build5classes pac!age4 I"arJ Suilding "ar4 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5dist 5ta$-calculator."ar S7I,D /7>>E//F7, #otal time4 @ second Alternatively, you can speciy the target you want to run, as shown here with the QcleanR target4 $ ant clean Suildile4 build.$ml init4 clean4 IdeleteJ Deleting directory 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5build IdeleteJ Deleting directory 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5dist S7I,D /7>>E//F7, #otal time4 A seconds Eou can also run several targets at the same time, simply by listing them as arguments on the command line4 $ ant clean compile Suildile4 build.$ml clean4 IdeleteJ Deleting directory 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5build IdeleteJ Deleting directory 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5dist init4 Im!dirJ >reated dir4 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5build5classes Im!dirJ >reated dir4 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5dist compile4 I"avacJ >ompiling @ source ile to 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo 5build5classes S7I,D /7>>E//F7, #otal time4 3 seconds Sy convention, Ant iles are called build.$ml, but you can speciy a dierent build script using the -f option4 $ ant -f my-special-buildfile.xml Finally, li!e many tools, you can activate a verbose mode (using the -v command-line option) to display more details about what Ant is doing. #his can be useul when de- bugging your build scripts4 $ ant -v Apache Ant version @.;.A compiled on July @@ 3AA; Suildile4 build.$ml Detected Java version4 @.T in4 5usr5lib5"vm5"ava-T-sun-@.T.A.AA5"re Detected 2/4 ,inu$ parsing buildile 5home5wa!aleo5pro"ects5"ava-power-tools5sample-code5chA@5ant-demo 5build.$ml with 7:I K ile45home5wa!aleo5pro"ects5"ava-power-tools5sample-code5chA@ 5ant-demo5build.$ml Cro"ect base dir set to4 5home5wa!aleo5pro"ects5"ava-power-tools5sample-code5chA@ 5ant-demo ... +ost Ant targets are not designed to be run in isolation. Seore compiling the Java source code, we need to create the target directories. And we obviously need to compile the latest version o the source code beore we can generate a new version o the JA: ile. In other words, there is a precise order in which the targets need to be e$ecuted. >ertain targets depend on others. In Ant, you use the depends attribute to declare a target(s direct dependencies4 Otarget nameKLpac!ageL dependsKLcompileL descriptionKL'enerate JA: ileLD Otarget nameKLcompileL dependsKLinitL descriptionKL'enerate JA: ileLD In this e$ample, the Qpac!ageR target depends on the QcompileR target to compile the Java classes, which in turn depends on the QinitR target to prepare the output directories. In act, the Qpac!ageR target also depends on Qinit,R but we don(t need to list QinitR in the Qpac!ageR target dependencies because it will automatically be called when the QcompileR target is e$ecuted. #hese dependencies can be e$pressed as a dependency graph, as shown in the above igure. /ome targets can have multiple dependencies. For e$ample, in the ollowing code the QtestR target directly depends on both the Qunit-testR and the Qintegration-testR targets. Otarget nameKLtestL dependsKLunit-test, integration-testL descriptionK L'enerate JA: ileLD Ant is airly smart about how it handles dependencies. For e$ample, i both the Qunit- testR and the Qintegration-testR targets depend on the QcompileR target, this target will only be e$ecuted once. Documenting Your Project Documenting build scripts is important, and Ant build iles are no e$ception. ,et unattended, they can -uic!ly become a nightmare to understand, both or you and other developers later on. In addition to traditional techni-ues such as *+, comments, Ant comes with a ew built-in eatures to help you document your build scripts. #he description attribute lets you provide a short description or your targets, as shown here4 Otarget nameKLcompileL dependsKLinitL descriptionKL>ompile Java codeLD O"avac srcdirKLsrcL destdirKLbuild5classesL5D O5targetD It is a good idea to use the description attribute or the targets in your build script that are intended or e$ternal use. Eou can then use the -projecthelp command-line option to list the main build targets, complete with a brie description. 9ith large build scripts (and Ant build scripts can become very large), this can be a valuable time-saver4 $ ant -projecthelp Suildile4 build.$ml +ain targets4 compile >ompile Java code pac!age 'enerate JA: ile clean Deletes generated directories Deault target4 pac!age Compiling Your a!a Code in Ant In Java development, one o the most undamental things that any build script needs to do is compile your code. In Ant, the <javac> tas! provides a convenient one-stop shop or Java compilation. ,et(s loo! at a simple use o the <javac> tas!. In the e$ample given above, we use a simple orm o this tas! to compile the Java classes in the src5main directory, and place the compiled classes in the build5classes directory4 Otarget nameKLcompileL dependsKLinitL descriptionKL>ompile Java codeLD O"avac srcdirKLsrcL destdirKLbuild5classesL5D O5targetD #his is e-uivalent to e$ecuting the javac tool as shown here4 U javac -noarn -d build!classes src!main In most real applications, your application will re-uire a set o libraries both to compile and to run. In Ant pro"ects, these libraries are oten stored (in the orm o JA: iles) in a directory called lib. 9hen you compile your application, you need to tell Ant where to ind these libraries. Ant comes with some very powerul eatures to help you do this. Ant e$cels at deining and manipulating classpaths and other ile path deinitions. At its simplest, you can use the <path> tag to identiy a particular library using the location attribute4 Opath idKL"unit.classpathL locationKLlib5"unit."arL5D #his path could also be deined in the same way using the path attribute. &owever, in addition to deining single JA: iles or directories, the path attribute lets you use a more path-li!e construction using a combination o directory paths and a JA: ile, as shown here4 Opath idKL"unit.classpathL pathKLbuild5classes4lib5"unit."arL5D 2ne o the nice things about the Ant path-handling eatures is that they are (li!e the underlying Java ACIs) portable across dierent operating systems. &ere, by convention, we use 7ni$-style paths containing orward slashes (Q5R). For e$ample, on a 9indows machine, Ant will automatically translate the above path into Qbuild<classesGlib <"unit."ar.R Although this certainly ma!es or more readable build iles, the real advantages o Ant(s path-handling eatures come into play when you need to manipulate large sets o iles. #he ollowing e$ample creates a path deinition including all the V."ar iles in the lib directory4 Opath idKLcompile.classpathLD Oileset dirKLlibL includesKLV."arL 5D O5pathD #his sort o thing is e$actly what you oten need to deine classpaths or real-world Java builds. Eou can use this classpath in the <javac> tas! using the classpathref attribute, as shown here4 Otarget nameKLcompileL dependsKLinitL descriptionKL>ompile Java codeLD O"avac srcdirKLsrcL destdirKLbuild5classesL classpathreKLcompile.classpathL 5D O5targetD Alternatively, i you don(t thin! you will need this classpath elsewhere in your build ile, you can embed the <classpath> element directly in the <javac> tas!4 Otarget nameKLcompileL dependsKLinitL descriptionKL>ompile Java codeLD O"avac srcdirKLsrcL destdirKLbuild5classesLD OclasspathD Oileset dirKLlibL includesKLV."arL5D O5classpathD O5"avacD O5targetD #hese paths actually use a shorthand notation or convenience. Eou can also use em- bedded tags or a more readable notation, which is useul when many separate classpath elements are re-uired. #his is also convenient i you want to reuse paths deined else- where in the build ile. #he <pathelement> tag lets you deine a classpath element using either a JA: ile, a directory, or even a reerence to another classpath element4 Opath idKLtest.classpathLD Opath reidKLcompile.classpathL5D Opathelement locationKLlib5"unit."arL5D Opathelement pathKLbuild5test-classesL5D O5pathD Eou can also use path-li!e e$pressions within the <javac> tas! itsel to tell Ant what classes to include or which ones should be e$cluded rom the compilation process, using the includes and excludes attributes. For e$ample, to compile only the classes in the com.mycompany.myapp.web pac!age (and below), you could do this4 O"avac srcdirKLsrcL destdirKLbuild5classesL includesKLcom5mycompany5myapp5web5VVL 5D 2ne re-uent re-uirement when compiling Java code is to compile or a speciic Java version. For e$ample, you may use Java T on your development machine, but need to deploy to an environment where only Java @.= is supported. Eou can ensure that your Java code is compatible with Java @.=, and that none o the nice Java B syntactic sugar is used, by setting the source attribute to Q@.=.R /imilarly, you can tell Ant to generate byte-code compatible with a Java @.= J0+ by speciying the target attribute as Q@.=.R O"avac srcdirKLsrcL destdirKLbuild5classesL sourceKL@.=L targetKL@.=L 5D Eou may also need to indicate i you want the source code compiled with debug in- ormation. Sy deault, this is turned o, but it can come in handy when testing and debugging your code. #o turn this option on, set the debug attribute to QonR (or QtrueR)4 O"avac srcdirKLsrcL destdirKLbuild5classesL debugKLonL 5D Despite its name, the <javac> tas! is not tied to the standard /un Java compiler, also called javac. In act, ans o alternative compilers li!e Ji!es and '>J can use these compilers, or a number o other more e$otic choices, by speciying the compiler attribute4 O"avac srcdirKLsrcL destdirKLbuild5classesL compilerKL"i!esL5D Eou can also deine this value or the entire build ile by setting the build.compiler property. As you can see, the <javac> tas! provides a powerul, le$ible tool or Java compilation. +any o the techni-ues covered here are typical o many Ant tas!s, and we will see more e$amples o these later on. Understanding Ant datatypes and properties Datatype o!er!ie" 2ne o the great advantages Ant has over the alternatives to building and pac!aging Java applications is that it understands the primary problem domain, that o building Java pro"ects. +ost steps to build a typical Java pro"ect deal with iles and paths (such as classpaths). Ant provides datatypes to handle these two concepts natively. Eou can thin! o an Ant datatype as similar to Java(s own built-in core classes4 data that can be passed around and provided to tas!s. #he ileset and path datatypes, and several others, orm the basic building bloc!s o Ant build iles. >lasspath-related headaches are commonplace in Java development. Ant ma!es dealing with classpaths much more natural and pleasant than the command-line manual alternative, and provides or the reuse o deined classpaths wherever needed. For e$ample, compiling source code re-uires that reerenced classes be in the classpath. A path can be deined once or compilation with O"avacD, and reused or e$ecution (via O"ava). 2ne o the conse-uences o classpaths being speciied inside the build ile is that Ant can be invo!ed without an e$plicitly deined system classpath, ma!ing it easy to install Ant and build a pro"ect with little or no environmental coniguration.@ Another no less important conse-uence is that classpaths can be easily and tightly controlled. #his reduces >,A//CA#& coniguration problems, both or compilation and e$ecution. A set o iles is a common entity to manipulate or such tas!s as compiling, pac!aging, copying, deleting, and documenting. Deining a ileset o all ."ava iles, or e$ample, is straightorward4 <fileset dir="src" includes="**/*.java" id="source.fileset"/> Sy providing an id attribute, we are deining a reerence. #his reerence name can be used later wherever a ileset is e$pected. For e$ample, copying our source code to another directory using the previously deined source.fileset is <copy todir="backup"> <fileset refid="source.fileset"/> </copy> Property o!er!ie" Ant(s property handling mechanism allows or build ile e$tensibility and reusability by parameteri8ing any string-speciied item. #he control users get over build iles can be dramatically increased with the techni-ues shown in this chapter. For e$ample, changing a build to use a dierent version o a third-party library, perhaps or testing purposes, can be made as trivial as this4 ant -Dstruts.jar=/home/ant/newstruts/struts.jar In this case, struts.jar represents an Ant property, and in our build ile, we reer to it with special synta$: ${struts.jar}. A !ey eature o an Ant property is its immutabilityG it resists change once set. FI#$S$%S Implicitly, all build processes will operate on sets o iles, either to compile, copy, delete, or operate on them in any number o other ways. Ant provides the ileset as a native datatype. It is diicult to imagine any useul build that does not use a ileset. /ome tas!s support paths, which implicitly support ilesets, while other tas!s support ilesets directly and this distinction should be made clear in each tas!(s documentation. A ileset is a set o iles rooted rom a single directory. Sy deault, a ileset speciied with only a root directory will include all the iles in that entire directory tree, including iles in all subdirectories recursively. For a concrete running e$ample that will demonstrate ileset eatures as we discuss them, let(s copy iles rom one directory to another4 <copy todir="new_web"> <fileset dir="web"/> </copy> In its current orm, all iles rom the web directory are copied to the new1web directory. #his e$ample will evolve into copying only speciic iles, altering them during the copy with to!en replacement, and lattening the directory hierarchy in the new1web directory. Fileset e&les During a build, you oten need to build a ileset by including or e$cluding sets o iles. A ew e$amples o typical ilesets ollow. Include all JA: iles in the lib directory (nonrecursive, no subdirectories are considered)4 <fileset dir="lib"> <include name="*.jar"/> </fileset> Include all ."ava iles below the test directory that end with the word Q#estR <fileset dir="test"> <include="**/*Test.java"/> </fileset> All non-J/C pages in the web directory and below4 <fileset dir="web"> <exclude name="**/*.jsp"/> </fileset> Sy deault, includes and e$cludes are case-sensitive, but this can be disabled by speciying casesensitive="false". The <include> and <exclude> elements are called patternsets. PA%%$R'S$%S Filesets accomplish the include5e$clude capability by utili8ing another o Ant(s core datatypes4 the patternset. A patternset is a collection o ile matching patterns. A patternset itsel does not reer to any actual iles until it is nested in a ileset and thereore rooted at a speciic directory. A pattern is a path-matching speciication similar to 7ni$- and +/-D2/-based ile matching. E$amples o this have already been shown with V."ar used to represent all iles with the ."ar e$tension in the top directory and VV5V."sp to represent all iles in the entire directory tree with the ."sp e$tension. #he pattern matching eatures are as ollows: V matches 8ero or more characters. W P matches a single character. W VV, used as the name o a directory, represents matching o all directories rom that point down, matching 8ero or more directories. A pattern ending with a trailing 5 or < implies a trailing VV. Implicitly a OilesetD holds a patternset, but patternsets can also be speciied independently, allowing or the reuse o patternsets in multiple ilesets. Catternset attributes. Including and e$cluding patterns allows ilesets to be deined precisely to encompass only the iles desired. #he includesile and e$cludesile adds a level o indirection and e$ternal customi8ation. Attribute Description includes Comma-separated list of patterns of fles that must be included. All fles are included when omitted. excludes Comma-separated list of patterns of fles that must be excluded. No fles (except default excludes are excluded when omitted. includesfile The name of a fle! each line of this fle is ta"en to be an include pattern. #ou can specif$ more than one include fle b$ usin% nested includesfile elements. excludesfile The name of a fle! each line of this fle is ta"en to be an exclude pattern. #ou can specif$ more than one exclude fle b$ usin% nested excludesfile elements. E$cludes ta!e precedence, so that i a ile matched both an include and e$clude pattern the ile would be e$cluded. Elements corresponding to these attributes are also available as child elements o OpatternsetD or increased le$ibility and control. #he elements are OincludeD, Oe$cludeD, OincludesileD, and Oe$cludesileD. Each o these elements has a name attribute. For OincludeD and Oe$cludeD, the name attribute speciies the pattern to be included or e$cluded, respectively. For the OincludesileD and Oe$cludesileD elements, the name attribute represents a ile name. Each o these elements has i5unless attributes, which are covered in the conditional patternset section later in this chapter &ere are some e$amples o patternsets4 <patternset> <include name="*.jsp"/> </patternset> #he OpatternsetD element is not always e$plicitly speciied when used within a ileset. A ileset implicitly contains patternsets. 2ur running copy e$ample is shown again using a patternset to include all J/C iles4 <copy todir="new_web"> <fileset dir="web" includes="**/*.jsp"/> </copy> #his is e-uivalent to <copy todir="new_web"> <fileset dir="web"> <include name="**/*.jsp"/> </fileset> </copy> &ad we speciied "ust V."sp, only the J/C iles in the web directory would have been copied, but no iles in its subdirectories. Catternsets may be nested within one another, such as <patternset> <include name="**/*.gif,**/*.jpg"/> <patternset> <exclude name="**/*.txt,**/*.xml"/> </patternset> </patternset> #his is a contrived e$ample simply demonstrating the nesting capability. #his nesting is unnecessary in this e$ample, but datatype reerences ma!e the nesting capability powerul. Catternset nesting is a eature introduced with Ant @.B S$#$C%(RS Ant @.B includes a sophisticated new eature, called selectors, orselecting the ilesincluded in a ileset. Ants built-in selectors Selector Description <filename> &or"s li"e a patternset <include> or <exclude> element to match fles based on a pattern. <depth> 'elects fles based on a director$ depth ran%e. <size> 'elects fles that are less, e(ual, or more than a specifed si)e. <date> 'elects fles (and optionall$ directories that ha*e been last modifed before, after, or on a specifed date. <present> 'elects fles if the$ exist in another director$ tree. <depend> 'elects fles that are newer than correspondin% ones in another director$ tree. <contains> 'elects fles that contain a strin%. #hese selectors can be combined inside selector containers to provide grouping and logic. #he containers are <and>, <or>, <not>, <none>, and <majority>. >ontainers may be nested inside containers, allowing or the construction o comple$ selection logic. :ather than detailing every available selector, container, and their options, we reer you to Ant(s documentation or this inormation. 9e will, however, provide a couple o e$amples showing how selectors wor!. #o compare two directory trees and copy the iles that e$ist in one tree but not another we use a combination o <not> and <present>: <copy todir="newfiles" includeemptydirs="false"> <fileset dir="web"> <not> <present targetdir="currentfiles"/> </not> </fileset> </copy> #he <copy> tas! is copying only the iles rom the web directory that do not e$ist in the currentiles directory. 7sing the <contains> selector, we can choose only the iles that contain a certain string: <copy todir="currentfiles" includeemptydirs="false"> <fileset dir="web"> <contains text="System"/> </fileset> </copy> 2nly the iles containing the te$t Q/ystemR in the web directory are copied to the currentiles directory. Sy deault <contains> is case-sensitive, but can be changed using casesensitive="no". All rules must be satisied beore a ile is considered part o a ileset, so when using selectors in con"unction with patternsets, the ile must match the include patterns, must not match any e$clude patterns, and the selector rules must test positively. A <custom> selector enables you to write your own selector logic in a Java class. FI#%$RC)AI'S A'D FI#%$RR$AD$RS Crocessing te$t iles has never been so easy with Ant until the introduction, in version @.B, o Filter>hains and Filter:eaders. A Filter:eader is a simple ilter o te$t input that can remove or modiy the te$t beore it is output. A Filter>hain is an ordered group o one or more Filter:eaders. A Filter>hain is analogous to piping output rom one command to another in 7ni$, with the output o one command being the input to the ne$t, and so on. #here are a number built-in Filter:eaders, as shown in table Ants built-in FilterReaders FilterReader Description <classconstants>. +enerates name=value" lines for basic and 'trin% datat$pe constants found in a class fle. <expandproperties> ,eplaces Ant propert$ *alues. <headfilter> -xtracts the frst specifed number of lines. <linecontains> .nl$ lines containin% the specifed strin% are passed throu%h. <linecontainsregexp> .nl$ lines matchin% specifed re%ular expression(s are passed throu%h. <prefixlines> All lines ha*e a prefx prepended. <replacetokens> /erforms to"en substitution, 0ust as fltersets do. <stripjavacomments> ,emo*es 1a*a st$le comments. <striplinebreaks> ,emo*es line brea"s, defaultin% to \r" and \n" but characters stripped can be specifed. <striplinecomments> ,emo*es lines be%innin% with a specifed set of characters. <tabstospaces> ,eplaces tabs with a specifed number of spaces. <tailfilter> -xtracts the last specifed number of lines. *APP$RS Ant(s mapper datatype is used to match sets o iles with one another. #here are several built-in mapper types as shown in table. +appers are used by <uptodate>, <move>, <copy>, and <apply> and several other tas!s. Depending on the mapper type, to and from attributes may be re-uired. Identity mapper #he target ile name maps e$actly to the source ile name. #he to and from attributes are not used by the identity mapper. <mapper type="identity"/> Sy deault, the <copy> tas! uses the identity mapper. #he ollowing two OcopyD tas!s have the same eect4 <copy todir="new_web"> <fileset dir="web" includes="**/*.jsp"/> <mapper type="identity"/> </copy> <copy todir="new_web"> <fileset dir="web" includes="**/*.jsp"/> </copy> Flatten mapper #he flatten mapper removes all directory path inormation rom the source ile name to map to the target ile name. The to and from attributes are not used. #he latten mapper is useul in copying iles rom a nested directory structure into a single directory eliminating the hierarchy. #o copy all J/C pages rom the web directory hierarchy into a single lat directory, the flatten mapper is used in this manner: <copy todir="new_web"> <fileset dir="web" includes="**/*.jsp"/> <mapper type="flatten"/> </copy> ?ote that i multiple iles have the same name in the source ileset, regardless o directory, only one o them will ma!e it to the destination directoryG it is unspeciied which one it will be. *erge mapper #he target ile name remains i$ed to the to attribute speciied. All source ile names map to the single target. <mapper type="merge" to="archive.zip"/> #he merge mapper is used with <uptodate> in cases where many iles map to a single destination. For e$ample, many iles are bundled together into a single Xip ile. A property can be set i the Xip contains all the latest sources: <uptodate property="zip.notRequired"> <srcfiles dir="src" includes="**/*.java"/> <mapper type="merge" to="${dist.dir}/src.zip"/> </uptodate> /aving time by s!ipping unnecessary steps4 OuptodateD #o determine i target iles are up-to-date with source iles, Ant provides the OuptodateD tas!. +ost tas!s (such as O"avacD) deal with source5target out-o-date chec!ing internally, but there are cases where it is necessary to do this yoursel. For e$ample, the J7nit test (see chapter = or in-depth coverage) tas! does no dependency chec!ing and simply runs all tests regardless o whether or not any .class iles were modiied. /!ipping the unit test target i all the test related iles are up-to-date dramatically improves build time without sacriicing integrated testing4 <uptodate property="tests.unnecessary"> <srcfiles dir="src" includes="**/*.java"/> <mapper type="glob" from="*.java" to="${build.dir}/classes/*.class" /> </uptodate> Deferring the discussion of the +mapper, element for just a moment- this e&le is setting the property tests.unnecessary to true if each module from the source tree is not ne"er than its corresponding .class file. /%his default is changed 0y specifying a !alue attri0ute.1 %his e&le is sho"ing a one2to2one mapping from source file to target file- also ignoring any non2.ja!a files in the source tree. (ther scenarios ta3e ad!antage of many2to2one mappings or other more comple& mappings a!aila0le "ith the mappers. Com0ining the use of +uptodate, and conditional targets is a useful techni4ue to allo" your 0uild file to handle some dependency chec3ing that tas3s do not. #he merge mapper in <copy> is not e$tremely useul since all iles get copied to the same ile, with the last unpredictable ile becoming the sole new ile. #here is one interesting case, however, that is worthy o mention. I, or e$ample, you have a directory containing a single ile whose name is not precisely !nown (perhaps with a timestamp sui$), you can copy this ile to a !nown ile name using the merge mapper: <copy todir="output"> <fileset dir="data"/> <mapper type="merge" to="data.dat"/> </copy> Assume that there is a single ile in the data directory called data13AA3A3A3.dat, yet this ile name is dynamically generated. #he use o the merge mapper will copy it to the output directory with the name data.dat. #his particular techni-ue, remember, is only useul with ilesets containing a single ile. Rege&p mapper #he !ing o all mappers, but over!ill or most cases, is regexp. #he from attribute speciies a regular e$pression. 2nly source iles matching the from pattern are considered. #he target ile name is built using the to pattern with pattern substitutions rom the from pattern, including \0 or the ull matched source ile name and \1 through \9 or patterns matched with enclosing parenthesis in the from pattern. In order to use the regexp mapper, a regular e$pression library is needed. #he Ant documentation reers to several implementations. 9e recommend Ja!arta 2:2, although JD. @.= comes with an implementation as well and is used by deault i present. /imply drop the JA: ile or the regular e$pression implementation into A?#1&2+E5lib to have it automatically recogni8ed by Ant. &ere(s a simple e$ample having the same eect as the glob mapper e$ample to map all .java iles to .java.bak iles: <mapper type="regexp" from="^(.*)\.java$" to="\1.java.bak"/> E$ample4 <copy todir="new_web"> <fileset dir="web" includes="**/*.jsp"/> <mapper type="regexp" from="^(.*)\.jsp$" to="\1.jsp.bak" /> </copy> ADDI%I('A# A'% DA%A%YP$S 9e have covered the Ant datatypes that are re-uently used by Ant tas!s, but there are everal other datatypes that are used by a smaller number o tas!s. 5ipFileset Suilding an archive that contains the contents o other archive iles can be accomplished using the <zipfileset> datat$pe. A <zipfileset> not only allows putting the contents o one archive inside another, it also provides the capability to prei$ an archives contents within another. For e$ample, when building the 9A: ile or our search engine application, we incorporate the Javadoc &#+, in an api subdirectory and our documentation under the help directory. #hese were not the directory names used during our build process, yet the 9A: ile will have these names in its structure. <war destfile="dist/antbook.war" webxml="web.xml"> <classes dir="${build.classes.dir}"/> . . . <fileset dir="web"/> <zipfileset dir="${javadoc.dir}" prefix="api" /> <zipfileset dir="${build.dir}/webdocs" prefix="help"/> </war> #he tas!s that support the XipFileset datatype are <zip>, <jar>, <war>, and <ear>. PR(P$R%I$S Cerhaps the most important concept to ully understand in Ant is its notion o properties. Croperties are loosely analogous to variables in that they are mappings between names and values and, not coincidentally, are very similar conceptually to "ava. util.Croperties. Ant properties are typically, depending on the conte$t o their use, denoted by ${property.name}within the build ile. #o e$amine the properties provided <target name="echo"> <echo message="ant.file = ${ant.file}"/> <echo message="ant.home = ${ant.home}"/> <echo message="ant.java.version = ${ant.java.version}"/> <echo message="ant.version = ${ant.version}"/> <echo message="basedir = ${basedir}"/> </target> #his generates output similar to this4 echo: [echo] ant.file = C:\AntBook\Sections\Learning\datatypes\properties.xml [echo] ant.home = c:\AntBook\jakarta-ant-1.5Beta1 [echo] ant.java.version = 1.3 [echo] ant.version = Apache Ant version 1.5Beta1 compiled on April 30 2002 [echo] basedir = C:\AntBook\Sections\Learning\datatypes Built-in properties Name Defnition ant.file The absolute path of the build fle. ant.home The path to executin% *ersion of Ant2s root director$ . ant.java.version The 134 *ersion Ant detected! currentl$ it can hold the *alues 1.1, 1.2, 1.3, and 1.4 . ant.project.name The name of the pro0ect that is currentl$ executin%! it is set in the name attribute of <project>. ant.version. The *ersion of Ant basedir The absolute path of the pro0ect5s basedir (as set with the basedir attribute of 6pro0ect7. #his e$ample was run with the -f command-line option to speciy a dierent build ile name as shown in ant.file. Sy the time o publication, many o us will probably see 1.4 for ant.java.version. #he latest release version o Ant at the time o writing was version @.B Seta, but it will be an oicial release by the time o publication. #he basedir property deaults to the path o the current build ile, and can be changed by speciying basedir on the <project> element or controlled e$ternally using property overrides as discussed shortly. Implicitly, all J0+ system properties are provided as Ant properties, allowing valuable inormation such as the users home directory path and the current username to be utili8ed as desired. #he J0+ system properties will vary rom platorm-to-platorm, but there are many that you can rely on, or e$ample <echo message="user.name = ${user.name}"/> <echo message="user.home = ${user.home}"/> <echo message="java.home = ${java.home}"/> &ere are sample results rom running this code on a 9indows machine: [echo] user.name = erik [echo] user.home = C:\Documents and Settings\erik [echo] java.home = c:\jdk1.3.1\jre Setting properties "ith the +property, tas3 #he <property> tas! allows build iles to deine their own sets o custom properties. #he most common variants o creating properties are W ?ame5value attributes W ,oad a set o properties rom a properties ile W ,oad environment variables Setting and using a simple property A typical development-versus-production build dierence is in the enabling or disabling o debug mode on compilation. /ince we want a single build ile with a single <javac> tas!, we use a property to parameteri8e it. 9e deine a property named build.debug and set its value to on (the value that <javac> uses on its debug atribute). <property name="build.debug" value="on"/> Enhancing the <javac> example, we now ha*e this: <javac srcdir="src" debug="${build.debug}"/> #he obvious ne$t step is to vary that property valueG to begin, let(s load properties rom a ile. #oading properties from a properties file A useul method to provide coniguration and settings inormation to a build process is to load all name5value pairs rom a properties ile that creates internal Ant properties or each one. #o demonstrate4 we create a ile named build.properties in the root directory o our pro"ect, where our build ile lives. #his ile has the ollowing contents4 build.debug=off #o load it we use one o the variants o the <property> tas!: <property file="build.properties"/> Croperty values in the properties ile may also contain property reerences. For e$ample, consider a properties ile containing these lines4 build.dir=build output.dir=${build.dir}/output 9hen loaded, output.dir will have the value build/output. Forward-reerencing property values may be used in a single properties ile as wellG i the previous lines had been in opposite order, the same results would be obtained. >ircular deinitions will cause a build ailure. NOTE Croperties that reer to relative paths are best set using the location variant. /ee QFi$ing properties to absolute path locations.R Croperties set rom a properties ile are set as a simple values. /ince properties are immutable, you may want to load properties rom a ile and prei$ their name. In the last e$ample, had we used prefix="temp", the properties created would have been temp.build.dir and temp.output.dir. #his is a nice tric! to The absolute path of the pro0ect5s basedir (as set with the basedir attribute of 6pro0ect7.two property iles that may have the same named property, yet ensure that you have access to both values. (!erriding a property First, a little pop--ui8%e$amine the ollowing code lines and guess their output given the properties ile "ust deined4 <target name="override"> <propert fle!"build.properties"#$ <property name="build.debug" value="on"/> <echo message="debugging is turned %&build.debu'("/> </target> As you may have guessed, we would not have as!ed this -uestion had it been completely straightorward. #he result is [echo] debugging is turned off A property(s value does not change once set4 properties are immutable. ,et(s e$plore what this mechanism gives us in terms o control and le$ibility. 9hat i our properties ile had not contained the line deining build.debug, or what i build.properties had not e$isted8 The <property file="..."> tas! simply does nothing but warn in verbose mode when the speciied property ile does not e$ist. 2nly properties listed in an e$isting properties ile are loaded, so in the case where build.debug is not present in the properties ile, its value would not be set until it is deined in the build ile itsel, in the line <property name="build. debug" value="on"/>. NOTE 2nce a property has been set, either in the build ile or on the command line, it cannot be changed. 9hoever sets a property irst i$es its value. #his is the direct opposite o variables in a program, where the last assignment becomes its value. Eou have "ust witnessed the mechanism that will bring your build iles to lie4 allowing them to adapt to user preerences, environment conditions, provide mapping indirections, and scaling to large multi-build-ile processes. '(%$ #here are ways to brea! the immutability o properties using OantD, OantcallD, OavailableD, and the -D command-line option. +ost o the reasons or these e$ceptions are logically legitimate, yet certainly an area o conusion and concern. #oading en!ironment !aria0les Another important variant of <property> allows environment variables to be pulled into Ant properties. In order to avoid inadvertent collision with e$isting Ant properties (in other words4 what would happen i an environment variable was named build.debug8, environment variables are loaded with a name prei$. >onsider the ollowing e$ample4 <property environment="env"/> All environment variables are loaded into Ant(s internal properties with the prei$ env. (including the trailing period). #his gives us properties li!e env. CATALINA_HOME, which we can then use in tas!s related to deployment, or e$ample. Although you can use any prei$ or environment variables, it is customary to use env. as the prefx. )o" the +property, tas3 is different #he <property> tas! is special in that it has the special right to unction outside of a <target>: it is allowed to stand alone directly as a child element o Opro"ectD. All tas!s that appear outside o targets are evaluated beore any target is e$ecuted. 9e recommend that you to put all such Qnontarget declarationsR o <project> beore any target declarations, to avoid conusion. Chec3ing for the a!aila0ility of resources6 +a!aila0le, #he <available> tas! will set a property value i a speciied resource e$ists. It has the capability to chec! or W E$istence o a class in a classpath W E$istence o a ile or directory W E$istence o a J0+ system resource Customi7ing Your Build Script Using Properties In development, people oten spea! o the D:E (Don(t :epeat Eoursel) principle. #his is a general principle aimed at ma!ing code more readable and easier to maintain by avoiding the duplication o data. In a Java application, or e$ample, !ey values that are used in several places, or that may need to be modiied easily, are stored as constants or as parameters in a coniguration ile. #his ma!es the code easier to read and under- stand, and ma!es maintenance less o a headache. In Ant, you can do the same sort o thing by using the <property> tag, which lets you declare constant values that can be used throughout the rest o your build ile. Declaring a property is straightorwardG you "ust need to provide a name and value attribute, as shown here4 Oproperty nameKL"avac.debugL valueKLonL5D I you are reerring to a directory, you can use the location attribute instead o value4 Oproperty nameKLbuild.dirL locationKLbuildL5D #his property value will be set to the absolute ilename o the build directory. #o use a property elsewhere in the build ile, you "ust -uote the name o the property surrounded by $"...#. For e$ample, you can subse-uently reer to this property anywhere in your build ile as $"build.dir#. Eou could use the <echo> tas! to display the property value to the screen, as shown here4 Otarget nameKLdisplay-propertiesLD OechoDDebug K UH"avac.debugNO5echoD OechoDSuild directory (build.dir) K UHbuild.dirNO5echoD O5targetD >alling this target would display the value o this property on the console. 2n my machine, it displays the ollowing4 $ ant display-properties Suildile4 build.$ml display-properties4 IechoJ Suild directory (build.dir) K 5home5"ohn5pro"ects5ta$-calculator5build S7I,D /7>>E//F7, #otal time4 A seconds Another way to do this would be to use the <echoproperties> tas!, which, as the name suggests, lets you display all o the current property values to the console4 Otarget nameKLdisplay-propertiesLD Oechoproperties 5D O5targetD Croperties can also be used to ta!e into account environment dierences on each de- veloper(s machine. For e$ample, you may need to store a path to a local server or to application directories, which may be dierent on dierent machines. #o do this, you can store local properties in an ordinary Java properties ile. #he ollowing directories would be dierent on 7ni$ and 9indows machines. 2n a ,inu$ development bo$, you might have the ollowing set o properties4 chec!style.home K 5usr5local5tools5chec!style pmd.home K 5usr5local5tools5pmd indbugs.home K 5usr5local5tools5indbugs cobertura.home K 5usr5local5tools5cobertura 2n a 9indows machine, by contrast, you might have something li!e this4 chec!style.home K >4<tools<chec!style pmd.home K >4<tools<pmd indbugs.home K >4<tools<indbugs cobertura.home K >4<tools<cobertura Another common use o local properties iles is to store user-speciic and5or potentially sensitive details such as logins and passwords. #his way, this sort o data doesn(t end up in the version control system. Ant also comes with a set o built-in properties, such as $"basedir#, which is the absolute path o the pro"ect base directory, as well as Java system properties li!e $"java.home#, $"java.version#, and $"user.home#. Eou can also deine other properties based on these properties. #his can limit the need to put a lot o variables in local properties iles. For e$ample, suppose you want to use the FindSugs (see >hapter 36) library in your build process. Eou could deine a deault FindSugs installation directory as a subdirectory o the user(s home directory4 Oproperty nameKLindbugs.homeL valueKLUHuser.homeN5.indbugsL5D 7sing this deinition, any user who has installed FindSugs into this directory would not need to conigure their local properties ile%the deault property value would suice. 2ne nice eature here is that you can also use properties that you deine in a properties ile to deine other properties, as shown below4 test.server K "upiter.mycompany.com test.server.port K YAYA test.server.url K http455UHtest.serverN4UHtest.server.portN test.server.manager.url K UHtest.server.urlN5manager All team members need to be aware o where these properties should be deined. #his is important, because by deinition this is not something you can place under version control. 2ne good approach is to agree on a properties ile naming convention (say, use a ile called local.properties in the pro"ect home directory) and to place a docu- mented sample ile under version control (called, or e$ample, sample.local.proper ties). Another, possibly complementary, convention is to use a global properties ile, stored in the user(s home directory, which contains properties that are shared between several pro"ects. #his ile is oten called Qant-global.propertiesR or Q.ant-global.prop erties.R Eou can incorporate these properties into your build script by using the file attribute in the <property> tag4 <property file$%$"user.home#!ant-global.properties%!> <property file$%$"basedir#!local.properties%!> OechoDchec!style.home K UHchec!style.homeNO5echoD OechoDpmd.home K UHpmd.homeNO5echoD OechoDindbugs.home K UHindbugs.homeNO5echoD OechoDcobertura.home K UHcobertura.homeNO5echoD 9hen you run this, the property values will be loaded and integrated into the build ile4 $ ant compile Suildile4 build.$ml IechoJ chec!style.home K 5usr5local5tools5chec!style IechoJ pmd.home K 5usr5local5tools5pmd IechoJ indbugs.home K 5usr5local5tools5indbugs IechoJ cobertura.home K 5usr5local5tools5cobertura ... Eou can ma!e your build ile more robust by setting up sensible deault values or locally deined properties. 2ne very powerul eature o Ant properties (which has caused a lot o conusion among ine$perienced Ant users) is immutability. 2nce deined, Ant properties cannot be modiied or the duration o the build, no matter how many <property> tags reer to them aterward. In other words, the irst declaration o any property wins. ,et(s loo! at a practical e$ample. /uppose you deine a property called $"javac.debug# to indicate i you want to include debug inormation in your compiled classes. Eou could do this as ollows4 Oproperty nameKL"avac.debugL valueKLoL5D ... Otarget nameKLcompileL dependsKLinitL descriptionKL>ompile Java codeLD Oecho messageKLDebug4 UH"avac.debugNL 5D O"avac srcdirKLUHsrc.dirNL destdirKLUHbuild.classes.dirNL classpathreKLcompile.classpathL debugKLUH"avac.debugNL5D O5targetD 9hen you run this, unsurprisingly, the $"javac.debug# property is set to QoR4 $ ant compile Suildile4 build.$ml ... compile4 IechoJ Debug4 o S7I,D /7>>E//F7, #otal time4 A seconds ?ow suppose you write a ile called local.properties that you store in your pro"ect directory. #his properties ile contains your own personal preerences or build options such as debugging. In it, you stipulate that debugging should be on4 "avac.debug K on And now we incorporate this properties ile into our build ile (note that we include the properties ile before the property declaration)4 <property file$%$"basedir#!local.properties%!> Oproperty nameKL"avac.debugL valueKLoL5D O"avac srcdirKLsrcL destdirKLbuild5classesL debugKLUH"avac.debugNL 5D 9hen you run the build again, the irst declaration o $"javac.debug# (in the properties ile) is considered deinitive, and the second (in the build ile) is ignored4 $ ant compile Suildile4 build.$ml ... compile4 IechoJ Debug4 on S7I,D /7>>E//F7, #otal time4 A seconds #he story doesn(t end there, however. Eou can override any property value rom the command line, using the -D command-line option. For e$ample, here we override the $"javac.debug# property value to Qo.R #his will ta!e precedence over all other property declarations4 $ ant -Djavac.debug$off compile Suildile4 build.$ml init4 compile4 IechoJ Debug4 o S7I,D /7>>E//F7, #otal time4 A seconds 8enerating Documentation "ith a!adoc #echnical documentation is an important part o any pro"ect, and Javadoc is one o the cornerstones o technical documentation in Java. Javadoc produces a -uite decent, usable set o ACI documentation or your Java code, which can be a valuable aid as a communication tool, helping team members understand what other team members are doing. 2 course, good Javadoc re-uires well-written and meaningul comments within the source code, and enorcing that is a tall order or any tool. And Javadoc documen- tation is by deinition low-level reerence material%it can be very useul or an application developer amiliar with the application, but it will be o limited use or a new developer trying to learn the application architecture. Despite these reservations, Javadoc should be an integral part o any development pro"ect. It is a good idea to generate Javadoc as part o your build process. Javadoc documen- tation should be generated and published alongside the compiled source code and the unit test results as part o the automatic build liecycle. In Ant, you can do this using the <javadoc> tas!. #his tas! has a lot o attributes and nested elements, but only a ew are essential. &ere is a simple e$ample4 Otarget nameKL"avadocL dependsKLcompile,initL descriptionKL'enerate JavaDocs.LD O"avadoc sourcepathKLUHsrc.dirNL destdirKLUHreports."avadocNL authorKLtrueL versionKLtrueL useKLtrueL accessKLprivateL lin!sourceKLtrueL windowtitleKLUHant.pro"ect.nameN ACILD OclasspathD Opath reidKLcompile.classpathL 5D Opathelement pathKLUHbuild.classes.dirNL 5D O5classpathD OdoctitleDOZI>DA#AIOh@DUHant.pro"ect.nameNO5h@DJJDO5doctitleD ObottomDOZI>DA#AIOiD>opyright [\@T]G 3AA; All :ights :eserved. O5iDJJDO5bottomD O5"avadocD O5targetD #his tas! will generate Javadoc documentation or all the classes in the UHsrc.dirN directory. 9e needed to provide it with a classpath containing both the compiled classes and the application dependencies. 9e did this using an embedded <class- path> structure. 9e could also have deined this classpath elsewhere in the build ile and reerred to it using the classpathref attribute. +ost o the other attributes used here are airly sel-e$planatory. #he listsource attribute causes Ant to insert lin!s in the Javadoc document to the source code in &#+, orm. #his is similar to the +aven J*: plugin, although the ormatting is less polished. #he access property determines what parts o the classes should be documented. &ere we document everything, rom the private ields up. I you want a more succinct view, you might want to limit the "avadoc to the protected or even to only the public ields and methods. #here are many other options or this tas!, ar too many, in act, to cover here. +ost involve ine-tuning ormatting details, and aren(t particularly interesting. Eou can limit the classes being documented by providing a list o pac!ages in the packagenames at- tribute, although i you separate your test classes rom your application source code, the reasons or doing so are generally more rare. Javadoc documentation is generated in the orm o a sel-contained web site. #his ma!es it easy to deploy to your local pro"ect web site, or to bundle up with your library, as most open source pro"ects do. Pac3aging Your Application 2nce you have compiled and tested your application, the ne$t step is to bundle up the compiled code into a deliverable application or library. #his can ta!e dierent orms, depending on your pro"ect4 you may have to prepare a JA: ile, a 9A: ile, or possibly a XIC or #A: ile containing the e$ecutable code plus other iles such as documentation and source code. Ant has many powerul eatures that can help you prepare your ap- plication or delivery. In the ollowing sections, we will loo! at a ew o the more interesting ones. 8enerating a AR File #he most undamental Java pac!aging mechanism is the JA: ile. A JA: ile is essen- tially a XIC ile containing a hierarchy o compiled Java classes, plus some metadata. 9A: and EA: iles are similar, with some e$tra constraints on their internal directory structure and content. #he basic usage o the <jar> tas! is simple. &ere is an e$ample rom our sample ap- plication, where we bundle the compiled classes into a JA: ile4 Oproperty nameKLpro"ect.nameL valueKLHant.pro"ect.nameNL 5D Oproperty nameKLpro"ect.versionL valueKL@.AL 5D ... Otarget nameKLpac!ageL dependsKLcompileL descriptionKL'enerate JA: ileLD O"ar destileKLUHdist.dirN5UHpro"ect.nameN-UHpro"ect.versionN."arL basedirK LUHbuild.classes.dirNL5D O5targetD :unning this will (surprise, surpriseZ) generate a JA: ile containing your compiled classes4 $ ant clean package Suildile4 build.$ml clean4 IdeleteJ Deleting directory 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5dist IdeleteJ Deleting directory 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5reports init4 Im!dirJ >reated dir4 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5dist Im!dirJ >reated dir4 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5reports5$ml Im!dirJ >reated dir4 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5reports5html compile4 pac!age4 I"arJ Suilding "ar4 5home5wa!aleo5pro"ects5"pt-sample-code5ant-demo5dist5 ta$-calculator-@.A."ar S7I,D /7>>E//F7, #otal time4 A seconds 9e use the +aven convention or naming JA: iles here, which is to add the version number to the end o the ilename. #his ma!es it easier to identiy ile versions at a glance. #he pro"ect name comes rom the ant.project.name property, which is deined in the Opro"ectD root element. 7sing a dierent property means that developers are ree to change the name o the generated JA: ile by overriding this variable. V I you need to deploy iles rom several dierent directories, you can use <fileset> ele- ments to deine which iles to include. For e$ample, i you also want to include iles rom the src5resources directory, you could do the ollowing4 Oproperty nameKLpro"ect.nameL valueKLHant.pro"ect.nameNL 5D Oproperty nameKLpro"ect.versionL valueKL@.AL 5D ... Otarget nameKLpac!ageL dependsKLcompileL descriptionKL'enerate JA: ileLD O"ar destileKLUHdist.dirN5UHpro"ect.nameN-UHpro"ect.versionN."arLD Oileset dirKLUHbuild.classes.dirNL5D Oileset dirKLsrc5resourcesL5D O5"arD O5targetD I we have a loo! inside the JA: ile generated by this tas!, we might notice the e$tra +E#A-I?F directory, which contains a ile called +A?IFE/#.+F. #his is where metadata about the version o the ile is stored, along with other details such as the product and vendor names4 U jar -tf dist!tax-calculator-&.'.jar +E#A-I?F5 +E#A-I?F5+A?IFE/#.+F com5 com5"avapowertools5 com5"avapowertools5antdemo5 com5"avapowertools5antdemo5domain5 com5"avapowertools5antdemo5web5 com5"avapowertools5antdemo5+ain.class com5"avapowertools5antdemo5domain5>ustomer.class com5"avapowertools5antdemo5domain5#a$>alculator.class com5"avapowertools5antdemo5domain5#a$:ate.class com5"avapowertools5antdemo5web5#a$>alculator>ontroller.clas ... Sy deault, the +A?IFE/#.+F ile contains very little. A sample is shown here4 +aniest-0ersion4 @.A Ant-0ersion4 Apache Ant @.;.A >reated-Sy4 @.T.A-b@AB (/un +icrosystems Inc.) &owever, this ile is a great place to put version and build numbers and5or timestamps. Cutting a version number and a build number (or timestamp) into your deployed pac!- ages is a good habit to get into%you never !now when you need to wor! out e$actly which build has "ust been deployed into production. In Ant, you can add e$tra details into the +A?IFE/#.+F ile using the <manifest> element in the <jar> tas!4 Otarget nameKLpac!ageL dependsKLcompileL descriptionKL'enerate JA: ileLD OtstampD Oormat propertyKLbuild.dateL patternKLEEEE, d ++++ yyyyL5D Oormat propertyKLbuild.timeL patternKLhh4mm aL5D O5tstampD O"ar destileKLUHdist.dirN5UHpro"ect.nameN-UHpro"ect.versionN."arL basedirKLUHbuild.classes.dirNL D OmaniestD Oattribute nameKLSuilt-SyL valueKLUHuser.nameNL5D Oattribute nameKL/peciication-#itleL valueKLUHpro"ect.nameNL5D Oattribute nameKL/peciication-0ersionL valueKLUHpro"ect.versionNL5D Oattribute nameKL/peciication-0endorL valueKLA>+E IncorporatedL5D Oattribute nameKLImplementation-#itleL valueKLcommonL5D Oattribute nameKLImplementation-0ersionL valueKLUHpro"ect.versionN - built at UHbuild.timeN on UHbuild.dateN L5D Oattribute nameKLImplementation-0endorL valueKLA>+E IncorporatedL5D O5maniestD O5"arD O5targetD &ere we use the <tstamp> tas! to generate a timestamp corresponding to the current time. #his tas! automatically sets three properties4 D()A*+, )()A*+, and ),DA-. #he irst two (D()A*+ and )()A*+) are set to the current date and time, respectively, in a airly machine-riendly (but not particularly readable) ormat (e.g., Q3AA;AY3AR and Q3A3=,R respectively). #he ),DA- value is more readable (e.g., QAu- gust 3A 3AA;R), but or a build date, we want something a little more precise. /o, we use the nested <format> element to set some properties o our own. #he deployed +A?IFE/#.+F ile will now loo! something li!e this4 +aniest-0ersion4 @.A Ant-0ersion4 Apache Ant @.;.A >reated-Sy4 @.T.A-b@AB (/un +icrosystems Inc.) Suilt-Sy4 wa!aleo /peciication-#itle4 ta$-calculator /peciication-0ersion4 @.A /peciication-0endor4 A>+E Incorporated Implementation-#itle4 common Implementation-0ersion4 @.A - built at @A43T C+ on +onday, 3A August Implementation-0endor4 A>+E Incorporated 8enerating a 9AR File or an $AR File 9eb applications are usually distributed in the orm o a 9A: ile. 9A: iles can (usually) be deployed to any Java web server using a very simple deployment procedure. #he e$act procedure will vary rom one application server to another, but it is usually something that can be done by a system administrator without a detailed understanding o the application. A 9A: ile is simply a JA: ile with a ew e$tra re-uirements. In particular, a 9A: ile needs a special directory called 9ES-I?F, which contains application classes, libra- ries, and coniguration iles. Files placed under this directory cannot be accessed directly on the deployed web application, so this is a convenient place to put compiled classes, libraries, coniguration iles, and J/C pages. #he basic directory structure o a 9A: ile is illustrated in the ollowing table. A typical .A/ directory structure Directory 5 9ES-I?F5 Description Cublicly accessible web pages >oniguration iles, not visible rom the web site 9ES-I?F5classes >ompiled classes 9ES-I?F5lib Application libraries #he <ar> tas! is an e$tension o the <jar> tas! that ta!es into account the special structure o a 9A: ile. Eou use special nested elements to deine the iles to go into the 9ES-I?F5classes, 9ES-I?F5lib or 9ES-I?F directories. /uppose you need to generate a 9A: ile or a J/C-based web application. #he J/C iles are stored in a directory called web. #his directory also contains the 9ES-I?F sub- directory, where we store the web.$ml ile and any other coniguration iles we need. &owever, the application libraries and compiled classes will be obtained rom other pro"ect directories. Eou can create a 9A: ile rom this directory structure using the <ar> tas!, as shown here4 Oproperty nameKLweb.dirL locationKLwebL 5D Oproperty nameKLdist.dirL locationKLdistL 5D Otarget nameKLwarL dependsKLcompileL descriptionKL'enerate 9A: ileLD Owar destileKLUHdist.dirN5UHpro"ect.nameN-UHpro"ect.versionN.warL web$mlKLUHweb.dirN59ES-I?F5web.$mlLD Oileset dirKLUHweb.dirNL 5D Oclasses dirKLUHbuild.classes.dirNL5D Olib dirKLUHlibNLD Oinclude nameKLV."arL 5D O5libD O5warD O5targetD #he usage o this tas! is similar to the <jar> tas! we saw previously (see Q'enerating a JA: File,R earlier in this section), with a ew additions. #he most important conig- uration ile in the 9ES-I?F directory is the web.$ml ile. As can be seen here, you use the ebxml attribute to speciy the location o this ile. As with the <jar> tas!, you can use one or more <fileset> elements to deine the iles you want to deploy in the root directory. In addition, the <classes> element deines the iles that will be placed in the 9ES-I?F5classes directory. And the <lib> element deines the application libraries to be deployed in the 9ES-I?F5lib directory. ,i!e the <jar> tas!, the <ar> tas! will generate a +A?IFE/#.+F ile in the +E#A-I?F directory. And li!e the <jar> tas!, you can use the <manifest> element to add e$tra inormation into this ile. For more comple$ applications, a 9A: ile will not be enough. I you are developing an EJS-based application, you may need to deploy your application as an EA: ile. An EA: ile, li!e a 9A: ile, is an e$tension o the JA: ile ormat. Instead o a web.$ml ile, every EA: ile contains an application.$ml ile. #he OearD tas!, another e$tension o the OjarD tas!, is airly easy to use. Eou simply speciy the location o your applica- tion.$ml ile using the app$ml attribute, and then use one or more OfilesetD elements to indicate what iles need to be bundled. For e$ample, i you wanted to deploy the previous 9A: ile, plus a ew particular JA: iles (stored in a directory speciied by the $"ear.lib# property), you could do the ollowing4 Otarget nameKLearL dependsKLwarL descriptionKL'enerate EA: ileLD Oear destileKLUHdist.dirN5UHpro"ect.nameN-UHpro"ect.versionN.earL app$mlKLsrc5metadata5application.$mlLD Oileset ileKLUHdist.dirN5UHpro"ect.nameN-UHpro"ect.versionN.warL 5D Oileset dirKLUHear.libNLD Oinclude nameKLV."arL 5D O5ilesetD O5earD O5targetD Deploying Your Application 2nce you have generated a pac!aged version o your application, you will certainly want to deploy it. For e$ample, i you are developing a web application, you may want to deploy it to a web server on your own machine, or to a remote server or testing. 2r, i you are developing a shared library, you may copy your latest version to a local web server, where other users can consult the documentation and download the ACI. Copying Files #he simplest way to deploy an application is to copy the pac!aged ile to the target server. 2 course, this will only wor! i the target server is hosted on the development machine or i the target server has a shared drive that can be mapped to rom the development5build machine, and the current user has write access to these directories. Secause this is generally the case or a local development machine, this approach is oten a simple, pragmatic way to deploy (and redeploy) a web application to a locally running application server. Eou can copy a ile to another directory by using the <copy> tas!, as shown here4 Oproperty nameKLtomcat.install.dirL locationKLUHuser.homeN5servers5tomcat 5apache-tomcat-B.B.36L 5D Otarget nameKLlocal.deployL dependsKLwarL descriptionKLDeploy to local #omcat instanceLD Ocopy ileKLUHdist.dirN5UHpro"ect.nameN-UHpro"ect.versionN.warL todirKLUHtomcat.install.dirN5webappsL 5D O5targetD In this e$ample, we simply deined a property pointing to a local #omcat installation, and used the <copy> tas! to copy the generated 9A: ile to the #omcat webapps directory, where #omcat will be able to pic! it up and deploy it automatically. +any application servers wor! in the same way. 2 course, you may want to rename the 9A: ile on the way. #ypically, you may want to strip o the version number when you deploy the web application so that users can simply access the application using the pro"ect name. Eou can do this using the tofile attribute instead o todir4 Oproperty nameKLtomcat.install.dirL locationKLUHuser.homeN5servers5tomcat 5apache-tomcat-B.B.36L 5D Otarget nameKLlocal.deployL dependsKLwarL descriptionKLDeploy to local #omcat instanceLD Ocopy ileKLUHdist.dirN5UHpro"ect.nameN-UHpro"ect.versionN.warL toileKLUHtomcat.install.dirN5webapps5UHpro"ect.nameN.warL 5D O5targetD As you might e$pect, you aren(t limited to copying a single ile. Eou can also use the <copy> tas! to copy sets o iles, using the usual Ant path-li!e tags. For e$ample, you might want to deploy the latest Javadoc to a local Apache web server. /uppose your Apache server(s web directory is 5var5www5public1html, with a special subdirectory or each pro"ect. #he Javadoc needs to be deployed to a directory called "avadoc directly underneath the pro"ect directory. I you are running Ant on the same machine as the Apache server, you could deploy your Javadoc simply using the <copy> tas!, as shown here4 Oproperty nameKLweb.dirL locationKL5var5www5public1htmlL 5D Otarget nameKLlocal.documentationL dependsKL"avadocL descriptionKLDeploy documentation to local web serverLD Ocopy todirKLUHweb.dirN5UHpro"ect.nameN5"avadocLD Oileset dirKLUHreports."avadocL5D O5copyD O5targetD #he <copy> tas! is a powerul, le$ible tool or ile manipulation, and here we only cover its main eatures. >hec! out the Ant documentation or more details about what it can do. (ther Deployment %echni4ues Ant provides many other ways to deploy your application. For e$ample, the <ftp> tas! lets you deploy to an F#C server. And the <scp> tas! lets you deploy iles using the widely used (/ecure >opy) />C protocol. A simple e$ample o the <scp> tas! is shown here4 Otarget nameKLremote.deployL dependsKLwarL descriptionKLDeploy to a remote integration server using />CLD Oscp ileKLUHdist.dirN5UHpro"ect.nameN-UHpro"ect.versionN.warL todirKLuser^testserver45home5integration5tomcatbase5webappsL passwordKLpasswordL5D O5targetD #here are also many third-party libraries that can help you here. Using Ant in $clipse Ant is well-supported in virtually all modern Java IDEs, and Eclipse is no e$ception. Eclipse allows you to create a new Eclipse pro"ect using an e$isting Ant ile, and rec- ogni8es the structure o Ant build iles. #he 2utline view gives you a structured vision o your build ile. In addition, you can e$ecute any target directly rom within Eclipse using the conte$tual menu Using Ant in 'etBeans Ant integrates smoothly into ?etSeans. Indeed, by deault, ?etSeans uses Ant inter- nally to organi8e your pro"ect, even i you don(t as! it to. ?etSeans automatically recogni8es Ant build iles and displays the build ile targets. As in Eclipse, you can e$ecute targets directly using the conte$tual menu. Real time e&le for 0uild.&ml - compiles the ej0 code- pac3ages to jar file and deploys to j0oss ser!er +:&ml !ersion;<=.><:, +?22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 22, +?22 Boss 0uild file 22, +?22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 22, +project name;<Boss< default;<ej0jar< 0asedir;<.<, +property en!ironment;<en!<@, +property name;<src.dir< !alue;<AB0asedirC@src@main<@, +property name;<src.resources< !alue;<AB0asedirC@src@resources<@, +property name;<j0oss.home< !alue;<ABen!.B(SSD)(*$C<@, +property name;<0uild.dir< !alue;<AB0asedirC@0uild<@, +property name;<0uild.classes.dir< !alue;<AB0uild.dirC@classes<@, +?22 Build classpath 22, +path id;<classpath<, +fileset dir;<ABj0oss.homeC@ser!er@default@li0<, +include name;<E.jar<@, +@fileset, +fileset dir;<ABj0oss.homeC@ser!er@default@deploy@ej0F.deployer<, +include name;<E.jar<@, +@fileset, +fileset dir;<ABj0oss.homeC@ser!er@default@deploy@j0oss2aop2jd3G>.deployer<, +include name;<E.jar<@, +@fileset, +fileset dir;<ABj0oss.homeC@li0<, +include name;<E.jar<@, +@fileset, +pathelement location;<AB0uild.classes.dirC<@, +?22 So that "e can get jndi.properties for InitialConte&t and logHj.&ml file 22, +pathelement location;<AB0asedirC@client2config<@, +@path, +property name;<0uild.classpath< refid;<classpath<@, +?22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 22, +?22 Prepares the 0uild directory 22, +?22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 22, +target name;<prepare< , +m3dir dir;<AB0uild.dirC<@, +m3dir dir;<AB0uild.classes.dirC<@, +@target, +?22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 22, +?22 Compiles the source code 22, +?22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 22, +target name;<compile< depends;<prepare<, +ja!ac srcdir;<ABsrc.dirC< destdir;<AB0uild.classes.dirC< de0ug;<on< deprecation;<on< optimi7e;<off< includes;<EE<, +classpath refid;<classpath<@, +@ja!ac, +@target, +target name;<ej0jar< depends;<compile<, +jar jarfile;<0uild@titan.jar<, +fileset dir;<AB0uild.classes.dirC<, +include name;<com@it@domain@E.class<@, +include name;<com@it@tra!elagent@E.class<@, +@fileset, +fileset dir;<ABsrc.resourcesC@<, +include name;<*$%A2I'F@persistence.&ml<@, +@fileset, +@jar, +copy file;<0uild@titan.jar< todir;<ABj0oss.homeC@ser!er@default@deploy<@, +@target, +target name;<run.client< depends;<ej0jar<, +ja!a classname;<com.it.clients.Client< for3;<yes< dir;<.<, +classpath refid;<classpath<@, +@ja!a, +@target, +?22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 22, +?22 Cleans up generated stuff 22, +?22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 22, +target name;<clean.d0<, +delete dir;<ABj0oss.homeC@ser!er@default@data@hypersonic<@, +@target, +target name;<clean<, +delete dir;<AB0uild.dirC<@, +delete file;<ABj0oss.homeC@ser!er@default@deploy@it.jar<@, +@target, +@project, Setting Up a Project Using *a!en *a!en and the De!elopment Build Process 9e loo! at the second ma"or player in the Java build tools arena4 +aven.
+aven is an increasingly popular open source build management tool or en- terprise Java pro"ects, designed to ta!e much o the hard wor! out o the build process. +aven uses a declarative approach, in which the pro"ect structure and contents are described, rather then the tas!-based approach used in Ant or in traditional +a!e iles or shell scripts. +aven also strongly promotes the use o standard directory structures and a well-deined build liecycle. #his helps enorce company-wide development standards and reduces the time needed to write and maintain build scripts. +aven(s authors describe +aven as a Qpro"ect management ramewor!,R and it is in- deed much more than "ust a simple build scripting tool. +aven(s declarative, standards- based approach to pro"ect build management simpliies many aspects o the pro"ect liecycle. As well as catering or compiling, building, testing, and deploying your application with a minimum o eort, +aven oers a number o other !ey advantages4 W Cro"ect dependencies are declared and managed in a clean, transparent way, which reduces the ris! o dependency-related errors and ma!es or better documentation. W +aven lets you easily generate useul, high--uality, technical documentation and reports about the current state o the pro"ect and pro"ect team members. ?ote that we aren(t ta!ing about a good user manual, which is an altogether dierent issue, but, rather, about technical documentation, written by developers or developers. In many technical pro"ects, decent technical documentation is woeully inade- -uate. It is nevertheless a vital part o modern sotware development, especially when dislocated teams are involved. W +aven proposes a clear standard directory layout or source code, pro"ect resources and coniguration iles, generated output, and pro"ect documentation. #his ma!es it easier to understand new +aven pro"ects, and also ma!es the +aven build scripts cleaner and simpler. W +aven integrates smoothly with source code repositories, continuous integration servers, and issue trac!ing systems. W #he +aven build cycle is le$ible4 it is easy to integrate additional build tas!s, using e$isting +aven plug-ins or by writing Ant scriptlets. All o these points ma!e +aven an invaluable tool or Java development teams *a!en and Ant 9ithout a doubt, the most popular and most well-!nown build tool in the Java sphere is Ant. Ant is a ine tool and a hugely successul open source pro"ect. +illions o Java developers are amiliar with it. And, as we will see throughout the rest o the boo!, there is hardly a Java tool in e$istence that doesn(t integrate with Ant. &owever, when you write a lot o Ant build scripts, you ind yoursel as!ing yoursel (and other team members) the same -uestions over and over again4 9here will the source code goP 9hat about the unit testsP &ow do we handle dependenciesP &ow will we bundle up the deliverable applicationP 9hat shall we call the main targetsP Indi- vidually, Ant lets you deal with each o these tas!s with a high degree o le$ibility and power. &owever, you still have to write the tas!s rom scratch or duplicate and modiy an Ant script rom a previous pro"ect. And when you move to a new pro"ect or company, you need to as! these -uestions once again to (begin to) understand the build process in place. +any (although not all) pro"ects do ollow airly common and well-!nown patterns. A lot o what you need to conigure in your build process is pretty much run-o-the-mill. It always seems a shame to redo the wor! again or each new pro"ect. +aven can help you here. +aven ta!es a lot o the grunt wor! out o the build process, and tries to lever the combined e$perience and best practice o a large community o developers. Sy adhering to a certain number o conventions and best practices, +aven lets you remove the drudgery o all the low-level tas!s in your build scripts. In the rest o this chapter, we will see how. Installing *a!en In this chapter, we will go through how to install +aven 3 on various platorms. #he basic installation process is straightorward, and is the same or all platorms. +aven is a pure Java tool, so irst o all you need to ensure that there is a recent version o Java (@.= or later) on your machine. #hen, download the latest distribution rom the +aven download site and e$tract it into an appropriate directory. Finally, "ust add the bin subdirectory to the system path. I you are amiliar with installing Java tools, this should be enough to get you started. In the rest o this chapter, we discuss some more detailed environment-speciic considerations. Installing *a!en on a Uni& *achine 9e run through how to install +aven into a 7ni$ environment. Installing +aven in a 7ni$-based environment is a relatively simple tas!. Download the latest version in the ormat o your choice, and e$tract it to an appropriate directory. >onventions vary greatly rom one system to another, and rom one system adminis- trator to another4 I generally place the maven installation in a nonuser-speciic directory such as 5usr5local, as shown here4 \ cd 5usr5local \ tar $v8 maven-3.A.;-bin.tar.g8 \ ls #his will e$tract the maven installation in a directory called maven-3.A.;. For conven- ience, on a 7ni$ system, I generally create a symbolic lin! to this directory to ma!e upgrades easier to manage4 \ ln -s maven-3.A.; maven \ ls -al total @T drw$r-$r-$ 6 root root =A]T 3AAT-AY-AT @64@Y . drw$r-$r-$ B6 root root =A]T 3AAT-A;-3A 3@463 .. lrw$rw$rw$ @ root root @@ 3AAT-AY-AT @64@; maven -D maven-3.A.; drw$r-$r-$ T root root =A]T 3AAT-AY-AT @64@; maven-3.A.; ?ow "ust add the maven5bin directory to your environment path. #ypically, you will set this up in one o your environment initiali8ation scripts (or e$ample, i you are using Sash, you could place this coniguration in the _5.bashrc ile i you "ust need to set it up or your account, or in 5etc5bashrc i you want to set it up or all users on this machine). Don(t orget to ma!e sure that the JA0A1&2+E environment variable is deined as well. &ere is a typical e$ample4 CA#&KUCA#&45usr5local5maven5bin JA0A1&2+EK5usr5lib5"vm5"ava e$port CA#& JA0A1&2+E ?ow chec! that it wor!s by running the maven command rom the command line4 \ mvn --version +aven version4 3.A.; Installing *a!en on a 9indo"s *achine Installing +aven on a 9indows machine is also relatively straightorward, although the application still lac!s the graphical installation pac!age amiliar to 9indows users. First, download and un8ip the +aven distribution into an appropriate directory. +ost 9indows machines will have a graphical compression utility that you can use to e$tract the XIC ile, although i you are stuc!, you can always use the Java "ar command-line tool, as shown here4 >4D "ar -$ maven-3.A.=-bin.8ip In t, +aven has been installed in the C4<tools<maven<maven-3.A.= directory, although o course you can install it anywhere that suits your particular needs. A more conventional choice might be something li!e >4<Crogram Files<Apache /otware Foundation<maven-3.A.=. Secause it is a Java application, +aven also e$pects the JA0A1&2+E environment variable to be correctly deined. ?e$t add the +aven bin directory to your CA#& user variable.Eou will need to open a new console window to see the new path ta!en into account. ?ow, chec! that +aven is correctly installed by running mvn --version4 >4<Dmvn --version +aven version4 3.A.= ?ow you should have a wor!ing +aven environment ready to goZ Declarati!e Builds and the *a!en Project (0ject *odel An Introduction to Declarati!e Build *anagement Seore we loo! at how to create and wor! with pro"ects in +aven, we need to discuss some o the basics. #he most undamental o these is the +aven Cro"ect 2b"ect +odel, or C2+, which we will loo! at in this chapter. In the process, we also will cover some important basic principles o +aven development, as well as a lot o the !ey eatures o +aven. As many, i not most, new +aven users are already amiliar with Ant, we will loo! at how the +aven approach diers rom the one used by Ant, and how this can help simpliy your builds. For Ant users, the +aven philosophy can ta!e a little getting use to. 7nli!e Ant, which is very much tas!-oriented, +aven uses a highly declarative approach to pro"ect builds. In Ant, or e$ample, you list the tas!s that must be perormed to compile, test, and deliver your product. In +aven, by contrast, you describe your pro"ect and your build process, relying on conventions and sensible deault values to do much o the grunt wor!. #he heart o a +aven 3 pro"ect, the C2+, describes your pro"ect, its structure, and its dependencies. It contains a detailed description o your pro"ect, including in- ormation about versioning and coniguration management, dependencies, application and testing resources, team members and structure, and much more. #he C2+ ta!es the orm o an *+, ile (called pom.$ml by deault), which is placed in your pro"ect home directory. ,et(s loo! at a practical e$ample. 2ne o the most undamental parts o any Java build process involves compiling your Java classes. In a typical Ant build, you would use the <javac> tas! to compile your classes. #his involves deining the di- rectory or directories containing your Java source code, the directory into which the compiled classes will be placed, and creating a classpath that contains any dependencies needed to compile your classes. Seore invo!ing the compiler, you need to be sure to create the target directory. #he corresponding Ant script might loo! something li!e this4 Opro"ect nameKL!iller-appLD ... Oproperty nameKLsrc.dirL locationKLsrc5main5"avaL5D Oproperty nameKLtarget.dirL locationKLtarget5classesL5D ... Opath idKLcompile.classpathLD Oileset dirKLlibLD Oinclude nameKLVV5V."arL5D O5ilesetD O5pathD ... Otarget nameKLinitLD Om!dir directoryKLUHtarget.dirNL5D O5targetD Otarget nameKLcompileL dependsKLinitL descriptionKL>ompile the application classesLD O"avac srcdirKLUHsrc.dirNL destdirKLUHtarget.dirNL classpathreKLcompile.classpathL sourceKL@.BL targetKL@.BL 5D O5targetD O5pro"ectD #o compile your application, you would invo!e the QcompileR target4 U ant compile In +aven, the build ile or this pro"ect would be somewhat dierent. First o all, you would not need to declare the source and target directories.In act, the only thing that we need to speciy is that our pro"ect code is written using Java B language eatures, or a Java B J0+. +aven uses components called plug-ins to do most o the serious wor!. #he plug-in that handles Java compilation is called maven-compiler-plugin. /o, to set up Java com- pilation in our +aven script, all we need to do is to conigure this plug-in, which we do as ollows4 Opro"ect...D ... ObuildD Oplug-insD OZ-- 7sing Java B --D OpluginD OartiactIdDmaven-compiler-pluginO5artiactIdD OconigurationD OsourceD@.BO5sourceD OtargetD@.BO5targetD O5conigurationD O5pluginD O5plug-insD O5buildD ... O5pro"ectD ?ote that had we been using the deault javac source and target values, even this con- iguration would not have been needed. #he one thing that we glossed over here is the +aven e-uivalent o the lib directory. In Ant, the libraries re-uired by a pro"ect are stored in a local pro"ect directory, oten called lib. In the above e$ample, we deined a classpath called compile.classpath, which included all the JA: iles in this directory. +aven uses a totally dierent approach. In +aven, JA: iles are rarely, i ever, stored in the pro"ect directory structure. Instead, dependencies are declared within the build script itsel. An e$tract rom a list o +aven dependencies is shown here4 Opro"ect...D ... OZ-- C:2JE># DECE?DE?>IE/ --D OdependenciesD OZ-- &ibernate --D OdependencyD OgroupIdDorg.hibernateO5groupIdD OartiactIdDhibernateO5artiactIdD OversionD6.3.=.O5versionD O5dependencyD OZ-- ,og=" --D OdependencyD OgroupIdDlog="O5groupIdD OartiactIdDlog="O5artiactIdD OversionD@.3.@=O5versionD O5dependencyD ... O5dependenciesD O5pro"ectD Dependency management is a ma"or eature o +aven 3, and we loo! at it in much more detail in Q+anaging #ransitive DependenciesQ in chA3-dependency-manage- ment. #he third part o our C2+ ile contains inormation that is largely irrelevant or the tas! at hand (compiling our Java class), but will come in handy later on. At the start o each +aven C2+ ile, you will ind a list o descriptive elements describing things li!e the pro"ect name, version number, how it is to be pac!aged, and so on. #his is shown here4 Opro"ect...D OZ-- C:2JE># DE/>:IC#I2? --D Omodel0ersionD=.A.AO5model0ersionD OgroupIdDcom.mycompanyO5groupIdD OartiactIdDmyappO5artiactIdD Opac!agingD"arO5pac!agingD OnameD.iller applicationO5nameD OversionD@.AO5versionD OdescriptionD+y new !iller appO5descriptionD ... O5pro"ectD &ere is the complete corresponding +aven build ile4 OP$ml versionKL@.AL encodingKL7#F-YLPD Opro"ect $mlnsKLhttp455maven.apache.org5C2+5=.A.AL $mlns4$siKLhttp455www.w6.org53AA@5*+,/chema-instanceL $si4schema,ocationKLhttp455maven.apache.org5C2+5=.A.A http455maven.apache.org 5maven-v=1A1A.$sdLD OZ-- C:2JE># DE/>:IC#I2? --D Omodel0ersionD=.A.AO5model0ersionD OgroupIdDcom.mycompanyO5groupIdD OartiactIdDmyappO5artiactIdD Opac!agingDwarO5pac!agingD OnameD.iller applicationO5nameD OversionD@.AO5versionD OdescriptionD+y new !iller appO5descriptionD OZ-- S7I,D >2?FI'7:A#I2? --D ObuildD Oplug-insD OpluginD OartiactIdDmaven-compiler-pluginO5artiactIdD OconigurationD OsourceD@.BO5sourceD OtargetD@.BO5targetD O5conigurationD O5pluginD O5plug-insD O5buildD OZ-- C:2JE># DECE?DE?>IE/ --D OdependenciesD OZ-- &ibernate --D OdependencyD OgroupIdDorg.hibernateO5groupIdD OartiactIdDhibernateO5artiactIdD OversionD6.3.=.O5versionD O5dependencyD OZ-- ,og=" --D OdependencyD OgroupIdDlog="O5groupIdD OartiactIdDlog="O5artiactIdD OversionD@.3.@=O5versionD O5dependencyD ... O5dependenciesD O5pro"ectD /o a +aven build ile is not necessarily any shorter than an Ant build ile or an e-uiv- alent pro"ect. Sut the nature o the inormation it contains is very dierent. Ant users will notice that there is no sign o any target-li!e structures, or any indication o what goals can be run4 V U mvn compile In a similar manner, this same build ile can be used to run the application(s unit tests, stored by convention in the src5test5"ava directory, by invo!ing the QtestR goal4 U mvn test And this same build ile can be used to bundle up a JA: ile containing the compiled classes, via the Qpac!ageR goal4 U mvn package #here are many other goals. 9e will cover the main ones in the remainder o this chapter, and in the other +aven-related chapters o this boo!. #his illustrates another o +aven(s strong points4 all o these goals are standard +aven goals and will wor! in a similar way on any +aven pro"ect. As can be gleaned here, one o the guiding principles o +aven is to use sensible deault values wherever possible. #his is where the +aven conventions play an important role. +aven pro"ects are e$pected to respect a certain number o conventions, such as placing your main source code in the src5main5"ava directory and your test code in the src5main5test directory. #hese conventions are largely deined in a special C2+ ile, the so-called /uper C2+, rom which every C2+ is e$tended. In practice, this means that i you respect the standard +aven conventions, you can get away with surprisingly little in your C2+ ile. Project Conte&t and Artifacts #he irst part o a C2+ ile basically introduces the pro"ect and its conte$t, including the group and artiact IDs that uni-uely identiy this pro"ect in the +aven world, as well as how the artiact is pac!aged ("ar, war, ear`), and the current version number. #his is a small but crucial part o the +aven C2+ ile, in which you deine many !ey aspects o your pro"ect. A typical e$ample is shown here4 Opro"ect $mlnsKLhttp455maven.apache.org5C2+5=.A.AL $mlns4$siKLhttp455www.w6.org53AA@5*+,/chema-instanceL $si4schema,ocationKLhttp455maven.apache.org5C2+5=.A.A http455maven.apache.org5maven-v=1A1A.$sdLD Omodel0ersionD=.A.AO5model0ersionD OgroupIdDcom.mycompany.accountingO5groupIdD OartiactIdDaccounting-coreO5artiactIdD Opac!agingD"arO5pac!agingD OversionD@.@O5versionD ... #he inormation in this section is used to identiy the pro"ect uni-uely and, in particular, the artiact that it produces. #his is one o the hallmar!s o +aven, and it is what enables you to deine very precisely your pro"ects dependencies. Indeed, the inormation in this section allows +aven to derive a uni-ue path to the artiact generated by this pro"ect. . com5mycompany5accounting5accounting-core5@.@5accounting-core-@.@."ar com5mycompany5accounting a groupid accounting-core a articatId @.@ a versionId accounting-core a artiactId "ar a pac!aging ,et(s loo! at how +aven does this in a little more detail. #he <group0d> element is supposed to identiy a particular pro"ect or set o libraries within a company or organi8ation. Sy convention, it oten corresponds to the initial part o the Java pac!age used or the application classes (e.g., Qorg.apache.mavenR or +aven pro"ects, Qorg.springramewor!R or the /pring libraries, and so on), although this is not always the case. 9hen the artiact is deployed to a +aven repository, the group0d is split out into a matching directory structure on the repository. #he artifact0d represents the actual name o the pro"ect. #his, combined with the group0d, should uni-uely identiy the pro"ect. Every pro"ect also has a <version> element, which indicates the current version number. #his number usually reers to ma"or releases (Q&ibernate 6.3.=,R Q/pring 3.A.B,R and so on), as opposed to speciic build numbers, which are dierent or each build. Each version has its own directory on the +aven repository, which is a subdirectory o the pro"ect directory. /o, in the above e$ample, the generated artiact would be stored on the +aven repo- sitory in a directory called com5mycompany5accounting5accounting-core5@.@. 9hen it comes to inally generating a deliverable pac!age, +aven supports many di- erent ile ormats. At the time o this writing, supported pac!age types included pom, "ar, maven-plugin, e"b, war, ear, rar, and par. As the name suggests, you use the <packaging> element to indicate the pac!aging type. For e$ample, in this listing, +aven will generate a ile called accounting-core-@.@."ar. #he Q"arR e$tension comes rom the <packaging> element. +aven saves you the hassle o !nowing e$actly what iles need to go into the delivered pac!age and what iles were delivered. All you need to do is provide the type and +aven will do the rest. Finally, there is an optional element called <classifier> that can be used to distinguish dierent distributions o the same version o a product. For e$ample, you might have a distribution or Java @.=, and a dierent distribution or Java B. #he #est?' unit testing library does "ust this. #he pro"ect description or the Java B version o this prod- uct might contain something li!e this4 OgroupIdDorg.testngO5groupIdD OartiactIdDtestngO5artiactIdD Opac!agingD"arO5pac!agingD OversionDB.BO5versionD OclassiierD"d!@BO5classiierD #his would produce a ile called testng-B.@-"d!@B."ar. #he e-uivalent version or Java @.= would be testng-B.@-"d!@=."ar. *anaging Dependencies 2ne o the most powerul +aven eatures is the way it handles dependencies. A typical medium-si8e Java pro"ect can re-uire do8ens, or even hundreds, o JA: iles. 9ithout a strict dependency management strategy, this can -uic!ly become out o control. It can rapidly become diicult to !now e$actly what library versions a particular pro"ect is using, and conlicting dependency re-uirements can trigger hard-to-ind errors. +aven addresses these issues using a two-pronged approach, based on the notions o declarative dependencies and a central repository o JA: iles. In +aven, a pro"ect(s dependencies are declared in the pom.xml ile. #he <dependencies> section, shown here, lets you list the libraries that your application needs to compile, be tested, and be run. Dependencies are deined using the +aven artiact naming schema (see QCro"ect >onte$t and Artiacts,R earlier in this section), which allows you to precisely identiy the e$act version o each library you need. In addition, you usually only need to list the libraries you need directly to compile your code4 with a eature called #ransitive Dependencies +aven 3 will discover and retrieve any additional libraries that those libraries need to wor!. &ere is a simple e$ample o the dependencies section in a C2+ ile4 ... OdependenciesD OdependencyD OgroupIdDorg.hibernateO5groupIdD OartiactIdDhibernateO5artiactIdD OversionD6.@O5versionD O5dependencyD OdependencyD OgroupIdD"unitO5groupIdD OartiactIdD"unitO5artiactIdD OversionD6.Y.@O5versionD OscopeDtestO5scopeD O5dependencyD O5dependenciesD ... 9e are saying that our application re-uires &ibernate 6.@ (and, implicitly, all the other libraries that this version o &ibernate re-uires). And, to run our unit tests, we need J7nit 6.Y.@. Customi7ing Your Build Process Although optional, the <build> section is a !ey part o any but the simplest o C2+ iles. #his section is where you tailor your +aven pro"ect build process to your e$act needs, deining various plug-in conigurations and setting up additional tas!s that need to be perormed at various points in the build liecycle. #he +aven build process is very le$ible, and it is easy to integrate new tas!s by using plug-ins. Clug-ins are a powerul way to encapsulate build logic into reusable compo- nents, or use in uture pro"ects. Eou may use plug-ins to generate source code rom a 9/D, ile or rom &ibernate mappings, or e$ample. +any plug-ins are available, both rom the +aven web site and rom other third-party providers such as >odehaus. V Secause they are used e$tensively in the standard +aven build liecycle tas!s, you also can use plug-ins to customi8e e$isting aspects o the +aven liecycle. A common e$- ample o this type o coniguration, shown in the e$ample below, is to conigure the maven-compiler-plugin, which compiles the pro"ect source code or use with Java B (by deault, the +aven compiler generates code compatible with JD. @.6). #he <build> section is also where resource directories are deined. Eou also can deine resources that will be bundled into the inal pac!age produced by the pro"ect, and resources that need to be on the classpath during unit tests. Sy deault, any iles placed in the src5main5resources will be pac!aged into the generated pro"ect artiact. Any iles in src5test5resources will be made available on the pro"ect classpath during unit tests. Eou also can add additional resource directories. In the ollowing e$ample, we set up an additional resource directory or &ibernate mapping iles. At build-time, these iles automatically will be bundled into the resulting pro"ect artiact, along with the com- piled classes and other resource iles. #he ollowing listing illustrates a typical build section, illustrating these e$amples4 ... ObuildD Oplug-insD OpluginD OgroupIdDorg.apache.maven.plug-insO5groupIdD OartiactIdDmaven-compiler-pluginO5artiactIdD OconigurationD OsourceD@.BO5sourceD OtargetD@.BO5targetD O5conigurationD O5pluginD O5plug-insD OresourcesD OresourceD OdirectoryDsrc5main5hibernateO5directoryD O5resourceD O5resourcesD O5buildD ... Setting Up Reporting An important part o any pro"ect is internal communication. Although it is not a silver bullet, a centrali8ed technical pro"ect web site can go a long way toward improving visibility within the team, especially with large or geographically dispersed teams. #he site generation unctionality in +aven 3 lets you set up a proessional--uality pro"ect web site with little eort. Eou use the <reporting> section to conigure options or +aven site generation. In the absence o any reporting section, +aven will generate a simple site with inormation about the pro"ect derived rom the inormation provided in the C2+ ile. #he <reporting> section lets you add many other additional reports, such as "avadoc, unit test results, >hec!style or C+D reports, and so on. In this e$ample, we add >hec!style reporting to the generated site4 OreportingD Oplug-insD OpluginD OartiactIdDmaven-chec!style-pluginO5artiactIdD OconigurationD Oconig,ocationDconig5company-chec!s.$mlO5conig,ocationD Oenable:ules/ummaryDalseO5enable:ules/ummaryD Oails2nErrorDtrueO5ails2nErrorD O5conigurationD O5pluginD O5reportingD Defining Build Profiles #he inal ma"or section o the C2+ ile is the <profiles> section. Croiles are a useul way to customi8e the build liecycle or dierent environments. #hey let you deine properties that change depending on your target environment, such as database con- nections or ilepaths. At compile time, these properties can be inserted into your pro"ect coniguration iles. For e$ample, you may need to conigure dierent database connections or dierent platorms. /uppose JDS> coniguration details are stored in a ile called "dbc.properties, stored in the src5main5resources directory. In this ile, you would use a variable e$pression in the place o the property value, as shown here4 "dbc.connection.urlKUH"dbc.connection.urlN In this case, we will deine two proiles4 one or a development database, and one or a test database. #he <profiles> section o the C2+ ile would loo! li!e this4 OproilesD OZ-- Development environment --D OproileD OidDdevelopmentO5idD OactivationD OactiveSyDeaultDtrueO5activeSyDeaultD O5activationD OpropertiesD OZ-- #he development database --D O"dbc.connection.urlD"dbc4mys-l455localhost5devdbO5"dbc.connection.urlD O5propertiesD O5proileD OZ-- #est environment --D OproileD OidDtestO5idD OpropertiesD OZ-- #he test database --D O"dbc.connection.urlD"dbc4mys-l455localhost5testdbO5"dbc.connection.urlD O5propertiesD O5proileD O5proilesD Each proile has an identiier (<id>) that lets you invo!e the proile by name, and a list o property values to be used or variable substitution (in the <properties> section). For variable substitution to wor! correctly, +aven needs to !now which iles are li!ely to contain variables. Eou do this by activating iltering on resource directories in the <build> section (see Q>ustomi8ing Eour Suild Crocess,R earlier in this section). #o do this in our case, we need to activate iltering on the resource directory entry in the build section (see Q>ustomi8ing Eour Suild CrocessR), as shown here4 ... ObuildD OresourcesD OresourceD OdirectoryDsrc5main5resourcesO5directoryD OilteringDtrueO5ilteringD O5resourceD O5resourcesD O5buildD ... Croiles can be activated in several ways. In this case, we use the active1yDefault prop- erty to deine the development proile as the deault proile. #hereore, running a standard +aven compile with no proiling options will use this proile4 U mvn compile In this case, the generated "dbc.properties ile in the target5classes directory will loo! li!e this4 "dbc.connection.urlK"dbc4mys-l455localhost5devdb #o activate the test proile, you need to name it e$plicitly, using the -+ command line option as shown here4 U mvn compile -+test ?ow, the generated "dbc.properties ile, in the target5classes directory, will be conig- ured or the test database4 "dbc.connection.urlK"dbc4mys-l455localhost5testdb 9e loo! at how to use proiles in more detail in QDeining Suild Croiles. Understanding the *a!en I #ifecycle Cro"ect liecycles are central to +aven 3. +ost developers are amiliar with the notion o build phases such as compile, test, and deploy. Ant build scripts typically have targets with names li!e these. In +aven 3, this notion is standardi8ed into a set o well-!nown and well-deined liecycle phases Instead o invo!ing tas!s or targets, the +aven 3 developer invo!es a liecycle phase. For e$ample, to compile the applica- tion source code, you invo!e the QcompileR liecycle phase4 U mvn compile /ome o the more useul +aven 3 liecycle phases are the ollowing generate-sources 'enerates any e$tra source code needed or the application, which is generally accomplished using the appropriate plug-ins. compile >ompiles the pro"ect source code. test-compile >ompiles the pro"ect unit tests. test :uns the unit tests (typically using J7nit) in the src5test directory. I any tests ail, the build will stop. In all cases, +aven generates a set o test reports in te$t and *+, test reports in the target5sureire-reports directory package Cac!ages the compiled code in its distributable ormat (JA:, 9A:, etc.). integration-test Crocesses and deploys the pac!age i necessary into an environment in which in- tegration tests can be run. install Installs the pac!age into the local repository or use as a dependency in other pro"ects on your local machine. deploy In an integration or release environment, this copies the inal pac!age to the remote repository or sharing with other developers and pro"ects. #he ull list is much longer than this, and can be ound on the +aven web site. V #hese phases illustrate the beneits o the recommended practices encouraged by +aven 34 once a developer is amiliar with the main +aven liecycle phases, he or she should eel at ease with the liecycle phases o any +aven pro"ect. #he liecycle phase invo!es the plug-ins it needs to do the "ob. Invo!ing a liecycle phase automatically invo!es any previous liecycle phases as well. Secause the liecycle phases are limited in number, easy to understand, and well organi8ed, becoming amiliar with the liecycle o a new +aven 3 pro"ect is easy. 7nderstanding the +aven liecycle is also important when it comes to customi8ing your build process. 9hen you customi8e your build process, you basically attach (or Qbind,R to use the +aven terminology) plug-ins to various phases in the pro"ect liecycle. #his may seem more rigid than Ant, in which you basically can deine any tas!s you want and arrange them in any order you li!e. &owever, once you are amiliar with the basic +aven phases, customi8ing the build liecycle in this way is easier to understand and to maintain than the relatively arbitrary se-uences o tas!s that you need to implement in an Ant build process. %he *a!en Directory Structure +uch o +aven(s power comes rom the standard practices that it encourages. A de- veloper who has previously wor!ed on a +aven pro"ect immediately will eel amiliar with the structure and organi8ation o a new one. #ime need not be wasted reinventing directory structures, conventions, and customi8ed Ant build scripts or each pro"ect. Although you can override any particular directory location or your own speciic ends, you really should respect the standard +aven 3 directory structure as much as possible, or several reasons4 W It ma!es your C2+ ile smaller and simpler. W It ma!es the pro"ect easier to understand and ma!es lie easier or the poor guy who must maintain the pro"ect when you leave. W It ma!es it easier to integrate plug-ins. #he C2+ (pom.$ml) and two subdirectories go into the pro"ect home directory4 src or all source code and target or generated artiacts. #he src directory has a number o subdirectories, each o which has a clearly deined purpose4 src5main5"ava Eour Java source code goes here (strangely enoughZ) src5main5resources 2ther resources your application needs src5main5ilters :esource ilters, in the orm o properties iles, which may be used to deine vari- ables only !nown at runtime src5main5conig >oniguration iles src5main5webapp #he web application directory or a 9A: pro"ect src5test5"ava /ource code or unit tests, by convention in a directory structure mirroring the one in your main source code directory src5test5resources :esources to be used or unit tests, but that will not be deployed src5test5ilters :esources ilters to be used or unit tests, but that will not be deployed src5site Files used to generate the +aven pro"ect web site Configuring *a!en to Your $n!ironment 2ne o the principal aims o +aven is to produce portable pro"ect build environments. ?evertheless, each wor! environment has its particularities, which need to be catered or. 9e investigate some common areas where you may need to tailor +aven to suit your particular wor! environment, such as coniguring pro$y servers, deining enterprise repositories, or speciying usernames and passwords. 9hen it comes to deining environment-speciic coniguration details, the most im- portant tool at your disposal is the settings.$ml ile. Each user can have his or her own individual settings.$ml ile, which should be placed in the U&2+E5.m3 directory. #his ile is not placed under version control, and thereore can contain details such as user- names and passwords, which should not be shared in the source code repository. Using a Pro&y I you are wor!ing in a company, you may well be accessing the Internet via a pro$y. +aven relies heavily on accessing the Internet to download the libraries that it needs or your pro"ects and or its own purposes. #hereore, i you are behind a pro$y, you will need to tell +aven about it. +aven stores environment-speciic parameters in a ile called U&2+E5.m35settings.$ml. Eou will have to create this ile i it doesn(t already e$ist. #o deine a pro$y, "ust add a <proxy> element in this ile, as ollows4 OsettingsD Opro$iesD Opro$yD OactiveDtrueO5activeD OprotocolDhttpO5protocolD OhostDpro$y.mycompany.comO5hostD OportDYAYAO5portD OusernameDuserO5usernameD OpasswordDpasswordO5passwordD OnonCro$y&ostsDV.mycompany.comO5nonCro$y&ostsD O5pro$yD O5pro$iesD O5settingsD #he Onon+roxy2ostsD element is useul to deine servers that do not need pro$y access, such as internal enterprise repositories. Using a #ocal *irror Another common use o the settings.$ml ile is to conigure mirror servers. #his typ- ically is done to conigure an organi8ation-wide repository. +any organi8ations use a local repository to store and share internal pac!ages and to act as a pro$y to e$ternal repositories. #his solution is aster and more reliable than re-uiring users to go to the Internet whenever a new dependency is re-uired. #he ollowing e$ample shows how to conigure a +aven installation to use an Arti- actory repository e$clusively4 OsettingsD OmirrorsD OmirrorD OidDartiactoryO5idD Omirror2DVO5mirror2D OurlDhttp455buildserver.mycomany.org4YAYA5artiactory5repoO5urlD OnameDArtiactoryO5nameD O5mirrorD O5mirrorsD O5settingsD Changing Your *a!en Cache #ocation +aven stores downloaded JA: iles in a local directory on your machine, !nown as the local repository. #his directory generally is ound at U&2+E5.m35repository. 2ver time, this directory can get pretty big. Although this usually is not an issue, it can be in some environments where your home directory is actually stored on a remote server and downloaded whenever you log on to a computer. In this case, i you preer to !eep your local repository on your machine, you can redeine the local repository directory by using the Olocal:epositoryD tag in your U&2+E5.m35settings.$ml ile4 OsettingsD Olocal:epositoryD>45maven5repositoryO5local:epositoryD O5settingsD Defining Ar0itrary $n!ironment2Specific Jaria0les #he settings.$ml ile is also a good place to let users tailor their environment variables i they really need to. For e$ample, you might need to speciy the directory o some locally installed product, which may vary rom machine to machine. Eou do this by deining a deault proile in the settings.$ml ile. Any properties deined here will override property values in the C2+ ile. 2 course, you can get the +aven build process to do this automatically. &owever, users who have already installed /chema/py, and may not want to duplicate installations, can override the /chema/py-related parameters by setting up properties in their local settings.$ml ile. In the ollowing e$ample, a user sets the installation directory (the schemaspy.home property) to C4<tools<schemaspy, which will override any property values deined in the main C2+ ile4 OsettingsD ... OproilesD OproileD OidDdevelopmentO5idD OactivationD OactiveSyDeaultDtrueO5activeSyDeaultD O5activationD OpropertiesD Oschemaspy.homeDC4<tools<schemaspyO5schemaspy.homeD Oschemaspy.versionD6.@.@O5schemaspy.versionD O5propertiesD O5proileD O5proilesD O5settingsD ?ote that we still need to provide sensible deault values in the C2+ ile so that cus- tomi8ing your environment becomes optional, not mandatory. 7sers only need to modiy their local ile i they really want to (and, presumably, when they !now what they are doingZ). #he best way to set up these deault values is by using the <properties> element at the end o your C2+ ile, as shown here4 Opro"ectD ... OpropertiesD Oschemaspy.homeDUHuser.homeN5.schemaspyO5schemaspy.homeD Oschemaspy.versionD6.@.@O5schemaspy.versionD O5propertiesD Opro"ectD Don(t be tempted to put these deault values in a deault proile element in your C2+ ileG in this case, the proile in the C2+ ile would override the proile in your local settings. Dependency *anagement in *a!en I Dependency management is one o the more powerul eatures o +aven 3. Depend- encies are the libraries you need to compile, test, and run your application. In tools such as Ant, these libraries typically are stored in a special directory (oten called lib), and are maintained either by hand or as pro"ect artiacts that are stored in the source code repository along with the source code. +aven, by contrast, uses a declarative approach. In a +aven pro"ect, you list the libraries your application needs, including the e$act version number o each library. 7sing this inormation, +aven will do its best to ind, retrieve, and assemble the libraries it needs during the dierent stages in the build liecycle. In addition, using a powerul eature called #ransitive Dependencies (see Q+anaging #ransitive Dependencies,R later in this section), it will include not only the libraries that you declare but also all the e$tra libraries that your declared libraries need to wor! correctly. 9e will loo! at dierent aspects o how to handle dependencies in +aven 3. Declaring Dependencies 2ne o the most powerul eatures o +aven 3 is its ability to handle dependencies in a consistent and reliable manner. In the <dependencies> section o the C2+ ile, you declare the libraries that you need to compile, test, and run your application. Depend- encies are retrieved rom local or remote repositories, and cached locally on your development machine, in the U&2+E5.m35repository directory structure. I you use the same "ar in two pro"ects, it will only be downloaded (and stored) once, which saves time and dis! space. In +aven, dependencies are handled declaratively. /uppose that your pro"ect needs to use &ibernate, and that your unit tests are written in J7nit. In this case, the dependency section in your C2+ ile might loo! something li!e the ollowing4 ... OdependenciesD OdependencyD OgroupIdDorg.hibernateO5groupIdD OartiactIdDhibernateO5artiactIdD OversionD6.@O5versionD O5dependencyD OdependencyD OgroupIdD"unitO5groupIdD OartiactIdD"unitO5artiactIdD OversionD6.Y.@O5versionD OscopeDtestO5scopeD O5dependencyD O5dependenciesD ... Each dependency is uni-uely identiied, using a +aven-style artiact. Dependencies can reer both to other pro"ects within your organi8ation and to publicly available libraries on the public +aven repositories. testng-B.@-"d!@=."ar @B-Aug-3AAT AY4BB Y@;. testng-B.@-"d!@B."ar @B-Aug-3AAT AY4BB T;T. 9hen you declare your dependencies, +aven needs to !now e$actly which version you need. Eou do this by providing the <classifier> element, as shown here4 OdependencyD OgroupIdDorg.testngO5groupIdD OartiactIdDtestngO5artiactIdD OversionDB.@O5versionD OclassiierD"d!@BO5classiierD OscopeDtestO5scopeD O5dependencyD Dependencies declarations are not limited to precise version numbers. In act, +aven is -uite le$ible about version numbers, and you can use a orm o interval notation to deine ranges o permissible version numbers. Interval notation comes rom set theory, and is one o those things you probably learned at school or university and subse-uently orgot. &ere is a -uic! reresher. Interval notation is a le$ible and concise way o deining ranges o values using s-uare brac!ets and parentheses to indicate boundary values. Eou use parentheses when the boundary value is not included in the set. For e$ample, the ollowing notation indicates a set o values greater than @ (noninclusive) and less than = (noninclusive)4 (@,=) Eou use s-uare brac!ets when the boundary values are included in the set. For e$ample, the ollowing notation indicates a set o values greater than or e3ual to @ and less than or e3ual to =4 I@,=J Eou can combine dierent types o boundary values in the same e$pression. For e$- ample, this is how you would represent a set o values greater than or e-ual to @, and strictly less than =4 I@,=) Eou can leave a value out to leave one side o the set unbounded. &ere we include all values greater or e-ual to 34 I3,) Eou can even deine a set made up o multiple intervals, simply by listing the intervals in a comma-separated list. #he ollowing e$ample shows how you would deine all the values between @ and @A inclusive, e$cept or B4 I@,B),(B,@AJ ?ow that you have mastered the theory, let(s see how it applies to dependency man- agement. Sy using interval notation, you can give +aven more le$ibility in its de- pendency management, which means that you spend less time chasing the latest ACI updates. +aven will use the highest available version within the range you provide. For e$ample, the ollowing dependency will use the latest available version o &ibernate, but re-uires at least &ibernate 6.A4 OdependencyD OgroupIdDorg.hibernateO5groupIdD OartiactIdDhibernateO5artiactIdD OversionDI6.A,)O5versionD O5dependencyD 2r you may want to limit the versions o an ACI to a particular range. 7sing the ol- lowing dependency, +aven will loo! or the highest version o the commons- collections in the 3.$ series, but will e$clude any versions rom 6.A onward4 OdependencyD OgroupIdDcommons-collectionsO5groupIdD OartiactIdDcommons-collectionsO5artiactIdD OversionDI3.A,6.A)O5versionD O5dependencyD *anaging %ransiti!e Dependencies #ransitive Dependencies are arguably one o the most useul eatures o +aven 3. I you have ever used a tool li!e urpmi or apt-get on a ,inu$ bo$, you will be amiliar with the concept o #ransitive Dependencies. /imply put, i you tell +aven 3 that your pro"ect needs a particular library, it will try to wor! out what other libraries this library needs, and retrieve them as well. ,et(s loo! at how this wor!s with a practical e$ample. /uppose that our pro"ect uses &ibernate 6.@. 9e might declare this dependency as ollows4 OdependencyD OgroupIdDorg.hibernateO5groupIdD OartiactIdDhibernateO5artiactIdD OversionD6.@O5versionD O5dependencyD E$actly where +aven loo!s or dependencies will depend on how your repositories are set up. #he deault +aven 3 repository is located at http455repo@.maven.org5maven3 (i in doubt, this is actually deined in the /uper C2+ ile). In this case, +aven will loo! or the &ibernate JA: ile in the ollowing directory4 http455repo@.maven.org5maven35org5hibernate5hibernate56.@5 I you loo! in this directory, you will see a list o iles similar to the ollowing4 hibernate-6.@-sources."ar @A-Jan-3AAT A;4AB @.3+ hibernate-6.@-sources."ar.mdB @A-Jan-3AAT A;4AT @=Y hibernate-6.@-sources."ar.sha@ @A-Jan-3AAT A;4A; @BT hibernate-6.@."ar @B-Dec-3AAB @@463 @.Y+ hibernate-6.@."ar.mdB @B-Dec-3AAB @@463 63 hibernate-6.@."ar.sha@ @B-Dec-3AAB @@463 =A hibernate-6.@.pom 3T-Dec-3AAB AT433 6.Y. hibernate-6.@.pom.mdB A=-Jan-3AAT A;466 @6Y hibernate-6.@.pom.sha@ A=-Jan-3AAT A;466 @=T maven-metadata.$ml @B-Dec-3AAB @@463 @@] maven-metadata.$ml.mdB A]-Jul-3AAT AY4=@ @6A maven-metadata.$ml.sha@ A]-Jul-3AAT AY4=@ @6Y ?ote that there is much more than "ust the JA: ile4 there is also a C2+ ile and (or good measure) digest iles that let +aven veriy the consistency o the iles it downloads. #he C2+ ile here is the C2+ ile or the &ibernate pro"ect. I your pro"ect needs to use &ibernate, it also needs to include all the &ibernate dependencies in its distribution. #hese secondary dependencies are listed in this C2+ ile. +aven uses the dependencies in this C2+ to wor! out what other library it needs to retrieve. #his is the main wea!ness o +aven #ransitive Dependency management4 it relies on the accuracy and completeness o the C2+ iles stored on the public repository. &ow- ever, in some cases, the dependencies in the C2+ ile may not be up-to-date, and, in other cases, the C2+ ile may actually be "ust an empty C2+ ile with no dependencies at allZ In these cases, you will need to supply the dependencies e$plicitly in your own C2+ ile. Dependency management can be a complicated beast, and sometimes you will want to understand e$actly which libraries +aven is using and why. 2ne option is to use the 45 command-line option with any +aven command to produce (among many other things) very detailed dependency inormation. #his option generates a lot o te$t, so it is useul to redirect output into a te$t ile and to view the ile in a te$t editor, rather than to wrestle with the command line4 U mvn -5 test > out.txt #he resulting output ile will contain lines li!e the ollowing, detailing the resolved dependencies and the corresponding dependency graphs4 IDES7'J org.hibernate4hibernate4"ar46.@.64compile (setting version to4 6.@.6 rom range4 I6.A,)) IDES7'J org.hibernate4hibernate4"ar46.@.64compile (selected or compile) IDES7'J "ava$.transaction4"ta4"ar4@.A.@S4compile (selected or compile) IDES7'J dom="4dom="4"ar4@.T.@4compile (selected or compile) IDES7'J cglib4cglib4"ar43.@164compile (selected or compile) IDES7'J asm4asm4"ar4@.B.64compile (selected or compile) IDES7'J asm4asm-attrs4"ar4@.B.64compile (selected or compile) IDES7'J asm4asm4"ar4@.B.64compile (selected or compile) IDES7'J commons-collections4commons-collections4"ar43.@.@4compile (removed - nearer ound4 3.@) IDES7'J antlr4antlr4"ar43.;.Trc@4compile (selected or compile) #his is a representation o the dependency tree4 you can see e$actly which library ver- sions were re-uested, and which were retained or the inal dependency list. It also indicates which libraries were removed because a nearer dependency was ound (loo! at the Qcommons-collectionsR library in the above listing). #his can give useul clues i a library is not behaving as e$pected. #he other useul tool in understanding your pro"ect(s dependencies is the Dependency report. #his report is generated by deault when you generate the +aven site, and placed in the target5dependencies.html ile4 U mvn site #his report displays lists o direct and transitive dependencies or each dependency scope Dependency Scope In a real-world enterprise application, you may not need to include all the dependencies in the deployed application. /ome JA:s are needed only or unit testing, while others will be provided at runtime by the application server. 7sing a techni-ue called de- pendency scoping, +aven 3 lets you use certain JA:s only when you really need them and e$cludes them rom the classpath when you don(t. +aven provides several de- pendency scopes. #he deault scope is the compile scope. >ompile-scope dependencies are available in all phases. OdependencyD OgroupIdDorg.hibernateO5groupIdD OartiactIdDhibernateO5artiactIdD OversionD6.@O5versionD O5dependencyD A provided dependency is used to compile the application but will not be deployed. Eou would use this scope when you e$pect the JD. or application server to provide the JA:. #he servlet ACIs are a good e$ample4 OdependencyD OgroupIdD"ava$.servletO5groupIdD OartiactIdDservlet-apiO5artiactIdD OversionD3.=O5versionD OscopeDprovidedO5scopeD O5dependencyD #he runtime dependency scope is used or dependencies that are not needed or com- pilation, only or e$ecution, such as Java Database >onnectivity (JDS>) drivers4 OdependencyD OgroupIdDmys-lO5groupIdD OartiactIdDmys-l-connector-"avaO5artiactIdD OversionD6.@.@6O5versionD OscopeDruntimeO5scopeD O5dependencyD Eou use the test dependency scope or dependencies that are only needed to compile and run tests, and that don(t need to be distributed (J7nit or #est?', or e$ample)4 OdependencyD OgroupIdD"unitO5groupIdD OartiactIdD"unitO5artiactIdD OversionD6.Y.@O5versionD OscopeDtestO5scopeD O5dependencyD In some special cases, you may need to use system dependencies, such as the tools.jar ile provided with the Java /D.. For e$ample, you may need to use the /un Apt or .(6en tools within your build process. Eou can do this using the system dependency scope. In this case (and in this case only), you need to provide a system+ath value that indicates the absolute path to this ile. #his is illustrated in the ollowing code e$tract4 OdependencyD OgroupIdDcom.sunO5groupIdD OartiactIdDtoolsO5artiactIdD OversionD@.B.AO5versionD OscopeDsystemO5scopeD OsystemCathDUH"ava.homeN5lib5tools."arO5systemCathD O5dependencyD )andling Proprietary Dependencies For commercial and copyright reasons, not all o the commonly used libraries are available on the public +aven repositories. A common e$ample is the 2racle JDS> Driver, which is available ree-o-charge on the 2racle web site, V but it cannot be re- distributed via a public +aven repository. Another re-uently encountered e$ample is the Java #ransaction ACI (J#A), which is notably re-uired by &ibernate. #he J#A library is produced by /un, which re-uires you to agree to a license agreement beore you are able to download the JA:. I you need to use a proprietary library li!e these in your +aven pro"ect, you will need to add it manually to your local repository. ,et(s see how this is done, using the 2racle driver as an e$ample. First, download the appropriate JA: ile rom the 2racle web site (or e$ample, odbc@=."ar). At the time o this writing, this corresponded to the Q2racle Database @Ag :elease 3 (@A.3.A.3) JDS> Driver.R It is important to note the e$act version, as it is not visible rom the name o the ile. #his version number will be used to identiy the JA: ile in our repository. #he dependency declaration would loo! something li!e this4 OdependencyD OgroupIdDoracleO5groupIdD OartiactIdDoracle-"dbcO5artiactIdD OversionD@A.@.A.3.AO5versionD OscopeDruntimeO5scopeD O5dependencyD #o get this to wor!, we need to copy the JA: into the correct place in our +aven repository. #here are several ways to do this. Eou may irst want to test on your devel- opment machine beore installing the JA: onto the organi8ation repository. Eou can install the "ar into your local repository by using the mvn install7install-file command, as shown here4 mvn install4install-ile -DgroupIdKoracle < -DartiactIdKoracle-"dbc < -Dpac!agingK"ar < -DversionK@A.@.A.3.A < -DgenerateComKtrue < -DileKo"dbc@=."ar Installing the J#A "ar is similar4 download it rom the /un siteb and use the mvn in- stall command as ollows4 mvn install4install-ile -DgroupIdK"ava$.transaction < -DartiactIdK"ta < -Dpac!agingK"ar < -DversionK@.A.@S < -DgenerateComKtrue < -DileK"ta-@1A1@S-classes.8ip ?ow you can test the installation, typically by running some unit tests and seeing i +aven correctly inds the dependency. 9hen you are happy, you can either deploy the ile to using the mvn deploy7deploy- file command, or simply copy the appropriate directory onto your company +aven repository. 9hen this is done, this dependency can be seamlessly downloaded by all the team members in e$actly the same way as any other new dependency. Refactoring Your Dependencies Using Properties In large pro"ects, even with the beneits o transitive dependency management, you will oten end up with a lot o dependencies. /ometimes, it is useul to declare !ey version numbers in a central place, ma!ing them easier to ind and update i necessary. 2ne good way to do this is by using properties. 9e saw in QDeining Suild CroilesR the ways in which you can deine proile or environment- speciic properties in a proile or in the set- tings.$ml ile. &owever, you also can declare properties directly at the root level in your pom.$ml ile. ,i!e constants in a Java class, or Ant properties in an Ant build script, this is a convenient way to deine reusable values in an easy-to- maintain manner. #he actual <properties> bloc! can appear anywhere in the build ile, but you may want to put it in an easy-to-ind place such as near the start or right at the end. ,et(s loo! at an e$ample. /uppose that we are developing a web application using J/C and J/#,. In the ollowing listing, we use two properties, somewhat unimaginatively named servlet-api.version and jstl.version, to identiy what version o the Java /ervlet and J/#, ACIs we are using4 Opro"ectD ... OpropertiesD ... Oservlet-api.versionD3.=O5servlet-api.versionD O"stl.versionD@.@.3O5"stl.versionD O5propertiesD ... O5pro"ectD #hese properties can then be used to declare our dependencies in a more le$ible man- ner. ?ow we can use these properties to declare our /ervlet ACI and J/#, dependencies. ?ote that this ma!es it easier to ensure that the J/#, ACI and J/#, standard taglibs versions stay in sync4 Opro"ectD ... OpropertiesD ... Oservlet-api.versionD3.=O5servlet-api.versionD O"stl.versionD@.@.3O5"stl.versionD O5propertiesD ... OdependenciesD ... OdependencyD OgroupIdD"ava$.servletO5groupIdD OartiactIdDservlet-apiO5artiactIdD OversionD$"servlet-api.version#O5versionD OscopeDprovidedO5scopeD O5dependencyD OdependencyD OgroupIdD"ava$.servletO5groupIdD OartiactIdD"stlO5artiactIdD OversionD$"jstl.version#O5versionD O5dependencyD OdependencyD OgroupIdDtaglibsO5groupIdD OartiactIdDstandardO5artiactIdD OversionD$"jstl.version#O5versionD O5dependencyD ... O5dependenciesD O5pro"ectD #oo3ing for Dependencies "ith *!nRepository 9hen you are wor!ing with +aven, you oten need to loo! up a particular dependency so that you can add it to your C2+ ile. It can be -uite tric!y to remember and5or hunt down the precise group and artiact names and the latest version numbers or any but the most well-!nown artiacts. For e$ample, do you remember the e$act group and latest version o the &ibernate or /pring +0> librariesP 2ne useul resource that can help out here is the +vn:epository site 7sing this site, you can search the central +aven repository or artiacts by name. 9hen you ind the version you are loo!ing or, simply copy the displayed dependency bloc! into your C2+ ile. 9hile you(re there, you also can list the dependencies o a particular library, view the latest updates to the repository, or browse the overall structure o the repository. Project Inheritance and Aggregation +aven actively encourages you to write your pro"ects as a set o small, le$ible, modules rather than as a monolithic bloc! o code. Dependencies are one way that you can create well-deined relationships between a set o modules to orm an overall pro"ect. Cro"ect inheritance is another. Cro"ect inheritance lets you deine pro"ect-wide properties and values that will be in- herited by all o the child pro"ects. #his is most easily understood by an e$ample. /uppose you are writing a simple web application, which will be deployed both as a traditional web application and as a portlet. 2ne way that you might do this is to deine three modules4 a core module, containing the application business logic, and two user interace modules, one or each target platorm. ,et(s see how you would implement this pro"ect structure. Carent C2+ iles are very much li!e any other C2+ ile. #he ollowing listing shows a very simple one4 Opro"ectD Omodel0ersionD=.A.AO5model0ersionD OgroupIdDcom.mycompanyO5groupIdD OartiactIdDmyappO5artiactIdD Opac!agingDpomO5pac!agingD OnameD.iller applicationO5nameD OversionD@.AO5versionD O5pro"ectD #he main distinguishing actor is the <packaging> element, which is declared as a C2+, rather than the 9A: or JA: values that we have seen in previous e$amples. Indeed, all parent C2+ iles must use the pom pac!aging type. #hen, within each child pro"ect, you need to declare a <parent> element that reers, suprisingly enough, to the parent C2+ ile4 Opro"ectD OparentD OgroupIdDcom.mycompanyO5groupIdD OartiactIdDmyappO5artiactIdD OversionD@.AO5versionD O5parentD Omodel0ersionD=.A.AO5model0ersionD OartiactIdDdebtcalculator-coreO5artiactIdD ... O5pro"ectD ?ote that you don(t need to deine the version or groupId o the child pro"ect%these values are inherited rom the parent. #he parent C2+ ile is an e$cellent place to deine pro"ect-wide properties or build coniguration details. A typical use is to deine the Java compile options in one central place. 9e can set the Java compiler to Java @.B. #his will be inherited by all the children pro"ects, without any special coniguration in their C2+ iles4 Opro"ectD Omodel0ersionD=.A.AO5model0ersionD OgroupIdDcom.mycompanyO5groupIdD OartiactIdDmyappO5artiactIdD Opac!agingDpomO5pac!agingD OnameD.iller applicationO5nameD OversionD@.AO5versionD OpropertiesD O"ava-api.versionD@.BO5"ava-api.versionD O5propertiesD ObuildD OpluginsD OpluginD OartiactIdDmaven-compiler-pluginO5artiactIdD OconigurationD OsourceDUH"ava-api.versionNO5sourceD OtargetDUH"ava-api.versionNO5targetD O5conigurationD O5pluginD O5pluginsD O5buildD O5pro"ectD In a similar way, you can deine pro"ect-wide dependencies at this level4 Opro"ectD Omodel0ersionD=.A.AO5model0ersionD OgroupIdDcom.mycompanyO5groupIdD OartiactIdDmyappO5artiactIdD Opac!agingDpomO5pac!agingD OnameD.iller applicationO5nameD OversionD@.AO5versionD OpropertiesD O"ava-api.versionD@.BO5"ava-api.versionD O"unit.versionD=.=O5"unit.versionD O5propertiesD ... OdependenciesD OdependencyD OgroupIdD"unitO5groupIdD OartiactIdD"unitO5artiactIdD OversionDUH"unit.versionNO5versionD OscopeDtestO5scopeD O5dependencyD O5dependenciesD O5pro"ectD All the children pro"ects will now be able to use these dependencies without having to list them among their speciic dependencies. #his is also an e$cellent way to ensure that all o your children pro"ects use the same versions o particular ACIs. #he parent C2+ ile is also an e$cellent place to set up reporting conigurations. #his way, you can deine and conigure the reports that you want generated or all the chil- dren pro"ects in one central place. Opro"ectD Omodel0ersionD=.A.AO5model0ersionD OgroupIdDcom.mycompanyO5groupIdD OartiactIdDmyappO5artiactIdD Opac!agingDpomO5pac!agingD OnameD.iller applicationO5nameD OversionD@.AO5versionD ... OreportingD OpluginsD OpluginD OartiactIdDmaven-sureire-report-pluginO5artiactIdD O5pluginD OpluginD OartiactIdDmaven-chec!style-pluginO5artiactIdD O5pluginD ... O5pluginsD O5reportingD O5pro"ectD Although, at the time o this writing, multimodule reporting is still a bit dodgy, each child pro"ect will inherit the reporting coniguration deined in the parent C2+ ile, ma!ing these iles simpler and easier to maintain. Eou can also deine the subpro"ects as modules. #his is !nown as aggregation, and allows you to build all the child pro"ects in one go rom the parent directory. Opro"ectD ... OmodulesD OmoduleDmyapp-coreO5moduleD OmoduleDmyapp-warO5moduleD OmoduleDmyapp-portletO5moduleD O5modulesD ... O5pro"ectD 9hen you run mvn compile rom the parent root directory, all o the child pro"ects also would be compiled4 U mvn compile II?F2J /canning or pro"ects... II?F2J :eactor build order4 II?F2J .iller App II?F2J .iller App - >ore II?F2J .iller App - Cortlet II?F2J .iller App - 9ebapp II?F2J ---------------------------------------------------------------------------- II?F2J Suilding .iller App II?F2J tas!-segment4 IcompileJ II?F2J ---------------------------------------------------------------------------- ... II?F2J ---------------------------------------------------------------------------- II?F2J Suilding .iller App - >ore II?F2J tas!-segment4 IcompileJ II?F2J ---------------------------------------------------------------------------- ... II?F2J ---------------------------------------------------------------------------- II?F2J Suilding .iller App - Cortlet II?F2J tas!-segment4 IcompileJ II?F2J ---------------------------------------------------------------------------- ... II?F2J ---------------------------------------------------------------------------- II?F2J Suilding .iller App - 9ebapp II?F2J tas!-segment4 IcompileJ II?F2J ---------------------------------------------------------------------------- ... II?F2J ------------------------------------------------------------------------ II?F2J :eactor /ummary4 II?F2J ------------------------------------------------------------------------ II?F2J .iller App ............................................ /7>>E// IA.6@;sJ II?F2J .iller App - >ore ..................................... /7>>E// I@.A@3sJ II?F2J .iller App - Cortlet .................................. /7>>E// IA.TA3sJ II?F2J .iller App - 9ebapp ................................... /7>>E// IA.;B6sJ II?F2J ------------------------------------------------------------------------ II?F2J ------------------------------------------------------------------------ II?F2J S7I,D /7>>E//F7, II?F2J ------------------------------------------------------------------------ II?F2J #otal time4 = seconds II?F2J Finished at4 /un ?ov @Y A34B=463 '+# 3AA; II?F2J Final +emory4 ;+5YA+ II?F2J ------------------------------------------------------------------------ Creating a Project %emplate "ith Archetypes Even with a standardi8ed directory structure, it is tiresome to have to create a ull set o empty directories by hand whenever you start a new +aven pro"ect. #o ma!e lie easier, +aven 3 provides the archetype plug-in, which builds an empty +aven 3% compatible pro"ect template, containing a standard directory structure as well as some sample iles illustrating +aven conventions and best practices. #his is an e$cellent way to get a basic pro"ect environment up and running -uic!ly. #he deault archetype model will produce a JA: library pro"ect. /everal other artiact types are available or other speciic pro"ect types, including web applications, +aven plug-ins, and others. ,et(s ta!e a -uic! tour to see what you can do with +aven Archetypes. /uppose that we want to create an online store using +aven. Following +aven(s recommendations, we will divide the pro"ect into several distinct modules. 2ur bac!end module will be called /hop>oreApi4 U mvn archetype7create -Dgroup0d$com.acme.shop -Dartifact0d$(hop8oreApi -Dpackagename$com.acme.shop II?F2J /canning or pro"ects... II?F2J /earching repository or plugin with prei$4 )archetype). II?F2J ---------------------------------------------------------------------------- II?F2J Suilding +aven Deault Cro"ect II?F2J tas!-segment4 Iarchetype4createJ (aggregator-style) II?F2J ---------------------------------------------------------------------------- ... II?F2J Archetype created in dir4 5home5"ohn5dev5pro"ects5shop5/hop>oreApi II?F2J ------------------------------------------------------------------------ II?F2J S7I,D /7>>E//F7, II?F2J ------------------------------------------------------------------------ II?F2J #otal time4 3 seconds II?F2J Finished at4 /un 2ct @B 3@4BA46Y ?XD# 3AAT II?F2J Final +emory4 =+5Y+ II?F2J ------------------------------------------------------------------------ #his will create a complete, correctly structured, wor!ing, albeit minimalist, +aven pro"ect, including a simple C2+ ile, a sample class, and a unit test. #he C2+ ile loo!s li!e this4 Opro"ect $mlnsKLhttp455maven.apache.org5C2+5=.A.AL $mlns4$siK Lhttp455www.w6.org53AA@5*+,/chema-instanceL $si4schema,ocationKLhttp455maven.apache.org5C2+5=.A.A http455maven.apache.org5maven-v=1A1A.$sdLD Omodel0ersionD=.A.AO5model0ersionD OgroupIdDcom.acme.shopO5groupIdD OartiactIdD/hop>oreApiO5artiactIdD Opac!agingD"arO5pac!agingD OversionD@.A-/?AC/&2#O5versionD OnameD/hop>oreApiO5nameD OurlDhttp455maven.apache.orgO5urlD OdependenciesD OdependencyD OgroupIdD"unitO5groupIdD OartiactIdD"unitO5artiactIdD OversionD6.Y.@O5versionD OscopeDtestO5scopeD O5dependencyD O5dependenciesD O5pro"ectD #he pro"ect will be created in a subdirectory with the same name o the artiact (in this case, Q/hop>oreApiR). #he group0d and the artiactId are used to identiy the artiact produced by the pro"ect (see QCro"ect >onte$t and ArtiactsR). #he pack- agename is the root pac!age or your pro"ect. +ore oten than not, the packagename option will be the same at the group0d4 in this case, you can drop the packagename option. #his pro"ect is now ready to try out. /witch to this directory and build the pro"ect using mvn package4 U ls /hop>oreApi U cd (hop8oreApi U mvn package II?F2J /canning or pro"ects... II?F2J ---------------------------------------------------------------------------- II?F2J Suilding +aven cuic! /tart Archetype II?F2J tas!-segment4 Ipac!ageJ II?F2J ---------------------------------------------------------------------------- ... ------------------------------------------------------- # E / # / ------------------------------------------------------- :unning com.acme.shop.App#est #ests run4 @, Failures4 A, Errors4 A, /!ipped4 A, #ime elapsed4 A.A6] sec :esults 4 #ests run4 @, Failures4 A, Errors4 A, /!ipped4 A II?F2J I"ar4"arJ II?F2J Suilding "ar4 5home5"ohn5dev5pro"ects5shop5/hop>oreApi5target 5/hop>oreApi-@.A-/?AC/&2#."ar II?F2J ------------------------------------------------------------------------ II?F2J S7I,D /7>>E//F7, II?F2J ------------------------------------------------------------------------ II?F2J #otal time4 = seconds II?F2J Finished at4 /un 2ct @B 3@4B3433 ?XD# 3AAT II?F2J Final +emory4 =+5@A+ II?F2J ------------------------------------------------------------------------ /o, now you have a wor!ing +aven pro"ect template, generated in "ust a ew minutesZ #he deault Archetype template (the maven-archetype--uic!start archetype) is de- signed to produce a JA: ile. #here are also several other archetypes that can be used to create templates or dierent types o pro"ects. Eou can use a dierent archetype by using the archetypeArtifact0d command-line option, as shown here4 U mvn archetype7create -Dgroup0d$com.acme.shop -Dartifact0d$(hop.eb 9 -DarchetypeArtifact0d$maven-archetype-ebapp #his e$ample uses the maven-archetype-webapp archetype, which creates (surprisingly enoughZ) an empty 9A: pro"ect. Following +aven(s recommendations about /epa- ration o >oncerns, the 9A: pro"ect is e$pected to contain only dynamic web pages (J/Cs), with the actual Java code being written in another pro"ect. Another useul archetype is the maven-archetype-site archetype, which creates a tem- plate or a +aven web site or an e$isting pro"ect, including a ull, multilingual (well, bilingual) site structure with sample *Doc, AC#, and FAcs content. #his archetype is the only one that you run on an e$isting pro"ect. Although it provides none o the source code-based reporting eatures, such as unit test reports, chec!style reports, and so on (which need to be conigured in the main C2+ ile), it does provide a good starting point or manually added site content4 U mvn archetype7create -Dgroup0d$com.acme.shop -Dartifact0d$(hop8oreApi 9 -DarchetypeArtifact0d$maven-archetype-site U mvn site II?F2J /canning or pro"ects... II?F2J ---------------------------------------------------------------------------- II?F2J Suilding +aven cuic! /tart Archetype II?F2J tas!-segment4 IsiteJ II?F2J ---------------------------------------------------------------------------- ... II?F2J 'enerate L>ontinuous IntegrationL report. II?F2J 'enerate LDependenciesL report. II?F2J 'enerate LIssue #rac!ingL report. II?F2J 'enerate LCro"ect ,icenseL report. II?F2J 'enerate L+ailing ,istsL report. II?F2J 'enerate LCro"ect /ummaryL report. II?F2J 'enerate L/ource :epositoryL report. II?F2J 'enerate LCro"ect #eamL report. II?F2J ------------------------------------------------------------------------ II?F2J S7I,D /7>>E//F7, II?F2J ------------------------------------------------------------------------ II?F2J #otal time4 @@ seconds II?F2J Finished at4 /un 2ct @B 334=;4A= ?XD# 3AAT II?F2J Final +emory4 @@+53@+ II?F2J ------------------------------------------------------------------------ #here is also an increasing number o third-party archetypes available or other types o web applications and web technology stac!s, such as /truts, /pring, J/F, &ibernate, Ageci, and many more. A list o some o these can be ound on the >odehaus web site. V +att :aible(s AppFuse pro"ectb provides a large number o archetypes that you can use to create wor!ing application templates based on a wide range o open source architectures and libraries, such as J/F, /pring, /pring +0>, /truts, &ibernate, and #apestry. For e$ample, the appfuse-basic-spring archetype, shown here, will create a very complete web application prototype based on &ibernate, /pring, and J/F4 U mvn archetype7create -Dgroup0d$com.jpt -Dartifact0d$shopfront 9 -DarchetypeArtifact0d$appfuse-basic-jsf -Darchetype6roup0d$org.appfuse.archetypes ... II?F2J Archetype created in dir4 5home5"ohn5pro"ects5shopront II?F2J ------------------------------------------------------------------------ II?F2J S7I,D /7>>E//F7, II?F2J ------------------------------------------------------------------------ II?F2J #otal time4 @ minute Y seconds II?F2J Finished at4 9ed 2ct @A 3A4=T43; '+#M@34AA 3AA; II?F2J Final +emory4 T+5TB+ II?F2J ------------------------------------------------------------------------ #his will create a e$ecutable web application, as well as a good e$ample o a wor!ing, detailed C2+ ile or a realSy deault. It will try to connect to a local +y/c, database (using the QrootR user with no password). Eou can try it out by running the Jetty plug- in, as shown here4 U cd shopfront U mvn jetty7run ... mvn "etty4run-war II?F2J /canning or pro"ects... II?F2J /earching repository or plugin with prei$4 )"etty). II?F2J ---------------------------------------------------------------------------- II?F2J Suilding AppFuse J/F Application II?F2J tas!-segment4 I"etty4run-warJ II?F2J ---------------------------------------------------------------------------- ... 3AA;-@A-@A 3@46A4=Y.=@A44I?F24 /tarted /elect>hannel>onnector^A.A.A.A4YAYA II?F2J /tarted Jetty /erver Eou can now view this application by going to http7!!localhost7:':'. Eou also can create your own archetypes, which can be useul i you want to encourage organi8ation-wide pro"ect conventions, or to support particular types o pro"ects that you use oten. Compiling Code A !ey part o any development liecycle is compiling your source code. >ompiling your pro"ect with +aven is easy%"ust run mvn compile4 U mvn compile Seore compiling, +aven will chec! that all the pro"ect(s dependencies have been downloaded, and will etch any that it doesn(t already have. It also will generate any source code or pro"ect resources that need to be generated and instantiate any variables in the resources and coniguration iles (see QDeining Suild CroilesR). 2ne o the nice things about +aven is that these tas!s are done automatically, as part o the normal +aven liecycle, without needing any particular coniguration. #o be sure that there are no stale ob"ects remaining in the target directories, you can also call the clean plug-in, which, as the name indicates, empties the output directories in preparation or a clean build4 U mvn clean compile Sy deault, Java compilation in +aven 3 supports bac!ward compatibility to JD. @.6, which means that your generated artiacts will wor! ine with pretty much any modern version o Java. #his is a useul thing to do i you are generating JA: iles or community use, or or multiple JD.s. &owever, i you compile your brand-new Java class ull o generics, or e$ample, you(ll get a message li!e this4 IE::2:J S7I,D FAI,7:E II?F2J ---------------------------------------------------------------------------- II?F2J >ompilation ailure 57sers5"smart5chapters5caching5app5hibernate>aching5src5main5"ava5com5wa!aleo5 chapters5caching5businessob"ects5>ountry."ava4I=@,@YJ generics are not supported in -source @.6 (try -source @.B to enable generics) public /et getAirports() H #o get your code to compile correctly using the new Java B eatures (generics and so orth), you need to conigure the special maven-compiler-plugin in your pom.xml ile. #his allows you to deine the source and target parameters or the Java compiler. For Java B, you could do the ollowing4 Opro"ect...D ... ObuildD OpluginsD OpluginD OgroupIdDorg.apache.maven.plug-insO5groupIdD OartiactIdDmaven-compiler-pluginO5artiactIdD OconigurationD OsourceD@.BO5sourceD OtargetD@.BO5targetD O5conigurationD O5pluginD O5pluginsD O5buildD O5pro"ectD %esting Your Code 7nit tests are an important part o any modern development methodology, and they play a !ey role in the +aven development liecycle. Sy deault, +aven will not let you pac!age or deploy your application unless all the unit tests succeed. +aven will recogni8e both J7nit 6.$, J7nit = and #est?' unit tests, as long as they are placed in the src5test directory structure. :unning unit tests rom +aven is done using the mvn test command, as shown here4 U mvn test II?F2J /canning or pro"ects... . . . II?F2J Isureire4testJ II?F2J /ureire report directory4 5home5"ohn5pro"ects5"ava-power-tools5... 5target5sureire-reports ------------------------------------------------------- # E / # / ------------------------------------------------------- :unning com."avapowertools.ta$calculator.services.#a$>alculator#est #ests run4 @A, Failures4 A, Errors4 A, /!ipped4 A, #ime elapsed4 A.A6T sec :unning com."avapowertools.ta$calculator.domain.#a$:ate#est #ests run4 6, Failures4 A, Errors4 A, /!ipped4 A, #ime elapsed4 A.AA] sec :esults 4 #ests run4 @6, Failures4 A, Errors4 A, /!ipped4 A +aven will compile i necessary beore running the application(s unit tests. Sy deault, +aven e$pects unit tests to be placed in the src5test directory, and will automatically pic! up any test classes with names that start or end with Q#estR or that end with Q#est>ase.R Detailed test results are produced in te$t and *+, orm in the target5sureire-reports directory. Alternatively, you can generate the test results in &#+, orm using the sureire reporting eature4 U mvn surefire-report7report #he &#+, report will be generated in a ile called target5site5sureire- report.html Another important aspect o unit testing is #est >overage, which ma!es sure that a high proportion o your code is actually being e$ercised by your tests. Although high test coverage is not suicient in itsel to prove that your code is being well tested, the opposite is probably true%poor test coverage is usually a reliable sign o poorly tested code. >obertura is an open source coverage tool that integrates well with +aven. Eou can measure test coverage with >obertura without any additional conig- uration by simply invo!ing the cobertura plug-in, as shown here4 U mvn cobertura7cobertura II?F2J /canning or pro"ects... II?F2J /earching repository or plugin with prei$4 )cobertura). II?F2J ---------------------------------------------------------------------------- II?F2J Suilding #a$ >alculator II?F2J tas!-segment4 Icobertura4coberturaJ II?F2J ---------------------------------------------------------------------------- II?F2J Creparing cobertura4cobertura ... :eport time4 @;Yms II?F2J >obertura :eport generation was successul. II?F2J ------------------------------------------------------------------------ II?F2J S7I,D /7>>E//F7, II?F2J ------------------------------------------------------------------------ II?F2J #otal time4 @; seconds II?F2J Finished at4 9ed ?ov 3Y A]43B4BB '+# 3AA; II?F2J Final +emory4 T+5Y@+ II?F2J ------------------------------------------------------------------------ #his will generate a detailed &#+, coverage report, which can be ound in target5 site5cobertura5inde$.html. >obertura gives a high-level summary o code coverage across the whole pro"ect, and lets you drill down into a pac!age to in- dividual classes where you can see which lines o code have not been tested . Soth o these reports also can be easily integrated into the +aven-generated pro"ect web site. Actually, at the time o writing, there is one slight hitch, and this won(t wor! as shown. In act, you need to use version 3.A or 3.3 o the >obertura plug-in. Eou do this by overriding the standard >obertura plug-in coniguration in the <build> section o your pom.xml ile, as shown here4 OZ-- S7I,D >2?FI'7:A#I2? --D ObuildD OpluginsD ... OpluginD OgroupIdDorg.codehaus.mo"oO5groupIdD OartiactIdDcobertura-maven-pluginO5artiactIdD OversionD3.3O5versionD O5pluginD O5pluginsD O5buildD During debugging, you oten want to "ust run a single test. In +aven, you can do this using the -Dtest command-line option, speciying the name o your unit test class4 U mvn -Dtest$+roductDA,)ests test Finally, i you need to, you can also s!ip tests entirely using the -Dmaven.test.skip option4 U mvn -Dmaven.test.skip package Pac3aging and Deploying Your Application 2ne o the undamental principles o +aven is that each +aven pro"ect generates one, and only one, main artiact. #he type o artiact generated by a +aven pro"ect is deined in the <packaging> section o the C2+ ile. #he main types o pac!aging are sel- e$planatory4 jar, ar, and ear. A typical e$ample is shown here4 Opro"ect...D Omodel0ersionD=.A.AO5model0ersionD OgroupIdDcom.mycompany.accountingO5groupIdD OartiactIdDaccounting-webappO5artiactIdD <packaging>ar<!packaging> OversionD@.@O5versionD ... #he pac!aging type will determine e$actly how your pro"ect is bundled together4 com- piled classes are placed at the root o a JA: ile and in the 9ES-I?F5classes subdirectory in a 9A: ile, or e$ample. #he ne$t step is to install and5or deploy your application. #he install command will generate and deploy your pro"ect artiact to the local repository on your local machine, where it will become available to other pro"ects on your machine4 U mvn install #he deploy command will generate and deploy your pro"ect artiact to a remote server via one o the supported protocols (//&3, /F#C, F#C, and e$ternal //&), or simply to a local ilesystem4 U mvn deploy Eour application will be deployed to the remote repository deined in the <distribution*anagement> section in your C2+ ile. I you are deploying to a V?I* machine, you will probably need to use one o the networ! copying protocols4 //&3, /F#C, F#C, or e$ternal //&, as in this e$ample4 Odistribution+anagementD OrepositoryD OidDcompany.repositoryO5idD OnameDEnterprise +aven :epositoryO5nameD OurlDscp455repo.acme.com5mavenO5urlD O5repositoryD O5distribution+anagementD I you are deploying to a local ilesystem, or to a 9indows shared drive, you can use the file 7:, protocol, as shown here4 Odistribution+anagementD OrepositoryD OidDcompany.repositoryO5idD OnameDEnterprise +aven :epositoryO5nameD OurlDile4555D45maven5repoO5urlD O5repositoryD O5distribution+anagementD I you need to supply a username and password when you copy to the remote repository, you also will need to provide this inormation in your settings.$ml ile4 OsettingsD ... OserversD OserverD OidDcompany.repositoryO5idD OusernameDscottO5usernameD OpasswordDtigerO5passwordD O5serverD O5serversD O5settingsD +aven supports a variety o distribution protocols, including F#C, DA0, and />C. &owever, not all protocols are supported out-o-the-bo$. Eou oten will need to add an <extension> element to the <build> section in your pom.$ml ile. #his is illustrated here, where we add support or F#C and deploy our application to an enterprise F#C server4 O5buildD ... Oe$tensionsD Oe$tensionD OgroupIdDorg.apache.maven.wagonO5groupIdD OartiactIdDwagon-tpO5artiactIdD OversionD@.A-beta-3O5versionD O5e$tensionD O5e$tensionsD O5buildD ... Odistribution+anagementD OrepositoryD OidDtp.repositoryO5idD OnameD:emote F#C :epositoryO5nameD OurlDtp455www.mycompany.com5public1html5reposO5urlD O5repositoryD OsiteD OidDweb siteO5idD OurlDtp455www.mycompany.com5public1htmlO5urlD O5siteD O5distribution+anagementD Deploying an Application Using Cargo #here are also many third-party tools and libraries that can help you deploy your ap- plication. 2ne o the most versatile is >argo.V >argo is a powerul tool that allows you to deploy your application to a number o dierent application servers, including #om- cat, JSoss, 'eronimo, and 9eblogic. It integrates well with both +aven and Ant. 9e don(t have room to e$plore all o its possibilities here. In this chapter, we will "ust loo! at how to conigure >argo to deploy a 9A: application to a running remote #omcat server. >argo provides a +aven plug-in that allows you to integrate >argo unctionalities smoothly into the +aven liecycle. #he coniguration is a bit wordy, mainly as a result o the large degree o le$ibity oered by the tool. #he ull plug-in coniguration is shown here4 OpluginD OgroupIdDorg.codehaus.cargoO5groupIdD OartiactIdDcargo-maven3-pluginO5artiactIdD Oe$ecutionsD Oe$ecutionD OidDveriy-deployO5idD OphaseDpre-integration-testO5phaseD OgoalsD OgoalDdeployer-redeployO5goalD O5goalsD O5e$ecutionD O5e$ecutionsD OconigurationD OcontainerD OcontainerIdDtomcatB$O5containerIdD OtypeDremoteO5typeD O5containerD OconigurationD OtypeDruntimeO5typeD OpropertiesD Ocargo.tomcat.manager.urlDUHtomcat.managerNO5cargo.tomcat.manager.urlD Ocargo.remote.usernameDUHtomcat.manager.usernameNO5cargo.remote.usernameD Ocargo.remote.passwordDUHtomcat.manager.passwordNO5cargo.remote.passwordD O5propertiesD O5conigurationD OdeployerD OtypeDremoteO5typeD OdeployablesD OdeployableD OgroupIdDn8.govt.ird.egstO5groupIdD OartiactIdDegst-webO5artiactIdD OtypeDwarO5typeD Oping7:,Dhttp455UHtomcat.hostN4UHtomcat.portN5UHpro"ect.build.inal?ameN 5welcome.do O5ping7:,D O5deployableD O5deployablesD O5deployerD O5conigurationD O5pluginD ,et(s loo! at each section in more detail. #he irst section simply declares the plug-in in the usual way4 OpluginD OgroupIdDorg.codehaus.cargoO5groupIdD OartiactIdDcargo-maven3-pluginO5artiactIdD ... In this e$ample, we automatically deploy the pac!aged 9A: ile "ust beore the inte- gration tests phase. #his section is optional and is designed to ma!e it easier to run automatic integration or unctional tests against the latest version o the application. #he deployer-redeploy goal will, as you would e$pect, redeploy the application on the targetted #omcat server4 ... Oe$ecutionsD Oe$ecutionD OidDveriy-deployO5idD OphaseDpre-integration-testO5phaseD OgoalsD OgoalDdeployer-redeployO5goalD O5goalsD O5e$ecutionD O5e$ecutionsD ... #he ne$t section is the <configuration> element. 9e deine the type o application server (in this case, a remote #omcat B server), and provide some server-speciic con- iguration details indicating how to deploy to this server. For #omcat, this consists o the 7:, or the #omcat +anager application, as well as a valid #omcat username and password that will give us access to this server4 ... OconigurationD OcontainerD OcontainerIdDtomcatB$O5containerIdD OtypeDremoteO5typeD O5containerD OconigurationD OtypeDruntimeO5typeD OpropertiesD Ocargo.tomcat.manager.urlDUHtomcat.managerNO5cargo.tomcat.manager.urlD Ocargo.remote.usernameDUHtomcat.manager.usernameNO5cargo.remote.usernameD Ocargo.remote.passwordDUHtomcat.manager.passwordNO5cargo.remote.passwordD O5propertiesD O5conigurationD ... For this to wor! correctly, you need to have deined a #omcat user with the QmanagerR role. #his is not the case by deault, so you may have to modiy your #omcat conigu- ration manually. In a deault installation, the simplest way is to add a user to the #omcat con5tomcat-users.$ml ile, as shown here4 OP$ml versionK)@.A) encodingK)ut-Y)PD Otomcat-usersD Orole rolenameKLtomcatL5D Orole rolenameKLmanagerL5D Ouser usernameKLtomcatL passwordKLtomcatL rolesKLtomcatL5D Ouser usernameKLadminL passwordKLsecretL rolesKLtomcat,managerL5D O5tomcat-usersD #his e$ample uses a number o properties, among them are thVtomcat.manager, tomcat.manager.username, and tomcat.manager.passord. #hese properties are typi- cally by used both by >argo and by unctional testing tools such as /elenium (see >hapter 3A). #hey allow you to tailor the build process to dierent environments with- out modiying the build script itsel. &ere, the tomcat.manager property indicates the 7:, pointing to the #omcat manager application. >argo uses this application to deploy the 9A: ile, so it needs to be installed and running on your #omcat instance. #his 7:, is built using other more environment-speciic properties. It can be placed at the end o the pom.$ml ile, in the <properties> element, as shown here4 Opro"ectD ... OpropertiesD Otomcat.managerDhttp455UHtomcat.hostN4UHtomcat.portN5managerO5tomcat.managerD O5propertiesD O5pro"ectD #he other properties will vary depending on the target environment. Crobably the best way to set this up is to use +aven proiles (see QDeining Suild CroilesR). Croiles can be placed either in the pom.$ml ile (where they will be available to all users), or in the settings.$ml ile (or proiles that contain sensitive inormation such as server passwords). Eou might place the development proile directly in the pom.$ml ile or convenience4 ... OproilesD OZ-- ,ocal development environment --D OproileD OidDdevO5idD OactivationD OactiveSyDeaultDtrueO5activeSyDeaultD O5activationD OpropertiesD Otomcat.portDYAYAO5tomcat.portD Otomcat.serverDdevelopmentO5tomcat.serverD Otomcat.hostDlocalhostO5tomcat.hostD Otomcat.manager.usernameDadminO5tomcat.manager.usernameD Otomcat.manager.passwordDO5tomcat.manager.passwordD O5propertiesD O5proileD ... OproilesD ... O5pro"ectD A developer can then redeploy by using the cargo7redeploy goal4 U mvn package cargo7redeploy >argo also comes with other similar goals, such as cargo7deploy and cargo7undeploy, which can be useul on occasions. Deploying to the integration server, by contrast, re-uires a server password that you may not want to place under version control. In addition, you may not want developers deploying directly to the integration server rom their own machines%they may have to do this on the build server or through a >ontinuous Integration tool. Eou can arrange this by deining an integration server proile in the settings.$ml ile on the machine (or machines) that will be deploying to this server (or e$ample, on the build server)4 OsettingsD ... OproilesD ... OZ-- Integration environment on a remote build server --D OproileD OidDintegrationO5idD OactivationD OpropertyD OnameDenvO5nameD OvalueDintegrationO5valueD O5propertyD O5activationD OpropertiesD Otomcat.portD@AAA@O5tomcat.portD Otomcat.serverDintegrationO5tomcat.serverD Otomcat.hostDbuildserver.mycompany.comO5tomcat.hostD Otomcat.manager.usernameDadminO5tomcat.manager.usernameD Otomcat.manager.passwordDsecretO5tomcat.manager.passwordD O5propertiesD O5proileD ... OproilesD O5settingsD ?ow, rom these machines, you can redeploy your application onto the integration server, as shown here4 U mvn package cargo7redeploy -Denv$integration