1. Trang chủ
  2. » Công Nghệ Thông Tin

Java Development with Ant phần 2 ppt

68 1K 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Cấu trúc

  • Java Development with Ant

    • brief contents

    • contents

      • preface

      • acknowledgments

      • about this book

      • about the authors

      • about the cover illustration

      • foreword

    • chapter1

      • 1.1 What is Ant?

        • 1.1.1 What is a build process and why do you need one?

        • 1.1.2 Why do we think Ant makes a great build tool?

      • 1.2 The core concepts of Ant

        • 1.2.1 An example project

      • 1.3 Why use Ant?

        • 1.3.1 Integrated development environments

        • 1.3.2 Make

        • 1.3.3 Other build tools

        • 1.3.4 Up and running, in no time

      • 1.4 The evolution of Ant

      • 1.5 Ant and software development methodologies

        • 1.5.1 eXtreme Programming

        • 1.5.2 Rational Unified Process

      • 1.6 Our example project

        • 1.6.1 Documentation search engine—example Ant project

      • 1.7 Yeah, but can Ant…

      • 1.8 Beyond Java development

        • 1.8.1 Web publishing engine

        • 1.8.2 Simple workflow engine

        • 1.8.3 Microsoft .NET and other languages

      • 1.9 Summary

    • chapter2

      • 2.1 Defining our first project

      • 2.2 Step one: verifying the tools are in place

      • 2.3 Step two: writing your first Ant build file

        • 2.3.1 Examining the build file

      • 2.4 Step three: running your first build

        • 2.4.1 If the build fails

        • 2.4.2 Looking at the build in more detail

      • 2.5 Step four: imposing structure

        • 2.5.1 Laying out the source directories

        • 2.5.2 Laying out the build directories

        • 2.5.3 Laying out the dist directories

        • 2.5.4 Creating the build file

        • 2.5.5 Target dependencies

        • 2.5.6 Running the new build file

        • 2.5.7 Rerunning the build

        • 2.5.8 How Ant handles multiple targets on the command line

      • 2.6 Step five: running our program

        • 2.6.1 Why execute from inside Ant

        • 2.6.2 Adding an execute target

        • 2.6.3 Running the new target

      • 2.7 Ant command line options

        • 2.7.1 Specifying which build file to run

        • 2.7.2 Controlling the amount of information provided

        • 2.7.3 Getting information about a projec t

      • 2.8 The final build file

      • 2.9 Summary

    • chapter3

      • 3.1 Preliminaries

        • 3.1.1 Datatype overview

        • 3.1.2 Property overview

      • 3.2 Introducing datatypes and properties with <javac>

      • 3.3 Paths

      • 3.4 Filesets

        • 3.4.1 Fileset examples

        • 3.4.2 Default excludes

      • 3.5 Patternsets

      • 3.6 Selectors

      • 3.7 Datatype element naming

      • 3.8 Filterset

        • 3.8.1 Inserting date stamps in files at build-time

      • 3.9 FilterChains and FilterReaders

      • 3.10 Mappers

        • 3.10.1 Identity mappe r

        • 3.10.2 Flatten mapper

        • 3.10.3 Merge mapper

        • 3.10.4 Glob mapper

        • 3.10.5 Regexp mapper

        • 3.10.6 Package mapper

      • 3.11 Additional Ant datatypes

        • 3.11.1 ZipFileset

        • 3.11.2 Dirset

        • 3.11.3 Filelist

        • 3.11.4 ClassFileset

      • 3.12 Properties

        • 3.12.1 Setting properties with the <property> task

        • 3.12.2 How the <property> task is different

        • 3.12.3 Checking for the availability of resources: <available>

        • 3.12.4 Saving time by skipping unnecessary steps: <uptodate>

        • 3.12.5 Testing conditions with <condition>

        • 3.12.6 Setting properties from the command-line

        • 3.12.7 Creating a build timestamp with <tstamp>

        • 3.12.8 Loading properties from an XML file

      • 3.13 Controlling Ant with properties

        • 3.13.1 Conditional target execution

        • 3.13.2 Conditional patternset inclusion/exclusion

        • 3.13.3 Conditional build failure

      • 3.14 References

        • 3.14.1 Properties and references

        • 3.14.2 Using references for nested patternsets

      • 3.15 Best practices

      • 3.16 Summary

    • chapter4

      • 4.1 Refactoring

      • 4.2 Java main() testing

      • 4.3 JUnit primer

        • 4.3.1 Writing a test case

        • 4.3.2 Running a test case

        • 4.3.3 Asserting desired results

        • 4.3.4 TestCase lifecycle

        • 4.3.5 Writing a TestSuite

        • 4.3.6 Obtaining and installing JUnit

        • 4.3.7 Extensions to JUnit

      • 4.4 Applying unit tests to our application

        • 4.4.1 Writing the test first

        • 4.4.2 Dealing with external resources during testing

      • 4.5 The JUnit task—<junit>

        • 4.5.1 Structure directories to accommodate testing

        • 4.5.2 Fitting JUnit into the build process

      • 4.6 Test failures are build failures

        • 4.6.1 Capturing test results

        • 4.6.2 Running multiple tests

        • 4.6.3 Creating your own results formatter

      • 4.7 Generating test result reports

        • 4.7.1 Generate reports and allow test failures to fail the build

        • 4.7.2 Run a single test case from the command-line

        • 4.7.3 Initializing the test environment

        • 4.7.4 Other test issues

      • 4.8 Short-circuiting tests

        • 4.8.1 Dealing with large number of tests

      • 4.9 Best practices

      • 4.10 Summary

    • chapter5

      • 5.1 Why you need to run externalprograms

      • 5.2 Running Java programs

        • 5.2.1 Introducing the <java> task

        • 5.2.2 Setting the classpath

        • 5.2.3 Arguments

        • 5.2.4 Defining system properties

        • 5.2.5 Running the program in a new JVM

        • 5.2.6 Setting environment variables

        • 5.2.7 Controlling the new JVM

        • 5.2.8 Handling errors with failonerror

        • 5.2.9 Executing JAR files

        • 5.2.10 Calling third-party programs

        • 5.2.11 Probing for a Java program before calling it

        • 5.2.12 Setting a timeout

      • 5.3 Starting native programs with<exec>

        • 5.3.1 Setting environment variables

        • 5.3.2 Handling errors

        • 5.3.3 Handling timeouts

        • 5.3.4 Making and executing shell commands

        • 5.3.5 Probing for a program before calling it

      • 5.4 Bulk execution with <apply>

      • 5.5 Processing output

      • 5.6 Limitations on execution

      • 5.7 Best practices

      • 5.8 Summary

    • chapter6

      • 6.1 Moving, copying, and deleting files

        • 6.1.1 How to delete files

        • 6.1.2 How to copy files

        • 6.1.3 How to move files

        • 6.1.4 Filtering

      • 6.2 Preparing to package

        • 6.2.1 Building and documenting release code

        • 6.2.2 Adding data files

        • 6.2.3 Preparing documentation

        • 6.2.4 Preparing install scripts and documents

        • 6.2.5 Preparing libraries for redistribution

      • 6.3 Creating archive files

        • 6.3.1 JAR files

        • 6.3.2 Creating a JAR file

        • 6.3.3 Testing the JAR file

        • 6.3.4 Creating JAR manifests

        • 6.3.5 Adding extra metadata to the JAR

        • 6.3.6 JAR file best practices

        • 6.3.7 Signing JAR files

      • 6.4 Creating Zip files

        • 6.4.1 Creating a binary distribution

        • 6.4.2 Creating a source distribution

        • 6.4.3 Merging Zip files

        • 6.4.4 Zip file best practices

      • 6.5 Creating tar files

      • 6.6 Creating web applications with WARfiles

      • 6.7 Testing packaging

      • 6.8 Summary

    • chapter7

      • 7.1 Example deployment problems

        • 7.1.1 Reviewing the tasks

        • 7.1.2 Tools for deployment

      • 7.2 Tasks for deployment

        • 7.2.1 File transfer with <ftp>

        • 7.2.2 Probing for server availability

        • 7.2.3 Inserting pauses into the build with <sleep>

        • 7.2.4 Ant’s email task

        • 7.2.5 Fetching remote files with <get>

        • 7.2.6 Using the tasks to deploy

      • 7.3 FTP-based distribution of apackagedapplication

        • 7.3.1 Asking for information with the <input> task

      • 7.4 Email-based distribution of apackagedapplication

      • 7.5 Local deployment to Tomcat4.x

        • 7.5.1 The Tomcat management servlet API

        • 7.5.2 Deploying to Tomcat with Ant

      • 7.6 Remote deployment to Tomcat

        • 7.6.1 Interlude: calling targets with <antcall>

        • 7.6.2 Using <antcall> in deployment

      • 7.7 Testing deployment

      • 7.8 Summary

    • chapter8

      • 8.1 Our application thus far

      • 8.2 Building the custom Ant task library

      • 8.3 Loading common properties across multipleprojects

      • 8.4 Handling versioned dependencies

        • 8.4.1 Installing a new library version

      • 8.5 Build file philosophy

        • 8.5.1 Begin with the end in mind

        • 8.5.2 Integrate tests with the build

        • 8.5.3 Support automated deployment

        • 8.5.4 Make it portable

        • 8.5.5 Allow for customizations

      • 8.6 Summary

    • chapter9

      • 9.1 Designing an Ant-based build process

        • 9.1.1 Analyzing your project

        • 9.1.2 Creating the core build file

        • 9.1.3 Evolve the build file

      • 9.2 Migrating to Ant

      • 9.3 The ten steps of migration

        • 9.3.1 Migrating from Make-based projects

        • 9.3.2 Migrating from IDE-based projects

      • 9.4 Master builds: managing large projects

        • 9.4.1 Refactoring build files

        • 9.4.2 Introducing the <ant> task

        • 9.4.3 Example: a basic master build file

        • 9.4.4 Designing a scalable, flexible master build file

      • 9.5 Managing child project builds

        • 9.5.1 How to control properties of child projects

        • 9.5.2 Inheriting properties and references from a master build file

        • 9.5.3 Declaring properties and references in <ant>

        • 9.5.4 Sharing properties via XML file fragments

        • 9.5.5 Sharing targets with XML file fragments

      • 9.6 Creating reusable library build files

      • 9.7 Looking ahead: large project support evolution

      • 9.8 Ant project best practices

        • 9.8.1 Managing libraries

        • 9.8.2 Implementing processes

      • 9.9 Summary

    • chapter10

      • 10.1 Understanding types of tasks

        • 10.1.1 So, what is an “optional” task?

        • 10.1.2 Ant’s major optional tasks

        • 10.1.3 Why third-party tasks?

      • 10.2 Optional tasks in action

        • 10.2.1 Manipulating property files

        • 10.2.2 Adding audio and visual feedback during a build

        • 10.2.3 Adding dependency checks

        • 10.2.4 Grammar parsing with JavaCC

        • 10.2.5 Regular expression replacement

      • 10.3 Using software configuration managementtasks

        • 10.3.1 CVS

        • 10.3.2 ClearCase

      • 10.4 Using third-party tasks

        • 10.4.1 Defining tasks with <taskdef>

      • 10.5 Notable third-party tasks

        • 10.5.1 Checkstyle

        • 10.5.2 Torque–object-relational mapping

      • 10.6 The ant-contrib tasks

      • 10.7 Sharing task definitions amongprojects

      • 10.8 Best practices

      • 10.9 Summary

    • chapter11

      • 11.1 Installing XDoclet

      • 11.2 To-do list generation

      • 11.3 XDoclet architecture

        • 11.3.1 XDoclet’s Ant tasks

        • 11.3.2 Templating

        • 11.3.3 How XDoclet works

      • 11.4 Writing your own XDoclet template

        • 11.4.1 Code generation

        • 11.4.2 Per-class versus single-file generation

        • 11.4.3 Filtering classes processed

      • 11.5 Advanced XDoclet

        • 11.5.1 Custom subtasks

        • 11.5.2 Creating a custom tag handler

      • 11.6 The direction of XDoclet

        • 11.6.1 XDoclet versus C#

        • 11.6.2 Looking into Java’s future: JSR 175 and 181

      • 11.7 XDoclet best practices

        • 11.7.1 Dependency checking

      • 11.8 Summary

    • chapter12

      • 12.1 How are web applications different?

      • 12.2 Working with tag libraries

        • 12.2.1 Creating a tag library

        • 12.2.2 Integrating tag libraries

        • 12.2.3 Summary of taglib development with Ant

      • 12.3 Compiling JSP pages

        • 12.3.1 Installing the <jspc> task

        • 12.3.2 Using the <jspc> task

        • 12.3.3 JSP compilation for deployment

        • 12.3.4 Other JSP compilation tasks

      • 12.4 Customizing web applications

        • 12.4.1 Filterset-based customization

        • 12.4.2 Customizing deployment descriptors with XDoclet

        • 12.4.3 Customizing libraries in the WAR file

      • 12.5 Generating static content

        • 12.5.1 Generating new content

        • 12.5.2 Creating new files

        • 12.5.3 Modifying existing files

      • 12.6 Testing web applications with HttpUnit

        • 12.6.1 Writing HttpUnit tests

        • 12.6.2 Compiling the tests

        • 12.6.3 Preparing to run HttpUnit tests from Ant

        • 12.6.4 Running the HttpUnit tests

        • 12.6.5 Integrating the tests

        • 12.6.6 Limitations of HttpUnit

        • 12.6.7 Canoo WebTest

      • 12.7 Server-side testing with Cactus

        • 12.7.1 Cactus from Ant’s perspective

        • 12.7.2 How Cactus works

        • 12.7.3 And now our test case

        • 12.7.4 Cactus summary

      • 12.8 Summary

    • chapter13

      • 13.1 Preamble: all about XML libraries

      • 13.2 Validating XML

        • 13.2.1 When a file isn’t validated

        • 13.2.2 Resolving XML DTDs

        • 13.2.3 Supporting alternative XML validation mechanisms

      • 13.3 Transforming XML with XSLT

        • 13.3.1 Using the XMLCatalog datatype

        • 13.3.2 Generating PDF files from XML source

        • 13.3.3 Styler–a third-party transformation task

      • 13.4 Generating an XML build log

        • 13.4.1 Stylesheets

        • 13.4.2 Output files

        • 13.4.3 Postprocessing the build log

      • 13.5 Loading XML data into Antproperties

      • 13.6 Next steps in XML processing

      • 13.7 Summary

    • chapter14

      • 14.1 EJB overview

        • 14.1.1 The many types of Enterprise JavaBeans

        • 14.1.2 EJB JAR

        • 14.1.3 Vendor-specific situations

      • 14.2 A simple EJB build

      • 14.3 Using Ant’s EJB tasks

      • 14.4 Using <ejbjar>

        • 14.4.1 Vendor-specific <ejbjar> processing

      • 14.5 Using XDoclet for EJB development

        • 14.5.1 XDoclet subtasks

        • 14.5.2 XDoclet’s @tags

        • 14.5.3 Supporting different application servers with XDoclet

        • 14.5.4 Ant property substitution

      • 14.6 Middlegen

      • 14.7 Deploying to J2EE application servers

      • 14.8 A complete EJB example

      • 14.9 Best practices in EJB projects

      • 14.10 Summary

    • chapter15

      • 15.1 What are web services and what is SOAP?

        • 15.1.1 The SOAP API

        • 15.1.2 Adding web services to Java

      • 15.2 Creating a SOAP client application with Ant

        • 15.2.1 Preparing our build file

        • 15.2.2 Creating the proxy classes

        • 15.2.3 Using the SOAP proxy classes

        • 15.2.4 Compiling the SOAP client

        • 15.2.5 Running the SOAP service

        • 15.2.6 Reviewing SOAP client creation

      • 15.3 Creating a SOAP service with Axisand Ant

        • 15.3.1 The simple way to build a web service

      • 15.4 Adding web services to an existing webapplication

        • 15.4.1 Configuring the web application

        • 15.4.2 Adding the libraries

        • 15.4.3 Including SOAP services in the build

        • 15.4.4 Testing the server for needed classes

        • 15.4.5 Implementing the SOAP endpoint

        • 15.4.6 Deploying our web service

      • 15.5 Writing a client for our SOAPservice

        • 15.5.1 Importing the WSDL

        • 15.5.2 Implementing the tests

        • 15.5.3 Writing the Java client

      • 15.6 What is interoperability, and why is it a problem?

      • 15.7 Building a C# client

        • 15.7.1 Probing for the classes

        • 15.7.2 Importing the WSDL in C#

        • 15.7.3 Writing the C# client class

        • 15.7.4 Building the C# client

        • 15.7.5 Running the C# client

        • 15.7.6 Review of the C# client build process

      • 15.8 The rigorous way to build a webservice

      • 15.9 Reviewing web service development

      • 15.10 Calling Ant via SOAP

      • 15.11 Summary

    • chapter16

      • 16.1 Scheduling Ant builds with the operating system

        • 16.1.1 The Windows way

        • 16.1.2 The Unix version

        • 16.1.3 Making use of scripting

      • 16.2 CruiseControl

        • 16.2.1 How it works

        • 16.2.2 It’s all about the cruise—getting the build runner working

        • 16.2.3 Build log reporting

        • 16.2.4 Email notifications and build labeling

        • 16.2.5 CruiseControl summary

        • 16.2.6 Tips and tricks

        • 16.2.7 Pros and cons to CruiseControl

      • 16.3 Anthill

        • 16.3.1 Getting Anthill working

        • 16.3.2 How Anthill works

        • 16.3.3 Anthill summary

      • 16.4 Gump

        • 16.4.1 Installing and running Gump

        • 16.4.2 How Gump works

        • 16.4.3 Summary of Gump

      • 16.5 Comparison of continuous integration tools

      • 16.6 Summary

    • chapter17

      • 17.1 The challenge of native code

      • 17.2 Using existing build tools

        • 17.2.1 Delegating to an IDE

        • 17.2.2 Using Make

      • 17.3 Introducing the <cc> task

        • 17.3.1 Installing the tasks

        • 17.3.2 Adding a compiler

        • 17.3.3 A quick introduction to the <cc> task

      • 17.4 Building a JNI library in Ant

        • 17.4.1 Steps to building a JNI library

        • 17.4.2 Writing the Java stub

        • 17.4.3 Writing the C++ class

        • 17.4.4 Compiling the C++ source

        • 17.4.5 Deploying and testing the library

      • 17.5 Going cross-platform

        • 17.5.1 Migrating the C++ source

        • 17.5.2 Extending the build file

        • 17.5.3 Testing the migration

        • 17.5.4 Porting the code

      • 17.6 Looking at <cc> in more detail

        • 17.6.1 Defining preprocessor macros

        • 17.6.2 Linking to libraries with <libset>

        • 17.6.3 Configuring compilers and linkers

        • 17.6.4 Customizing linkers

      • 17.7 Distributing native libraries

      • 17.8 Summary

    • chapter18

      • 18.1 The challenge of different application servers

        • 18.1.1 Fundamentally different underlying behaviors

        • 18.1.2 Different Java run-time behavior

        • 18.1.3 Coping with different API implementations

        • 18.1.4 Vendor-specific libraries

        • 18.1.5 Deployment descriptors

        • 18.1.6 Server-specific deployment processes

        • 18.1.7 Server-specific management

      • 18.2 Working with operations

        • 18.2.1 Operations use cases

        • 18.2.2 Operations tests

        • 18.2.3 Operations defect tracking

        • 18.2.4 Integrating operations with the build process

      • 18.3 Addressing the deployment challenge with Ant

        • 18.3.1 Have a single source tree

        • 18.3.2 Have a unified target for creating the archive files

        • 18.3.3 Run Ant server-side to deploy

        • 18.3.4 Automate the upload and deployment process

      • 18.4 Introducing Ant’s deployment power tools

        • 18.4.1 The <copy> task

        • 18.4.2 The <serverdeploy> task

        • 18.4.3 Remote control with <telnet>

      • 18.5 Building a production deployment process

        • 18.5.1 The plan

        • 18.5.2 The directory structure

        • 18.5.3 The configuration files

        • 18.5.4 The build files

        • 18.5.5 The remote build.xml build file

        • 18.5.6 Writing the build file for installing to a server

        • 18.5.7 Uploading to the remote server

        • 18.5.8 The remote deployment in action

        • 18.5.9 Reviewing the deployment process

      • 18.6 Deploying to specific application servers

        • 18.6.1 Tomcat 4.0 and 4.1

        • 18.6.2 BEA WebLogic

        • 18.6.3 HP Bluestone application server

        • 18.6.4 Other servers

      • 18.7 Verifying deployment

        • 18.7.1 Creating the timestamp file

        • 18.7.2 Adding the timestamp file to the application

        • 18.7.3 Testing the timestamp

      • 18.8 Best practices

      • 18.9 Summary

    • chapter19

      • 19.1 What exactly is an Ant task?

        • 19.1.1 The world’s simplest Ant task

        • 19.1.2 Compiling and using a task in the same build

        • 19.1.3 Task lifecycle

      • 19.2 Ant API primer

        • 19.2.1 Task

        • 19.2.2 Project

        • 19.2.3 Path

        • 19.2.4 FileSet

        • 19.2.5 DirectoryScanner

        • 19.2.6 EnumeratedAttribute

        • 19.2.7 FileUtils

      • 19.3 How tasks get data

        • 19.3.1 Setting attributes

        • 19.3.2 Supporting nested elements

        • 19.3.3 Supporting datatypes

        • 19.3.4 Allowing free-form body text

      • 19.4 Creating a basic Ant Task subclass

        • 19.4.1 Adding an attribute to a task

        • 19.4.2 Handling element text

      • 19.5 Operating on a fileset

      • 19.6 Error handling

      • 19.7 Testing Ant tasks

      • 19.8 Executing external programs

        • 19.8.1 Dealing with process output

        • 19.8.2 Summary of native execution

      • 19.9 Executing a Java program withinatask

        • 19.9.1 Example task to execute a forked Java program

      • 19.10 Supporting arbitrarily named elements and attributes

      • 19.11 Building a task library

      • 19.12 Supporting multiple versionsofAnt

      • 19.13 Summary

    • chapter20

      • 20.1 Scripting within Ant

        • 20.1.1 Implicit objects provided to <script>

        • 20.1.2 Scripting summary

      • 20.2 Listeners and loggers

        • 20.2.1 Writing a custom listener

        • 20.2.2 Using Log4j logging capabilities

        • 20.2.3 Writing a custom logger

        • 20.2.4 Using the MailLogger

      • 20.3 Developing a custom mapper

      • 20.4 Creating custom selectors

        • 20.4.1 Using a custom selector in a build

      • 20.5 Implementing a custom filter

        • 20.5.1 Coding a custom filter reader

      • 20.6 Summary

    • appendixa

    • appendixb

    • appendixc

    • appendixd

    • appendixe

      • index

    • Resources

    • index

