Title: Ant: The Only Bug You Want Near Your Software
1AntThe Only Bug You Want Near Your Software
- Erik Hatcher
- erik_at_ehatchersolutions.com
2Who am I?
- Co-author, Java Development with Ant
- jGuru Ant FAQ Maintainer
- Ant Committer
- XDoclet Committer
- , eHatcher Solutions, Inc.
3Agenda
- What Ant is
- How to use it on a project
- Syntax and usage
- Properties
- Datatypes
- Power of properties
- Unit testing
- XDoclet
- You will leave with
- Understanding of Ant and what it can do
- Some tricks of the trade
- Insight into XDoclet and its power
- Lots to cover, so lets get going
4Introduction to Ant
- What is Ant?
- Java-based build tool
- Why use Ant?
- Cross-platform
- Java domain smart
- Fast, extensible, integrated
- Alternatives?
- Analogy
- Factory automation
5Typical Things to Build
6Designing a Build
- What are you building?
- What does it take to build it?
- How are the steps related?
7Our Project
- Search engine of static content allowing for
site-specific user interface customization.
8High-level Model
HTML / Text files
Source Code
Index
Application (EAR)
9Technical Architecture
content
Web Tier
Ant build task
EJB Container
index
10Bonus 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
11Project Structure
- Directory structure
- Simpler is better
- Map to artifacts
- Customizations/personalizations
- IDE issues
- Separate source from artifacts - cleanable
12Top-level Directory Structure
lib
metadata
src
test
tools
web
13Java Directory Structure
src test
anttask
org.example.antbook
common
ejb
web
14Build File
- XML format
- Typically in project root directory
- Default name build.xml
- Declarative - define steps, not scripty details
- Defines a single project
- A project contains targets
- Targets contain tasks
15Dependencies
ejbdoclet
webdoclet
package-web
package-ejb
package-common
package-anttask
build-site-index
package-ear
deploy-jboss
16build.xml - Targets
fault"default" n"Removes build artifacts" t depends"package-common,package-ejb,package-web
description"Package EAR"
oy-jboss depends"package-ear,build-
site-index description"Deploy to lo
cal JBoss" name"default" depends"package-ear"/
17Tasks
- Do the work
- Handle dependency checking internally
- Parameterizable
- Commonly used tasks include
-
-
18Running Ant targets
- Execute default target ant
- Execute specific target ant deploy-jboss
- Execute multiple targets ant test-common
generate-test-reports
19Command-line switches
- -projecthelp
- 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
- -diagnostics
- -logfile
- -help
- and others
20Sample Ant Run
ant deploy-jboss -Dsitepersonal
Buildfile build.xml init echo Buildin
g for personal site. deploy-jboss copy
Copying 1 file to /Users/erik/jboss-3.0.0/server
/default/deploy BUILD SUCCESSFUL Total time 1
8 seconds
21Properties
- Ants parameterizability
- Immutable
- All JVM system properties available
- Useful Ant built-in properties
- ant.project.name
- basedir
- property.name for property value
22 task
- Name/value value"sample"/
- Load from properties filefile"sites/site/config.properties
prefix"site"/
- Load environment variablesenvironment"env"/
23Property for file/directory
on"build.dir/site/index
/
24Properties Quiz
build.properties javac.debugoff
javac.debug/
echo debug compilation is turned ????
25Other Property setting tasks
- - sets if resource present
- - sets if source files older
- - O/S, checksum, http, socket, files
match, and more.
-
26- Façade over Java compilers
- Performs .java/.class out-of-date checking
- Example of why the docs are important!
dirs" destdir"build.dir/module/classes
" debug"javac.debug" classpathref"com
pile.classpath" /
27 - A Closer Look
Property
dirs" destdir"build.dir/module/classes
" debug"javac.debug" classpathref"com
pile.classpath" /
Path
Datatype reference
28Ant Datatypes
- Provides domain expertise (e.g. paths)
- Reusable
- Commonly used built-in datatypes
- Path
- Fileset
- Patternset
- Selectors
- Filterset
- and others
29Path
- 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.
30Fileset
- Set of files from a single root directory
- Unordered
- Patternsets / Selectors filter files
- Many special files automatically excluded
jsp"/
31Patternset
- Collection of file matching patterns
- Relative paths, can apply to any root directory
- Exclusions take precedence
- / conditional-capable
includes/.java/
32Selectors
- New to Ant 1.5
- Sophisticated file selection capability
- Available selectors depth, size, date, present,
depend, contains
- Containers and, or, not, none, majority
argetdir"currentfiles"/
33Filterset
metadata/app/application.xml an
tbook-_at_SITE_at_.war antboo
k-_at_SITE_at_
overwrite"true" includes"application.xml"/
build.dir/personal/application.xml
antbook-personal.war
antbook-personal
34FilterChain / FilterReader
- FilterReader remove/modify text
- FilterChain ordered group of FilterReaders
- Built-in FilterReaders
-
- /
- /
-
35FilterChain example
package org.example.antbook public interface Con
stants public static final String VERSION
"1.7"
/Constants.class" stants/
Const
ants.VERSION Constants.VERSION
echo Constants.VERSION 1.7
36Other Ant datatypes
- Mapper - map source filename to destination
- Filelist - ordered collection of files
- Dirset
- ZipFileset
- ClassFileset
37Overriding properties
- Carefully order file"user.home/.ant.project.name-build.prop
erties"/erties"/roperty environment"env"/name"jboss.home" location"env.JBOSS_HOME"/property name"env.COMPUTERNAME"
value"env.HOSTNAME"/name"lib.dir" location"lib"/file"lib.dir/lib.properties"/file"common.properties"/ - Command-line -D and -propertyfile switchesant
deploy-jboss -Dsitepersonalant -propertyfile
nightly-build.properties
38Controlling with Properties
- Existence of property is IMPORTANTif"testcase" dir"test.dir/module/classes
includes"/testcase.class"/
a" unless"testcase" dir"test.dir/module/classes
includes"/Test.class"/
- Conditional
-
- Patternset / elements
-
- Site configuration for site not
present.
-
39Datatype References
-
- mon.jar"/
- .jar"/
-
-
- "/
- r"/
-
- "/
- "/
-
-
-
-
-
-
40Library Dependencies
- Easily allow
- Multiple projects to use different library
versions
- A developer to build against a new version
without affecting the team or local environment
- Property immutability is the key!
41lib Directory Structure
lib
lucene-1.2
lucene-1.2.jar
jakarta-struts-1.1-b2-lib
struts.jar
jtidy-04aug2000r7-dev
build
Tidy.jar
. . .
42lib.properties
lib/lib.properties - Global default library
mappings Lucene - http//jakarta.apache.org/
lucene lucene.version 1.2 lucene.dir
lib.dir/lucene-lucene.version
lucene.jarlucene.dir/lucene-lucene.version.
jar Struts - http//jakarta.apache.org/str
uts struts.version 1.1-b2 struts.dir
lib.dir/jakarta-struts-struts.version-lib
struts.jarstruts.dir/struts.jar
43Swapping Libraries
- Per-buildant -Dlucene.jar/path/to/mylucene.jar
- Per-project
- Create build.properties with overrideslucene.ver
sion1.3
- Per-developer
- Create /.antbook-build.propertiesstruts.dir/Us
ers/erik/struts-devsitepersonal
44Site 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)
45Loading site properties
value"sample"/ ation"sites/site"/ ir location"build.dir/site/inde
x"/ ies prefix"site"/
sites/sample/config.properties
search.linkname"item" property"field(path)"/"
property"field(title)"/
46Declarative logic
- Per-site customizations happen without any
explicit logic
- search.jsp customization
- overwrite"true" includes"search.jsp"/
value"site.search.link"/
- WAR and EAR are named by site
- ar
47Unit testing
- Test-driven design
- Courage
- Refactoring
Any program feature without an automated test
simply doesnt exist. (Kent Beck, eXtreme Progra
mming Explained)
48JUnit TestCase
public class TextDocumentTest extends
DocumentTestCase public TextDocumentTest (
String name) super(name)
TextDocument doc public void
setUp() throws IOException doc new Te
xtDocument(getFile("test.txt"))
public void testDoc()
assertEquals("Contents", "Test Contents",
doc.getContents()) public void
tearDown() doc null
49 task
excludes"/.java"/ ummary"no errorProperty"test.failed
failureProperty"test.failed
fork"junit.fork" rty key"docs.dir" file"test.dir/module/cla
sses"/ st.dir/index"/
eset dir"test.dir/module/classes"
includes"/Test.class"
/ .failed"Unit tests failed.
50Unit test reporting
51 task
name"TEST-.xml"/ rmat"frames" todir"test.dir/report"/
52Cactus
- In-container unit testing
53Cactus example
public class SearchFormTest extends
CactusStrutsTestCase public SearchFormTest(
String s) super(s) publi
c void testValidation() addRequestParam
eter("query","") setRequestPathInfo("/se
arch") actionPerform() verifyA
ctionErrors(new String "query.required")
verifyInputForward()
54What else?
- Running Java / native programs
- Remote deployment
- Native development
- Custom Ant development
- Maven Centipede
- Continuous integration
- Last but not least..XDoclet
55What is XDoclet?
- Javadoc metadata templating engine
- Attribute-oriented programming
- Outgrown its EJBDoclet roots
56Why 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
57JSR 175
A metadata facility for the JavaTM Programming
Language would allow classes, interfaces, fields,
and methods to be marked as having particular
attributes.
58JSR 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.
59XDoclet Architecture
- Built upon XJavaDoc
- Separated into modules
- Embedded templates
- Sophisticated Ant task with dynamically loaded
subtasks
- Tag handlers
60XJavaDoc
- JavaCC-based source code parser
- Builds model of
- Packages
- Classes / inheritance hierarchy
- Methods and parameters
- Member variables
- Constructors
- _at_tags
- oh yeah, and Javadoc comments too
61Our Project (refresher)
- Search engine of static content allowing for
site-specific user interface customization.
62High-level Model
HTML / Text files
Source Code
Index
Application (EAR)
63Technical Architecture
content
Web Tier
Ant build task
EJB Container
index
64Bonus 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
65XDoclet in this project
- Generates
- To-Do list
- EJB home/remote/lookup utilities
- Deployment descriptors ejb-jar.xml, jboss.xml
- Web web.xml, struts-config.xml, validation.xml
- Ant task custom properties file generation
- Starter JSP / resource properties
66ToDo List
67_at_todo
/ Index the fileset. _at_exception IOEx
ception if Lucene I/O exception
_at_todo refactor!!!!! / private void indexDocs
() throws IOException // . . .
68Ant
modules.doc.DocumentDocletTask"
classpathref"xdoclet.classpath"
/ d.dir/todo"/ todo"
69EJB Deployment Descriptor
. . .
org.exam
ple.antbook.session.SearchSession
org.example.antbook.session.Searc
hSessionHome org.example.
antbook.session.SearchSession
org.example.antb
ook.session.SearchSessionBean s Stateless Containeron-type . . .
70Vender-specific Descriptors
org.example.antbook.session.
SearchSession
personal/org.example.antbook.session.Sear
chSession
s
71Session Bean
/ _at_ejb.bean type"Stateless jndi
-name"site/org.example.antbook.session.SearchS
ession" _at_ejb.util generate"physical" / pu
blic class SearchSessionBean implements
SessionBean // / _at_ejb.inter
face-method / public Document search
(String indexDir, String query)
throws
SearchQueryException,SystemException
return SearchUtil.findDocuments(indexDir,
query)
72Ant Property Substitution
- Allows build-time control over values generated
build.properties"/ .build.properties"/ ties"/
/ _at_ejb.bean type"Stateless jndi
-name"site/org.example.antbook.session.SearchS
ession" _at_ejb.util generate"physical" / pu
blic class SearchSessionBean implements
SessionBean . . .
73Session Bean XDoclet-style
SessionBean
Source Code
Remote interface
Home interface
Generated
Lookup Utilities
jboss.xml
ejb-jar.xml
74 classname"xdoclet.modules.ejb.Ej
bDocletTask" classpathref"xdocl
et.classpath"/ jb/gen"/ jb/gen" addedtags"_at_xdoclet-gener
ated at TODAY" ejbspec"1.1"
force"xdoclet.force"
mergedir"metadata/ejb"
face/ lidatexml"true" destdir"build.dir/site"/
validatexml"true"/
75Servlet Definition
search-initt-name org.example
.antbook.web.SearchInitServlet
aram-nameindex-dir
/Users/erik/. .
./personal/index
1on-startup
76Servlet
/ _at_web.servlet name"search-init" load-on-st
artup"1" _at_web.servlet-init-param name"index-
dir" value"index.dir" _at_todo Refactor t
o use JNDI for directory lookup.
/ public class SearchInitServlet extends HttpSe
rvlet public void init() throws ServletExce
ption super.init() ServletC
onfig config getServletConfig()
getServletContext().setAttribute(Constants
.SEARCH_DIRECTORY, config.getInit
Parameter("index-dir"))
77Filter Definition
TimingFilterme org.example.antbook.web.Timin
gFilter ping TimingFilter
/ ing
78Filter
/ Logs duration of each request. _at_we
b.filter name"TimingFilter" _at_web.filter-mappi
ng url-pattern"/" servlet-name"TimingFilter"
/ public class TimingFilter implements Filter
// . . .
79Tag Library Descriptor
1.0
1.2
antbook
buildprops
org.example.antbook.web.BuildPropertie
sTag org.example.ant
book.web.BuildPropertiesTei
80Tag Library
/ Iterates build properties and places name/
value into page scope. _at_jsp.tag name"
buildprops" bodycontent"JSP"
tei-class"org.example.antbook.web.BuildProp
ertiesTei" / public class BuildPropertiesTag e
xtends BodyTagSupport // . . .
81Web Deployment Descriptor
SearchInitServlet
TimingFilter
BuildPropertiesTag
merge files
web.xml
TLD
82Merge 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
83Quick Struts Overview
SearchForm
ActionServlet
instantiates, populates, validates
/search.do?querye
SearchAction
executes
search.jsp
String resources
84Struts Descriptors
- struts-config.xml
- Global form bean definitions
- Action mappings
- validation.xml
- Field-level validations per form or action
- I18N / L16N
- Extensible
85struts-config.xml
type"org.example.antbook.struts.Sear
chForm" /
86validation.xml
Form bean name
ry" depends"required"
uired / hForm.query"/
Field name
Validation(s)
Message key (optional)
Argument for message
query.requiredYou must enter a query
87Struts ActionForm
/ Search query entry form. _at_struts.f
orm name"SearchForm" / public class Search
Form extends ValidatorForm private String q
uery / Sets the query attribut
e of the SearchForm object _at_struts
.validator type"required" msgkey"query.required"
/ public void setQuery(String query)
this.query query pub
lic String getQuery() return query
88 force"xdoclet.force"
mergedir"metadata/web"
escriptor validatexml"true
destdir"build.dir/site
/ shortName"antbook filena
me"antbook.tld / idatexml"true" version"1.1"/
89What next? Its your call
- Want advanced XDoclet?
- Demo of Ant, XDoclet, and application in action?
- Q A breather?
90Custom Generation
- Supply your own templates for the standard
subtasks
- Use subtask for ad hoc generation
- Write tag handlers / subtasks
91Ant Task Library
- Declare multiple Ant tasks using a properties
file
- lucene.jardist.dir/antbook-anttask.jarjt
idy.jar"
- /
- Name/classname pairsindexorg.example.antbook.a
nt.lucene.IndexTask
- Task(s) available overwrite"false
92Custom Ant Task Metadata
/ Ant task to index files with Lucene
_at_ant.task name"index" / public class IndexT
ask extends Task
// . . .
93 subtask
data/anttask/taskdef.xdt" destinati
onfile"taskdef.properties" name"date" value"DSTAMP _at_ TSTAMP"/
94XDoclet template
Created paramName"date"/ DtClassifHasClassTag tagName"anttask"
paramName"name" Name"anttask" paramName"name"/
asses
/ _at_ant.task name"index" / public class I
ndexTask extends Task
Java source
Result
Created 20020903 _at_ 2133 indexorg.example.antb
ook.ant.lucene.IndexTask
95Passive 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
96Starter Struts Pieces
SearchForm
JSP
Localized resources
SearchForm.queryQuery
Form.query"/ uery"/
97Per-class template generation
excludedtags"_at_version,_at_author"
force"xdoclet.force"
includes"/form.name.java"
/ ys.xdt" ofType"org.apache.struts
.validator.ValidatorForm" acceptA
bstractClasses"false" prefixWith
PackageStructure"false" destinat
ionFile"0.properties" / e templateFile"src/StrutsForm_jsp.xdt"
ofType"org.apache.struts.validato
r.ValidatorForm" acceptAbstractCl
asses"false" prefixWithPackageSt
ructure"false" destinationFile"
0.jsp" /
98Template w/ Custom Tag
handler"org.example.antbook.xdo
clet.FormTagsHandler"/ ds m" paramName"name"/. ame/
99Custom 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(cu
rFieldName) setCurrentMethod(field)
generate(template) public St
ring fieldName(Properties props)
return curFieldName
100Future of XDoclet
- Velocity templating
- Jakarta project?
- Support for metadata JSRs
- XDocletGUI
- XRAI
101References
- Java Development with Ant
- http//www.amazon.com/exec/obidos/ASIN/1930110588
- http//www.manning.com/antbook/
- Ant
- http//jakarta.apache.org/ant
- XDoclet
- http//xdoclet.sourceforge.net
- Pragmatic Programmer
- http//www.pragmaticprogrammer.com/
- Agile development
- eXtreme Programming Explained, Kent Beck
- Agile Software Development, Alistair Cockburn
102The End
Book signing immediately following presentation