Title: Introduction to Ant and XDoclet
1Introduction to Ant and XDoclet
2Who am I?
- Co-author, Java Development with Ant
- jGuru Ant FAQ Maintainer
- Ant Committer
- XDoclet Committer
- Senior Java Architect, Darden
- ltinsert title heregt, eHatcher Solutions, Inc.
3Overall Agenda
- Part I - Ant
- Part II - XDoclet
- QA
- Demo
4Part I Ant Agenda
- Introduction to Ant
- Example project overview
- Leveraging Ant
- Properties
- Datatypes
- Site customization
5Introduction to Ant
- What is Ant?
- Java-based build tool
- Why use Ant?
- Cross-platform
- Java domain smart
- Fast, extensible, integrated
- Alternatives?
- Analogy
- Factory automation
6Typical Things to Build
JARs
classes
Javadoc
EAR
Documentation HTML/PDF
WAR
7Designing a Build
- What are you building?
- What does it take to build it?
- How are the steps related?
8Our Project
- Search engine of static content allowing for
site-specific user interface customization.
9High-level Model
HTML / Text files
Source Code
"The Build"
Index
Application (EAR)
10Technical Architecture
content
Web Tier
Ant build ltindexgt task
EJB Container
index
11Bonus Requirements
- Report the duration of each web request
- Allow viewing of build information from live
application - Build and deploy multiple sites simultaneously,
each with separate indexes and content
12Project Structure
- Directory structure
- Simpler is better
- Map to artifacts
- Customizations/personalizations
- IDE issues
- Separate source from artifacts - cleanable
13Top-level Directory Structure
lib
metadata
src
test
tools
web
14Java Directory Structure
src test
anttask
org.example.antbook
common
ejb
web
15Build File
- XML format
- Typically in project root directory
- Default name build.xml
- Declarative - define steps
- Defines a single project
- A project contains targets
- Targets contain tasks
16Dependencies
ejbdoclet
webdoclet
package-web
package-ejb
package-common
package-anttask
Did someone say container shootout?
build-site-index
package-ear
deploy-jboss
17build.xml - Targets
lt?xml version"1.0" ?gt ltproject name"antbook"
default"default"gt lttarget
name"init"gtlt/targetgt lttarget name"clean"
description"Removes build artifacts"gt
lt/targetgt lttarget name"package-ear
depends"package-common,package-ejb,package-w
eb description"Package EAR"gt
lt/targetgt lttarget name"deploy-jboss
depends"package-ear,build-site-index
description"Deploy to local
JBoss"gt lt/targetgt lttarget
name"default" depends"package-ear"/gt lt/projectgt
18Tasks
- Do the work
- Handle dependency checking internally
- Parameterizable
- Commonly used tasks include
- ltmkdirgt
- ltjavacgt
- ltjargt
19Running Ant targets
- Execute default target ant
- Execute specific target ant deploy-jboss
- Execute multiple targets ant test-common
generate-test-reports - IDE just double-click
20Command-line switches
- -projecthelp
- gt ant -projecthelp
- Buildfile build.xml
- Main targets
- checkstyle Check code style
- clean Removes build artifacts
- compile-anttask Compile anttask module
- compile-common Compile common module
- compile-web Compile web module
- deploy-jboss Deploy to local JBoss
- ejbdoclet Generate EJB code and
descriptors - generate-test-reports Generate test reports
- package-ear Package EAR
- package-ejb Package EJB JAR
- package-web Package WAR
- test-anttask Test anttask module
- test-common Test common module
- webdoclet Generate web and Struts
descriptors
- -verbose
- -debug
- -find ltfilegt
- -diagnostics
- -logfile ltfilegt
- -help
- and others
21Sample Ant Run
gt ant deploy-jboss -Dsiteantdocs Buildfile
build.xml init echo Building for antdocs
site. deploy-jboss copy Copying 1 file
to /Users/erik/jboss-3.0.0/server/default/deploy
BUILD SUCCESSFUL Total time 18 seconds
22Properties
- Ants parameterizability
- Immutable
- All JVM system properties available
- Useful Ant built-in properties
- ant.project.name
- basedir
- property.name for property value
23ltpropertygt task
- Name/value ltproperty name"site"
value"sample"/gt - Load from properties fileltproperty
file"sites/site/config.properties
prefix"site"/gt - Load environment variablesltproperty
environment"env"/gt
24Property for file/directory
ltproperty namebuild.dir locationbuild/gt lt
property name"index.dir
location"build.dir/site/index /gt
25Properties Quiz
build.properties javac.debugoff
ltproperty filebuild.properties/gt ltproperty
namejavac.debug valueon/gt ltecho
messagedebug compilation is turned
javac.debug/gt
echo debug compilation is turned ????
off
26Other Property setting tasks
- ltavailablegt - sets if resource present
- ltuptodategt - sets if source files older
- ltconditiongt - O/S, checksum, http, socket, files
match, and more. - lttstampgt
- ltxmlpropertygt
27ltjavacgt
- Façade over Java compilers
- Performs .java/.class out-of-date checking
- Example of why the docs are important!
ltjavac srcdir"src/moduleadditional.src.d
irs" destdir"build.dir/module/classes"
debug"javac.debug" classpathref"compile
.classpath" /gt
28ltjavacgt - A Closer Look
Property reference
ltjavac srcdir"src/moduleadditional.src.d
irs" destdir"build.dir/module/classes"
debug"javac.debug" classpathref"compile
.classpath" /gt
Path
Datatype reference
29Ant Datatypes
- Provides domain expertise (e.g. paths)
- Reusable
- Commonly used built-in datatypes
- Path
- Fileset
- Patternset
- Filterset
- and others
30Path
- Ordered list of path elements
- Analogous to Java CLASSPATH
- Cross-platform path syntax
- Contains files and/or directories
- May contain a fileset, individual elements, or
nested paths.
ltpath id"anttask.compile.classpath"gt
ltpathelement location"lucene.jar"/gt
ltpathelement location"jtidy.jar"/gt lt/pathgt
31Fileset
- Set of files from a single root directory
- Unordered
- Patternsets / Selectors filter files
- Many special files automatically excluded
ltfileset dir"web" excludes"search.jsp"/gt ltfiles
et dir"build.dir/site" includes".jsp"/gt
32Patternset
- Collection of file matching patterns
- Relative paths, can apply to any root directory
- Exclusions take precedence
- ltincludegt/ltexcludegt conditional-capable
ltpatternset idjava.files.pattern
includes/.java/gt ltfileset dir"src"gt
ltpatternset refidjava.files.pattern/gt lt/fileset
gt
33Filterset
metadata/app/application.xml ltwebgt
ltweb-urigtantbook-_at_SITE_at_.warlt/web-urigt
ltcontext-rootgtantbook-_at_SITE_at_lt/context-rootgt lt/webgt
ltcopy todir"build.dir/site"
overwrite"true"gt ltfileset dir"metadata/app"
includes"application.xml"/gt ltfiltersetgt
ltfilter token"SITE" value"site"/gt
lt/filtersetgt lt/copygt
build.dir/antdocs/application.xml ltwebgt
ltweb-urigtantbook-antdocs.warlt/web-urigt
ltcontext-rootgtantbook-antdocslt/context-rootgt lt/web
gt
34Other Ant datatypes
- Selector
- FilterChain / FilterReader
- Mapper - map source filename to destination
- Filelist - ordered collection of files
- Dirset
- ZipFileset
- ClassFileset
35Overriding properties
- Carefully order ltpropertygtltproperty
file"user.home/.ant.project.name-build.prop
erties"/gtltproperty file"user.home/.build.prop
erties"/gtltproperty file"build.properties"/gtltp
roperty environment"env"/gtltproperty
name"jboss.home" location"env.JBOSS_HOME"/gtlt
property name"env.COMPUTERNAME"
value"env.HOSTNAME"/gtltproperty
name"lib.dir" location"lib"/gtltproperty
file"lib.dir/lib.properties"/gtltproperty
file"common.properties"/gt - Command-line -D and -propertyfile switchesant
deploy-jboss -Dsiteantdocsant -propertyfile
nightly-build.properties
36Controlling with Properties
- Existence of property is IMPORTANTltjunit
ltbatchtest todir"test.dir/data"
if"testcase"gt ltfileset
dir"test.dir/module/classes
includes"/testcase.class"/gt
lt/batchtestgt ltbatchtest todir"test.dir/dat
a" unless"testcase"gt ltfileset
dir"test.dir/module/classes
includes"/Test.class"/gt
lt/batchtestgtlt/junitgt - Conditional
- lttargetgt
- Patternset ltincludegt/ltexcludegt elements
- ltfailgt
ltfail unless"site.config.present"gt Site
configuration for site not present. lt/failgt
37Datatype References
- ltpath id"web.compile.classpath"gt
- ltpathelement location"dist.dir/antbook-com
mon.jar"/gt - ltpathelement location"dist.dir/antbook-ejb
.jar"/gt - ltpathelement location"struts.jar"/gt
- ltpathelement location"oro.jar"/gt
- ltpathelement location"commons-digester.jar
"/gt - ltpathelement location"commons-fileupload.ja
r"/gt - ltpathelement location"commons-lang.jar"/gt
- ltpathelement location"commons-resources.jar
"/gt - ltpathelement location"commons-validator.jar
"/gt - ltpathelement location"j2ee.jar"/gt
- lt/pathgt
- ltpath id"web.test.classpath"gt
- ltpathelement location"junit.jar"/gt
- ltpath refid"web.compile.classpath"/gt
- lt/pathgt
38Site Customization
- Controlled by site property
- Artifacts unique to site
- Index and content (of course)
- application.xml (different WAR file names)
- web.xml (different index directory references)
- jboss.xml (different JNDI names for session bean)
- search.jsp (results presentation differs)
39Loading site properties
lt!-- Site configuration --gt ltproperty name"site"
value"sample"/gt ltproperty name"site.dir"
location"sites/site"/gt ltproperty
name"index.dir location"build.dir/
site/index"/gt ltproperty file"site.dir/conf
ig.properties prefix"site"/gt
sites/antdocs/config.properties search.linklta
href"file//ltbeanwrite name"item"
property"field(path)"/gt"gt
ltbeanwrite name"item" property"field(title)"/gtlt
/agt
40Declarative logic
- Per-site customizations happen without any
explicit logic - search.jsp customizationltcopy
todir"build.dir/site" overwrite"true"gt
ltfileset dir"web" includes"search.jsp"/gt
ltfiltersetgt ltfilter token"LINK
value"site.search.link"/gt
lt/filtersetgtlt/copygt - WAR and EAR are named by siteltwar
destfile"dist.dir/antbook-site.wargt
41What else?
- JUnit / Cactus / HttpUnit
- Running Java / native programs
- Remote deployment
- Native development
- Custom Ant development
- Maven Centipede
- Continuous integration
- Last but not least..XDoclet
42Part II XDoclet with Ant
43Part II XDoclet Agenda
- Introduction to XDoclet
- XDoclet architecture
- The many ways XDoclet is leveraged
44What is XDoclet?
- Javadoc metadata templating engine
- Attribute-oriented programming
- Outgrown its EJBDoclet roots
_at_tags
45Why XDoclet?
- Avoid code/metadata duplication
- Pragmatic Programming
- DRY - Dont Repeat Yourself
- Program close to the problem domain
- Write code that writes code
- JSRs 175 181
46JSR 175
A metadata facility for the JavaTM Programming
Language would allow classes, interfaces, fields,
and methods to be marked as having particular
attributes.
47JSR 181
This JSR defines an annotated JavaTM format that
that uses JavaTM Language Metadata (JSR 175) to
enable easy definition of Java Web Services in a
J2EE container.
48XDoclet Architecture
- Built upon XJavaDoc
- Separated into modules
- Sophisticated Ant tasks with dynamically loaded
subtasks - Embedded templates
- Tag handlers
49XJavaDoc
- JavaCC-based source code parser
- Builds model of
- Packages
- Classes / inheritance hierarchy
- Methods and parameters
- Member variables
- Constructors
- Custom _at_tags
- oh yeah, and Javadoc comments too
50Technical Architecture
content
Web Tier
Ant build ltindexgt task
EJB Container
index
51Bonus Requirements
- Report the duration of each web request
- Allow viewing of build information from live
application - Build and deploy multiple sites simultaneously,
each with separate indexes and content
52ToDo List
53_at_todo
/ Index the fileset. _at_exception
IOException if Lucene I/O exception _at_todo
refactor!!!!! / private void indexDocs() throws
IOException // . . .
54Ant lttaskdefgt
lttaskdef name"todo" classname"xdoclet.m
odules.doc.DocumentDocletTask"
classpathref"xdoclet.classpath" /gt lttarget
name"todo"gt ltmkdir dir"build.dir/todo"/gt
lttodo destdir"build.dir/todo" gt
ltfileset dir"src/anttask"/gt ltfileset
dir"src/common"/gt ltfileset
dir"src/ejb"/gt ltfileset
dir"src/web"/gt ltinfo/gt
lt/todogt lt/targetgt
55EJB Deployment Descriptor
. .lt!-- ejb-jar.xml --gt . ltenterprise-beansgt
ltsession gt ltejb-namegtorg.example.ant
book.session.SearchSessionlt/ejb-namegt
lthomegtorg.example.antbook.session.SearchSessionHom
elt/homegt ltremotegtorg.example.antbook.sess
ion.SearchSessionlt/remotegt ltejb-classgt
org.example.antbook.session.SearchSessio
nBean lt/ejb-classgt
ltsession-typegtStatelesslt/session-typegt
lttransaction-typegtContainerlt/transaction-typegt
lt/sessiongt . . .
56Vender-specific Descriptors
ltjbossgt ltenterprise-beansgt ltsessiongt
ltejb-namegtorg.example.antbook.session.Searc
hSessionlt/ejb-namegt ltjndi-namegt
personal/org.example.antbook.session.SearchSessi
on lt/jndi-namegt lt/sessiongt
lt/enterprise-beansgt ltresource-managersgt
lt/resource-managersgt lt/jbossgt
57Session Bean
/ _at_ejb.bean type"Stateless
jndi-name"site/org.example.antbook.session.Sea
rchSession" _at_ejb.util generate"physical"
/ public class SearchSessionBean implements
SessionBean // /
_at_ejb.interface-method / public
Document search(String indexDir, String query)
throws
SearchQueryException,SystemException
return SearchUtil.findDocuments(indexDir,
query)
58Ant Property Substitution
- Allows build-time control over values generated
ltproperty file"user.home/.ant.project.name-
build.properties"/gt ltproperty file"user.home/.
build.properties"/gt ltproperty file"build.properti
es"/gt ltproperty name"site" value"sample"/gt
/ _at_ejb.bean type"Stateless
jndi-name"site/org.example.antbook.session.Sea
rchSession" _at_ejb.util generate"physical"
/ public class SearchSessionBean implements
SessionBean . . .
59Session Bean XDoclet-style
SessionBean
Source Code
Remote interface
Home interface
Generated
Lookup Utilities
jboss.xml
ejb-jar.xml
60ltejbdocletgt
lttarget name"ejbdoclet" depends"init"gt
lttaskdef name"ejbdoclet"
classname"xdoclet.modules.ejb.EjbDocletTask"
classpathref"xdoclet.classpath"/gt
ltmkdir dir"build.dir/ejb/gen"/gt
ltejbdoclet destdir"build.dir/ejb/gen"
addedtags"_at_xdoclet-generated at
TODAY" ejbspec"1.1"
force"xdoclet.force"
mergedir"metadata/ejb"gt ltfileset
dir"src/ejb"/gt ltremoteinterface/gt
lthomeinterface/gt ltutilobject/gt
ltjboss validatexml"true" destdir"build.dir
/site"/gt ltdeploymentdescriptor
validatexml"true"/gt lt/ejbdocletgt lt/targetgt
61Servlet Definition
ltservletgt ltservlet-namegtsearch-initlt/servlet-
namegt ltservlet-classgt
org.example.antbook.web.SearchInitServlet
lt/servlet-classgt ltinit-paramgt
ltparam-namegtindex-dirlt/param-namegt
ltparam-valuegt/Users/erik/. . ./personal/indexlt/par
am-valuegt lt/init-paramgt
ltload-on-startupgt1lt/load-on-startupgt lt/servletgt
62Servlet
/ _at_web.servlet name"search-init"
load-on-startup"1" _at_web.servlet-init-param
name"index-dir" value"index.dir" _at_todo
Refactor to use JNDI for directory lookup.
/ public class SearchInitServlet extends
HttpServlet public void init() throws
ServletException super.init()
ServletConfig config getServletConfig()
getServletContext().setAttribute(Constants.SEARCH
_DIRECTORY, config.getInitParamete
r("index-dir"))
63Filter Definition
ltfiltergt ltfilter-namegtTimingFilterlt/filter-name
gt ltfilter-classgtorg.example.antbook.web.TimingFi
lterlt/filter-classgt lt/filtergt ltfilter-mappinggt
ltfilter-namegtTimingFilterlt/filter-namegt
lturl-patterngt/lt/url-patterngt lt/filter-mappinggt
64Filter
/ Logs duration of each request.
_at_web.filter name"TimingFilter"
_at_web.filter-mapping url-pattern"/"
servlet-name"TimingFilter" / public class
TimingFilter implements Filter // . . .
65Tag Library Descriptor
lttaglibgt lttlib-versiongt1.0lt/tlib-versiongt
ltjsp-versiongt1.2lt/jsp-versiongt
ltshort-namegtantbooklt/short-namegt lttaggt
ltnamegtbuildpropslt/namegt lttag-classgtorg.examp
le.antbook.web.BuildPropertiesTaglt/tag-classgt
lttei-classgtorg.example.antbook.web.BuildProperti
esTeilt/tei-classgt lt/taggt lt/taglibgt
66Tag Library
/ Iterates build properties and places
name/value into page scope. _at_jsp.tag
name"buildprops" bodycontent"JSP"
tei-class"org.example.antbook.web.Buil
dPropertiesTei" / public class
BuildPropertiesTag extends BodyTagSupport
// . . .
67Web Deployment Descriptor
SearchInitServlet
TimingFilter
BuildPropertiesTag
merge files
web.xml
68Merge Points
- Not everything is stored in source code
- Customization entry point to generated artifacts
- Often documented in the generated code
- web.xml, for example
- External servlet mappings
- Tag library mappings
- Welcome file list, error pages, etc
69Quick Struts Overview
SearchForm
ActionServlet
instantiates, populates, validates
/search.do?querye
SearchAction
executes
search.jsp
String resources
70Struts Descriptors
- struts-config.xml
- Global form bean definitions
- Action mappings
- validation.xml
- Field-level validations per form or action
- I18N
- Extensible
71struts-config.xml
ltform-beansgt ltform-bean name"SearchForm"
type"org.example.antbook.struts.Search
Form" /gt lt!-- If you have non
XDoclet forms, define them in a file
called struts-forms.xml and place it in
your merge directory. --gt lt/form-beansgt
72validation.xml
Form bean name
ltform name"SearchForm"gt ltfield
property"query" depends"required"gt
ltmsg name"required"
key"query.required /gt ltarg0
key"SearchForm.query"/gt lt/fieldgt lt/formgt
Field name
Validation(s)
Message key
Argument for message
query.requiredYou must enter a query
73Struts ActionForm
/ Search query entry form.
_at_struts.form name"SearchForm" / public
class SearchForm extends ValidatorForm
private String query / Sets the
query attribute of the SearchForm object
_at_struts.validator type"required"
msgkey"query.required" / public void
setQuery(String query) this.query
query public String getQuery()
return query
74ltwebdocletgt
ltwebdoclet destdir"build.dir/web/WEB-INF"
force"xdoclet.force"
mergedir"metadata/web"gt ltfileset
dir"src/web"/gt ltdeploymentdescriptor
validatexml"true
destdir"build.dir/site /gt
ltjsptaglib validatexml"true
shortName"antbook
filename"antbook.tld /gt
ltstrutsconfigxml validatexml"true"
version"1.1"/gt ltstrutsvalidationxml
omitdtd"true"/gt lt/webdocletgt
75Custom Generation
- Supply your own templates for the standard
subtasks - Use lttemplategt task for ad hoc generation
- Write tag handlers / subtasks
76Ant Task Library
- Declare multiple Ant tasks using a properties
filelttaskdef resource"taskdef.properties
classpath"lucene.jardist.dir/antbook-antta
sk.jarjtidy.jar" - /gt
- Name/classname pairsindexorg.example.antbook.a
nt.lucene.IndexTask - Task(s) availableltindex index"index.dir
overwrite"falsegtlt/indexgt
77Custom Ant Task Metadata
/ Ant task to index files with Lucene
_at_ant.task name"index" / public class IndexTask
extends Task // . . .
78lttemplategt subtask
ltxdoclet destdir"build.dir/anttask/classes"gt
ltfileset dir"src/anttask"gt ltinclude
name"/.java" /gt lt/filesetgt lttemplate
templatefile"metadata/anttask/taskdef.xdt"
destinationfile"taskdef.properties"gt
ltconfigParam name"date" value"DSTAMP _at_
TSTAMP"/gt lt/templategt lt/xdocletgt
79XDoclet template
Created ltXDtConfigconfigParameterValue
paramName"date"/gt ltXDtClassforAllClassesgt
ltXDtClassifHasClassTag tagName"anttask"
paramName"name"gt ltXDtClassclassTagValue
tagName"anttask" paramName"name"/gt
ltXDtClassfullClassName/gt lt/XDtClassifHasClas
sTaggt lt/XDtClassforAllClassesgt
/ _at_ant.task name"index" / public class
IndexTask extends Task
Java source
Result
Created 20020903 _at_ 2133 indexorg.example.antbo
ok.ant.lucene.IndexTask
80Passive Generators
- Based on metadata from XDoclet
- One-time generation
- Results customized
- Regeneration painful after customizing
- Great for rapid development
- Example
- Starter Struts JSP pages
- String resources
81Starter Struts Pieces
SearchForm
JSP
Localized resources
SearchForm.queryQuery
lttablegt lttrgt ltthgtltbeanmessage
key"SearchForm.query"/gtlt/thgt lttdgtlthtmltext
property"query"/gtlt/tdgt lt/trgt lt/tablegt
82Per-class template generation
ltxdoclet destdir"build.dir
excludedtags"_at_version,_at_author"
force"xdoclet.force"gt ltfileset
dir"struts.src.dir"
includes"/form.name.java" /gt
lttemplate templateFile"src/FormKeys.xdt"
ofType"org.apache.struts.validator.Valida
torForm" acceptAbstractClasses"fa
lse" prefixWithPackageStructure"f
alse" destinationFile"0.propert
ies" /gt lttemplate templateFile"src/St
rutsForm_jsp.xdt"
ofType"org.apache.struts.validator.ValidatorForm"
acceptAbstractClasses"false"
prefixWithPackageStructure"false"
destinationFile"0.jsp"
/gt lt/xdocletgt
83Template w/ Custom Tag
ltXDtTagDeftagDef namespace"Struts
handler"org.example.antbook.xdoclet.FormTags
Handler"/gt ltXDtStrutsforAllFieldsgt ltXDtClass
classTagValue tagName"struts.form"
paramName"name"/gt. ltXDtStrutsfieldName/
gtltXDtStrutsfieldDescription/gt
lt/XDtStrutsforAllFieldsgt
84Custom Tag Handler
public void forAllFields(String template,
Properties attributes)
throws XDocletException
XClass clazz getCurrentClass() TreeMap
setters new TreeMap(getFields(clazz)) for
(Iterator iterator setters.keySet().iterator()
iterator.hasNext()) curFieldName
(String) iterator.next() XMethod field
(XMethod) setters.get(curFieldName)
setCurrentMethod(field)
generate(template) public String
fieldName(Properties props) return
curFieldName
85Future of XDoclet
- Velocity templating
- Jakarta project?
- Support for metadata JSRs
86References
- Java Development with Ant
- http//www.amazon.com/exec/obidos/ASIN/1930110588
- http//www.manning.com/antbook/
- XDoclet
- http//xdoclet.sourceforge.net
- Pragmatic Programmer
- http//www.pragmaticprogrammer.com/
- Agile development
- eXtreme Programming Explained, Kent Beck
- Agile Modeling, Scott Ambler
87The End