Nội dung

STEP FOUR: IMPOSING STRUCTURE 35 2.5.4 Creating the build file Now that we have the files in the right places, and we know what we want to do, the build file needs to be rewritten. Rather than glue all the tasks together in one long list of actions, we have broken the separate stages—directory creation, compilation, packaging, and cleanup—into four separate targets inside the build file. <?xml version="1.0" ?> <project name="structured" default="archive" > <target name="init"> <mkdir dir="build/classes" /> <mkdir dir="dist" /> </target> <target name="compile" depends="init" > <javac srcdir="src" destdir="build/classes" /> </target> <target name="archive" depends="compile" > <jar destfile="dist/project.jar" basedir="build/classes" /> </target> <target name="clean" depends="init"> <delete dir="build" /> <delete dir="dist" /> </target> </project> This build file adds an init target to do initialization work, which means creating directories. We’ve also added two other new targets, clean and archive. The archive target uses the <jar> task to create the JAR file containing all files in and below the build/classes directory, which in this case means all .class files created by the compile target. One target has a dependency upon another, a dependency that Ant needs to know about. The clean target cleans up the output directories by deleting them. It uses the <delete> task to do this. We have also changed the default target to archive, so this will be the target that Ant executes when you run it. 2.5.5 Target dependencies We need a way of ensuring that Ant runs some targets before other targets that depend on their outputs. In our current project, for the archive to be up to date, all the source files must be compiled, which means the archive target must come after the compilation target. Likewise, compile needs the directories created in init, so Ant must execute it after the init task. These are dependencies that we need to communicate to Ant. We do this as the targets are declared, listing the dependencies in their depends attributes: Creates the output directories Compiles into the output directories Creates the archive Cleans the output directories Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 36 CHAPTER 2 GETTING STARTED WITH ANT <target name="compile" depends="init" > <target name="archive" depends="compile" > <target name="clean" depends="init"> If a target directly depends on more than one predecessor target, then you should list both dependencies in the dependency attribute, for example depends="com- pile,test" . In our example build, the archive task does depend upon both init and compile, but we do not bother to state the dependency upon init because the compile target depends upon it. If Ant must execute init before compile, and archive depends upon compile then Ant must run init before archive. Put formally, dependencies are transitive. They are not however reflexive: the compile target does not know or care about the archive target. Another useful fact is that the order of targets inside the build file is not important: Ant reads in the whole file before it builds the dependency tree and executes targets. There is no need to worry about forward references. If you look at the dependency tree of targets in the current example, it looks like figure 2.3. Before Ant executes any target, all the predecessor targets must already have been executed. If these predecessors depend on targets themselves, the execution order will also consider those and produce an order that satisfies all dependencies. If two tar- gets in this execution order share a common dependency, then that predecessor will only execute once. Experienced makefile editors will recognize that Ant targets resemble Make’s pseudotargets—targets in a makefile that you refer to by name in the dependencies of other makefile targets. Usually in Make, you name the source files that a target depends on, and the build tool itself works out what to do to create the target file from the source files. In Ant, you name stages of work as targets, and the tasks inside each target work out for themselves what their dependencies are. 2.5.6 Running the new build file Now that there are multiple targets in the build file, we need a way of specifying which to run. You can simply list one or more targets on the command line, so all of the following are valid, as are other combinations: ant ant init ant clean init cleancompile archive Figure 2.3 Once you add dependencies, the graph of targets gets more complex. Here clean depends upon init; archive depends on compile directly and init indirectly. All of a target’s dependencies will be executed ahead of the target itself. Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com STEP FOUR: IMPOSING STRUCTURE 37 ant compile ant archive ant clean archive Calling Ant with no target is the same as calling the default target named in the project. In this example, it is the archive target: init: [mkdir] Created dir: C:\AntBook\secondbuild\build [mkdir] Created dir: C:\AntBook\secondbuild\dist compile: [javac] Compiling 1 source file to C:\AntBook\secondbuild\build archive: [jar] Building jar: C:\AntBook\secondbuild\dist\project.jar BUILD SUCCESSFUL Total time: 2 seconds This demonstrates that Ant has determined execution order of tasks. When you invoke a target with dependencies, all their dependencies execute first. As both the compile and archive targets depend upon the init target, Ant must call init before it executes either of those targets. It orders the targets so that first the directo- ries get created, then the source compiled, and finally the JAR archive built. 2.5.7 Rerunning the build What happens when the build is run a second time? Let’s try it and see: init: compile: archive: BUILD SUCCESSFUL Total time: 1 second We go through all the targets, but none of the tasks say that they are doing any work. Here’s why: all of these tasks check their dependencies, <mkdir> does not create directories that already exist, <javac> compares source and class file timestamps, and the <jar> task compares the time of all files to be added to the archive with the time of the file itself. Only if a source file is newer than the generated archive file does the task rebuild the JAR file. If you add the -verbose flag to the command line you will get more detail on what did or, in this case, did not take place. >ant -verbose Apache Ant version 1.5alpha compiled on February 1 2002 Buildfile: build.xml Detected Java version: 1.3 in: D:\Java\jdk13\jre Detected OS: Windows 2000 parsing buildfile C:\AntBook\secondbuild\build.xml with Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 38 CHAPTER 2 GETTING STARTED WITH ANT URI = file:C:/AntBook/secondbuild/build.xml Project base dir set to: C:\AntBook\secondbuild Build sequence for target `archive’ is [init, compile, archive] Complete build sequence is [init, compile, archive, clean] init: compile: [javac] org\example\antbook\lesson1\Main.java omitted as C:\AntBook\secondbuild\build\org\example\antbook\ lesson1\Main.class is up to date. archive: [jar] org\example\antbook\lesson1\Main.class omitted as C:\AntBook\secondbuild\dist\project.jar is up to date. BUILD SUCCESSFUL Total time: 2 seconds The verbose run provides a lot of information, much of which may seem distracting. When a build is working well, you do not need it, but it is invaluable while develop- ing that file. TIP If ever you are unsure why a build is not behaving as expected, run Ant with the - verbose option to get lots more information. 2.5.8 How Ant handles multiple targets on the command line Here is an interesting question which expert users of Make will usually get wrong: what happens when you type ant compile archive at the command line? Many people would expect Ant to pick an order that executes each target and its dependen- cies once only: init, compile, archive. Make would certainly do that, but Ant does not. Instead, it executes each target and dependents in turn, so the actual sequence is init, compile, then init, compile, archive: C:\AntBook\secondbuild>ant compile archive Buildfile: build.xml init: [mkdir] Created dir: C:\AntBook\secondbuild\build [mkdir] Created dir: C:\AntBook\secondbuild\dist compile: [javac] Compiling 1 source file to C:\AntBook\secondbuild\build init: compile: archive: [jar] Building jar: C:\AntBook\secondbuild\dist\project.jar BUILD SUCCESSFUL Total time: 2 seconds This behavior can be unexpected to anyone experienced in other build tools, as it seems to add extra work rather than save work by sharing dependencies. However, if you Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com STEP FIVE: RUNNING OUR PROGRAM 39 look closely, the second time Ant executes the compile target it does no work; the tasks get executed but their dependency checking stops existing outputs being rebuilt. Our next question is this: when a target lists multiple dependencies, does Ant exe- cute them in the order listed? The answer is yes, unless other dependency rules prevent it. Imagine if we modified the archive target with the dependency attribute depends="compile,init". A simple left-to-right execution order would run the compile target before it was initialized. Ant would try to execute the targets in this order, but because the compile target depends upon init, Ant will call init first. This subtle detail can catch you out. If you try to control the execution order by listing targets in order, you may not get the results you expect as explicit dependencies always take priority. 2.6 STEP FIVE: RUNNING OUR PROGRAM We now have a structured build process that creates the JAR file from the Java source. At this point the next steps could be to run tests on the code, distribute it, or deploy it. We shall be covering how to do all these things in the following chapters. For now, we just want to run the program. 2.6.1 Why execute from inside Ant We could just call our program from the command line, stating the classpath, the name of the entry point and the arguments: >java -cp build/classes org.example.antbook.lesson1.Main a b . a b . If the classpath is not complex and the arguments to the application are simple, call- ing Java programs from the command line is not particularly hard, just a manual pro- cess. We still want to run our program from the build file, not just to show it is possible, but because it provides some tangible benefits the moment we do so: • A target to run the program can depend upon the compilation target, so we know we are always running the latest version of the code. • It is easy to pass complex arguments to the program. • It is easier to set up the classpath. • The program can run inside Ant’s own JVM; so it loads faster. • You can halt a build if the return code of the program is not zero. The fact that the execute target can be made to depend on the compile target is one of the key benefits during development. There is simply no need to split program compilation from execution. Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 40 CHAPTER 2 GETTING STARTED WITH ANT 2.6.2 Adding an execute target To call the program from inside Ant, we merely add a new target, execute, which we make dependent upon compile. It contains one task, <java>, that runs our Main.class using the interim build/classes directory tree as our classpath: <target name="execute" depends="compile"> <java classname="org.example.antbook.lesson1.Main" classpath="build/classes"> <arg value="a"/> <arg value="b"/> <arg file="."/> </java> </target> We have three <arg> tags inside the <java> task; each tag contains one of the argu- ments to the program: "a", "b", and ".", as with the command line version. Note, however, that the final argument, <arg file="."/>, is different from the other two. The first two arguments use the value attribute of the <arg> tag, which passes the value straight down to the program. The final argument uses the file attribute, which tells Ant to resolve that attribute to an absolute file location before calling the program. 2.6.3 Running the new target What does the output of the run look like? First, let’s it run it on Windows: C:\AntBook\secondbuild>ant execute Buildfile: build.xml init: compile: execute: [java] a [java] b [java] C:\AntBook\secondbuild The compile task didn’t need to do any recompilation, and the execute task called our program. Ant has prefixed every line of output with the name of the task currently running, showing here that this is the output of an invoked Java applica- tion. The first two arguments went straight to our application, while the third argu- ment was resolved to the current directory; Ant turned "." into an absolute file reference. Next, let’s try the same program on Linux: [secondbuild]$ ant execute Buildfile: build.xml init: compile: execute: [java] a [java] b [java] /home/ant/Projects/secondbuild Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com ANT COMMAND LINE OPTIONS 41 Everything is identical, apart from the final argument, which has been resolved to a dif- ferent location, the current directory in the Unix path syntax, rather than the DOS one. This shows another benefit of starting programs from Ant rather than any batch file or shell script: a single build file can start the same program on multiple platforms, trans- forming file names and file paths into the appropriate values for the target platform. This is a very brief demonstration of how and why to call programs from inside Ant; enough to round off this little project. We have dedicated an entire chapter to the subject of calling Java and native programs from Ant during a build process. Chapter 5 explores the options and issues of the topic in detail. 2.7 ANT COMMAND LINE OPTIONS We have nearly finished our quick look at some of what Ant can do, but we have one more little foundational topic to cover: how to call Ant. We have already shown that Ant is a command-line program, and that you can specify multiple targets as parame- ters, and we have introduced the - verbose option to get more information on a build. We want to do some more with Ant’s command line to run our program. First, we want to remove the [java] prefixes, then we will run the build without any out- put at all unless something goes wrong. Ant command line options can do this. Ant can take a number of options, which it lists if you ask for them with ant -help . The current set of options is listed in table 2.2. Table 2.2 Ant command line options Option Meaning -help List the options Ant supports and exit -version Print the version information and exit -buildfile file Use the named buildfile, use -f as a shortcut -find file Search for the named buildfile up the tree -projecthelp Print information about the current project -verbose Be extra verbose -quiet Be extra quiet -debug Print debugging information -emacs Produce logging information without adornments -Dproperty=value Set a property to a value -propertyfile file Load all properties from file -logfile file Use given file for log -listener classname Add a project listener -logger classname Name a different logger -inputhandler classname The name of a class to respond to <input> requests -diagnostics Print information that might be helpful to diagnose or report problems. Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 42 CHAPTER 2 GETTING STARTED WITH ANT Some options require more explanation of Ant before they make sense. In particular, the two options related to properties are not relevant until we explore Ant’s properties in chapter 3. Likewise, we don’t introduce listeners and loggers until chapter 13, so let’s ignore those options for now. Just keep in mind that it is possible to write Java classes that get told when targets are executed, or that get fed all the output from the tasks as they execute, a feature that is the basis for integrating Ant into IDEs. 2.7.1 Specifying which build file to run Perhaps the most important option for Ant is -buildfile. This option lets you control which build file Ant uses, allowing you to divide the targets of a project into multiple files, and select the appropriate build file depending on your actions. Ashortcut to - buildfile is -f. To invoke our existing project, we just name it im- mediately after the - f or -buildfile argument: ant -buildfile build.xml compile This is exactly equivalent to calling ant compile with no file specified. If for some reason the current directory was somewhere in the source tree, which is sometimes the case when you are editing text from a console application such as vi, emacs, or even edit, then you can refer to a build file by passing in the appropriate relative file name for your platform, such as / / /build.xml or \ \ \build.xml . This is fiddly. It is better to use the -find option, which must be followed by the name of a build file. This variant does something very special: it searches up the directory tree to find the first build file in a parent directory of that name, and invokes it. With this option, when you are deep down the source tree editing files, you can easily invoke the project build with the simple command: ant -find build.xml 2.7.2 Controlling the amount of information provided We stated that we want to reduce the amount of information provided when we invoke Ant. Getting rid of the [java] prefix is easy: we run the build file with the - emacs option; this omits the task-name prefix from all lines printed. The option is called - emacs because the output is now in the emacs format for invoked tools, which enables that and other editors to locate the lines on which errors occurred. When calling Ant from any IDE that lacks built-in support, the - emacs option may tighten the integration. For our exercise, we only want to change the presentation from the command line, which is simple enough: [secondbuild]$ ant -emacs execute Buildfile: build.xml init: compile: execute: Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com ANT COMMAND LINE OPTIONS 43 a b /home/ant/Projects/secondbuild BUILD SUCCESSFUL Total time: 2 seconds. This leaves the next half of the problem, hiding all the output entirely. Three of the Ant options control how much information is output when Ant runs. Two of these (- verbose and -debug) progressively increase the amount. The verbose option is useful when you are curious about how Ant works, or why a build isn’t behaving. The debug option includes all the normal and verbose output, and much more low level information, primarily only of interest to Ant developers. The - quiet option reduces the amount of information to a success message or errors: [secondbuild]$ ant -quiet execute BUILD SUCCESSFUL Total time: 2 seconds This leaves us with no way of telling if the program worked, unless we can infer it from the time to execute. Would adding an <echo> statement in the execute tar- get help? Not by default. One of the attributes of echo is the level attribute: error, warning, info, verbose, and debug control the amount of information that appears. The default value info ensures that echoed messages appear in normal builds, or the two levels of even more information, verbose and debug. By insert- ing an echo statement into our execute target with the level set to warning, we ensure that even when the build is running in quiet mode the output appears. The Ant task declaration <echo level="warning" message="running" /> results in the following output: >ant -quiet [echo] running To eliminate the [echo] prefix, we add the -emacs option again, calling >ant -quiet -emacs to get the following output: running BUILD SUCCESSFUL Total time: 2 seconds. Controlling the output level of programs is not only useful when debugging, but when trying to run a large build that has worked in the past; only errors and occa- sional progress messages matter. A quiet build with a few manual <echo level= "warning"> tags is ideal for a bulk build. Likewise, some <echo level="verbose"> tags can provide extra trace information when more detail is required. Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 44 CHAPTER 2 GETTING STARTED WITH ANT 2.7.3 Getting information about a project The final option of immediate relevance is -projecthelp. It lists the main targets in a project, and is invaluable whenever you need to know what targets a build file provides. Ant only lists targets containing the optional description attribute, as these are the targets intended for public consumption. >ant -projecthelp Buildfile: build.xml Main targets: Subtargets: archive clean compile execute init Default target: archive This is not very informative, which is our fault for not documenting the file thor- oughly enough. If we add a description attribute to each target, such as description="Compiles the source code" for the compile target, and a <description> tag right after the project declaration, then the target listing includes these descriptions, marks all the described targets as “main targets,” and hides all sub targets from view: Buildfile: build.xml Compiles and runs a simple program Main targets: archive Creates the JAR file clean Removes the temporary directories used compile Compiles the source code execute Runs the program Default target: archive To see both main and sub targets in a project, you must call Ant with the options - projecthelp and -verbose. The more complex a project is, the more useful the - projecthelp feature becomes. We strongly recommend providing description strings for every target intended to act as an entry point to external callers, and a line or two at the top of each build file describing what it does. 2.8 THE FINAL BUILD FILE We close with the complete listing of the final build file, listing 2.1. As well as adding the description tags, we decided to change the default target to run the program, rather than just create the archive. We have marked the major changes in bold, to show where this build file differs from the build files and build file fragments shown earlier. Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com [...]... Sun’s JDK 1.3.1 javac compiler, the following command line is used: javac -d build\classes -classpath lib\lucene-1 .2- rc3\lucene-1 .2- rc3.jar; lib\jtidy-04aug2000r7-dev\build\Tidy.jar; C:\AntBook\jakarta -ant- 1.5\lib \ant. jar; -sourcepath src -g src\org\example\antbook \ant\ lucene\* .java The following Java compilation with Ant, utilizing Ant s datatypes and properties, shows the equivalent Ant task declaration... message= "ant. home = $ {ant. home}"/> This generates output similar to this: echo: [echo] [echo] [echo] [echo] [echo] 66 ant. file = C:\AntBook\Sections\Learning\datatypes\properties.xml ant. home = c:\AntBook\jakarta -ant- 1.5Beta1 ant .java. version = 1.3 ant. version... can do 46 CHAPTER 2 GETTING STARTED WITH ANT Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com C H A P T E R 3 Understanding Ant datatypes and properties 3.1 3 .2 3.3 3.4 3.5 3.6 3.7 3.8 Preliminaries 48 Introducing datatypes and properties with 49 Paths 51 Filesets 52 Patternsets 54 Selectors 56 Datatype element naming 57 Filterset 58 3.9 3.10 3.11 3. 12 3.13 3.14 3.15... constant: package org.example.antbook; public interface Constants { public static final String VERSION ="1.7"; } Our build compiles the code into the build directory Using the and FilterReaders in a task, we can now give Ant access to the VERSION constant ... similar conceptually to java util.Properties Ant provides the built-in properties listed in table 3.7 Table 3.7 Built-in properties Name Definition ant. file The absolute path of the build file ant. home The path to executing version of Ant s root directory ant .java. version The JVM version Ant detected; currently it can hold the values 1.1, 1 .2, 1.3, and 1.4 ant. project.name The name of the project that... interface The task is the common interface to JDK 1.1 and up, Jikes, and several other Java compilers There is much more to Java compilation than just specifying a source directory and destination directory A comparison of Sun’s JDK 1.3.1 javac command-line compiler switches to Ant s task is shown in table 3.1 Table 3.1 Sun’s JDK 1.3.1 javac compared to Ant s wrapper task Note... concepts natively You can think of an Ant datatype as similar to Java s own built-in core classes: data that can be passed around and provided to tasks The fileset and path datatypes, and several others, form the basic building blocks of Ant build files Classpath-related headaches are commonplace in Java development Ant makes dealing with classpaths much more natural and pleasant than the command-line manual... important to note that Ant guarantees no order within a Each element in a path is ordered from the top and down so that all files within a fileset would be grouped together in a path However, the order within that fileset is not guaranteed 3.4 FILESETS Implicitly, all build processes will operate on sets of files, either to compile, copy, delete, or operate on them in any number of other ways Ant. .. defined once for compilation with , and reused for execution (via , covered in chapter 5) One of the consequences of classpaths being specified inside the build file is that Ant can be invoked without an explicitly defined system classpath, making it easy to install Ant and build a project with little or no environmental configuration.1 Another no less important consequence is that classpaths... Assume that there is a single file in the data directory called data _20 020 2 02. dat, yet this file name is dynamically generated The use of the merge mapper will copy it to the output directory with the name data.dat This particular technique, remember, is only useful with filesets containing a single file 62 CHAPTER 3 UNDERSTANDING ANT DATATYPES AND PROPERTIES Simpo PDF Merge and Split Unregistered Version . C:AntBookjakarta -ant- 1.5lib ant. jar; -sourcepath src -g srcorgexampleantbook ant lucene* .java The following Java compilation with Ant, utilizing Ant s datatypes and properties, shows the equivalent Ant task. options can do this. Ant can take a number of options, which it lists if you ask for them with ant -help . The current set of options is listed in table 2. 2. Table 2. 2 Ant command line options Option. place. > ;ant -verbose Apache Ant version 1.5alpha compiled on February 1 20 02 Buildfile: build.xml Detected Java version: 1.3 in: D: Java jdk13jre Detected OS: Windows 20 00 parsing buildfile C:AntBooksecondbuilduild.xml

Ngày đăng: 13/08/2014, 22:21

TỪ KHÓA LIÊN QUAN

w