junhong

how to use ant to deply your web application


First of all, if you develop your application by Eclipse, it means you have had the ant tool and you need not to download the internet.

Projects

A project has three attributes:

Attribute Description Required
name the name of the project. No
default the default target to use when no target is supplied. No; however, since Ant 1.6.0, every project includes an implicit target that contains any and all top-level tasks and/or types. This target will always be executed as part of the project's initialization, even when Ant is run with the -projecthelp option.
basedir the base directory from which all path calculations are done. This attribute might be overridden by setting the "basedir" property beforehand. When this is done, it must be omitted in the project tag. If neither the attribute nor the property have been set, the parent directory of the buildfile will be used. No

Optionally, a description for the project can be provided as a top-level <description> element (see the description type).

Each project defines one or more targets. A target is a set of tasks you want to be executed. When starting Ant, you can select which target(s) you want to have executed. When no target is given, the project's default is used.

Targets

A target can depend on other targets. You might have a target for compiling, for example, and a target for creating a distributable. You can only build a distributable when you have compiled first, so the distribute target depends on the compile target. Ant resolves these dependencies.

It should be noted, however, that Ant's depends attribute only specifies the order in which targets should be executed - it does not affect whether the target that specifies the dependency(s) gets executed if the dependent target(s) did not (need to) run.

Ant tries to execute the targets in the depends attribute in the order they appear (from left to right). Keep in mind that it is possible that a target can get executed earlier when an earlier target depends on it:

						
								<target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>

Suppose we want to execute target D. From its depends attribute, you might think that first target C, then B and then A is executed. Wrong! C depends on B, and B depends on A, so first A is executed, then B, then C, and finally D.

In a chain of dependencies stretching back from a given target such as D above, each target gets executed only once, even when more than one target depends on it. Thus, executing the D target will first result in C being called, which in turn will first call B, which in turn will first call A. After A, then B, then C have executed, execution returns to the dependency list of D, which will not call B and A, since they were already called in process of dependency resolution for C and B respectively as dependencies of D. Had no such dependencies been discovered in processing C and B, B and A would have been executed after C in processing D's dependency list.

A target also has the ability to perform its execution if (or unless) a property has been set. This allows, for example, better control on the building process depending on the state of the system (java version, OS, command-line property defines, etc.). To make a target sense this property, you should add the if (or unless) attribute with the name of the property that the target should react to. Note: Ant will only check whether the property has been set, the value doesn't matter. A property set to the empty string is still an existing property. For example:

						
								<target name="build-module-A" if="module-A-present"/>
						
				
						
								<target name="build-own-fake-module-A" unless="module-A-present"/>
						
				

In the first example, if the module-A-present property is set (to any value), the target will be run. In the second example, if the module-A-present property is set (again, to any value), the target will not be run.

If no if and no unless attribute is present, the target will always be executed.

Important: the if and unless attributes only enable or disable the target to which they are attached. They do not control whether or not targets that a conditional target depends upon get executed. In fact, they do not even get evaluated until the target is about to be executed, and all its predecessors have already run.

The optional description attribute can be used to provide a one-line description of this target, which is printed by the -projecthelp command-line option. Targets without such a description are deemed internal and will not be listed, unless either the -verbose or -debug option is used.

It is a good practice to place your tstamp tasks in a so-called initialization target, on which all other targets depend. Make sure that target is always the first one in the depends list of the other targets. In this manual, most initialization targets have the name "init".

If the depends attribute and the if/unless attribute are set, the depends attribute is executed first.

A target has the following attributes:

Attribute Description Required
name the name of the target. Yes
depends a comma-separated list of names of targets on which this target depends. No
if the name of the property that must be set in order for this target to execute. No
unless the name of the property that must not be set in order for this target to execute. No
description a short description of this target's function. No

A target name can be any alphanumeric string valid in the encoding of the XML file. The empty string "" is in this set, as is comma "," and space " ". Please avoid using these, as they will not be supported in future Ant versions because of all the confusion they cause. IDE support of unusual target names, or any target name containing spaces, varies with the IDE.

Targets beginning with a hyphen such as "-restart" are valid, and can be used to name targets that should not be called directly from the command line.

Tasks

A task is a piece of code that can be executed.

A task can have multiple attributes (or arguments, if you prefer). The value of an attribute might contain references to a property. These references will be resolved before the task is executed.

Tasks have a common structure:

						
								<nameattribute1="value1" attribute2="value2" ... />
						
				

where name is the name of the task, attributeN is the attribute name, and valueN is the value for this attribute.

There is a set of built-in tasks , along with a number of optional tasks , but it is also very easy to write your own .

All tasks share a task name attribute. The value of this attribute will be used in the logging messages generated by Ant.

Tasks can be assigned an id attribute:

						
								<taskname id="taskID" ... />
						
				

where taskname is the name of the task, and taskID is a unique identifier for this task. You can refer to the corresponding task object in scripts or other tasks via this name. For example, in scripts you could do:

						
								<script ... >
task1.setFoo("bar");
</script>

to set the foo attribute of this particular task instance. In another task (written in Java), you can access the instance via project.getReference("task1").

Note1: If "task1" has not been run yet, then it has not been configured (ie., no attributes have been set), and if it is going to be configured later, anything you've done to the instance may be overwritten.

Note2: Future versions of Ant will most likely not be backward-compatible with this behaviour, since there will likely be no task instances at all, only proxies.

Properties

A project can have a set of properties. These might be set in the buildfile by the property task, or might be set outside Ant. A property has a name and a value; the name is case-sensitive. Properties may be used in the value of task attributes. This is done by placing the property name between "${" and "}" in the attribute value. For example, if there is a "builddir" property with the value "build", then this could be used in an attribute like this: ${builddir}/classes. This is resolved at run-time as build/classes.

Built-in Properties

Ant provides access to all system properties as if they had been defined using a <property> task. For example, ${os.name} expands to the name of the operating system.

For a list of system properties see the Javadoc of System.getProperties .

In addition, Ant has some built-in properties:

				
						basedir             the absolute path of the project's basedir (as set
with the basedir attribute of <project>).
ant.file the absolute path of the buildfile.
ant.version the version of Ant
ant.project.name the name of the project that is currently executing;
it is set in the name attribute of <project>.
ant.java.version the JVM version Ant detected; currently it can hold
the values "1.1", "1.2", "1.3", "1.4" and "1.5".

Example Buildfile

				
						<project name="MyProject" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>

<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>

<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>

<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>

<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>

<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>

Notice that we are declaring properties outside any target. As of Ant 1.6 all tasks can be declared outside targets (earlier version only allowed <property>,<typedef> and <taskdef>). When you do this they are evaluated before any targets are executed. Some tasks will generate build failures if they are used outside of targets as they may cause infinite loops otherwise (<antcall> for example).

We have given some targets descriptions; this causes the projecthelp invocation option to list them as public targets with the descriptions; the other target is internal and not listed.

Finally, for this target to work the source in the src subdirectory should be stored in a directory tree which matches the package names. Check the <javac> task for details.

Token Filters

A project can have a set of tokens that might be automatically expanded if found when a file is copied, when the filtering-copy behavior is selected in the tasks that support this. These might be set in the buildfile by the filter task.

Since this can potentially be a very harmful behavior, the tokens in the files must be of the form @token@, where token is the token name that is set in the <filter> task. This token syntax matches the syntax of other build systems that perform such filtering and remains sufficiently orthogonal to most programming and scripting languages, as well as with documentation systems.

Note: If a token with the format @token@ is found in a file, but no filter is associated with that token, no changes take place; therefore, no escaping method is available - but as long as you choose appropriate names for your tokens, this should not cause problems.

Warning: If you copy binary files with filtering turned on, you can corrupt the files. This feature should be used with text files only.

Path-like Structures

You can specify PATH- and CLASSPATH-type references using both ":" and ";" as separator characters. Ant will convert the separator to the correct character of the current operating system.

Wherever path-like values need to be specified, a nested element can be used. This takes the general form of:

				
						    <classpath>
<pathelement path="${classpath}"/>
<pathelement location="lib/helper.jar"/>
</classpath>

The location attribute specifies a single file or directory relative to the project's base directory (or an absolute filename), while the path attribute accepts colon- or semicolon-separated lists of locations. The path attribute is intended to be used with predefined paths - in any other case, multiple elements with location attributes should be preferred.

As a shortcut, the <classpath> tag supports path and location attributes of its own, so:

				
						    <classpath>
<pathelement path="${classpath}"/>
</classpath>

can be abbreviated to:

				
						    <classpath path="${classpath}"/>

In addition, DirSet s, FileSet s, and FileList s can be specified via nested <dirset>, <fileset>, and <filelist> elements, respectively. Note: The order in which the files building up a FileSet are added to the path-like structure is not defined.

				
						    <classpath>
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
<dirset dir="${build.dir}">
<include name="apps/**/classes"/>
<exclude name="apps/**/*Test*"/>
</dirset>
<filelist refid="third-party_jars"/>
</classpath>

This builds a path that holds the value of ${classpath}, followed by all jar files in the lib directory, the classes directory, all directories named classes under the apps subdirectory of ${build.dir}, except those that have the text Test in their name, and the files specified in the referenced FileList.

If you want to use the same path-like structure for several tasks, you can define them with a <path> element at the same level as targets, and reference them via their id attribute - see References for an example.

A path-like structure can include a reference to another path-like structure via nested <path> elements:

				
						    <path id="base.path">
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
</path>

<path id="tests.path">
<path refid="base.path"/>
<pathelement location="testclasses"/>
</path>

The shortcuts previously mentioned for <classpath> are also valid for <path>.For example:

				
						
								
								 <path id="base.path">
<pathelement path="${classpath}"/>
</path>

can be written as:

				
						 <path id="base.path" path="${classpath}"/>
				
		
				
						generally, you need not to write your builder.xml file started from scratch. you can just modify the following
part to meet your demand.
				
						<project name="javastep" default="deploy" basedir=".">
				
		
				
						<!-- ===================== Property Definitions =========================== -->
				
		
				
						    <!--
         All properties should be defined in this section.
         Any host-specific properties should be defined
         in the build.properties file.
				
						  In this app, the following properties are defined in build.properties:
				
		
				
						   o  tomcat.home     - the home directory of your Tomcat installation
        o  webapps.home    - the place to copy the war file to deploy it
    -->
				
						  <property file="build.properties" />
 
				
						  <property name="app.home"          value="." />
  <property name="app.name"          value="javastep" />
  <property name="javadoc.pkg.top"   value="hello" />
				
						  <property name="src.home"          value="${app.home}/src"/>
  <property name="lib.home"          value="${app.home}/WebRoot/WEB-INF/lib"/>
 
  <property name="classes.home"       value="${app.home}/WebRoot/WEB-INF/classes/"/>
  <property name="deploy.home"       value="${app.home}/deploy"/>
  <property name="doc.home"          value="${app.home}/doc"/>
  <property name="web.home"          value="${app.home}/WebRoot"/>
				
						  <property name="build.home"        value="${app.home}/build"/>
  <property name="build.classes"     value="${build.home}/WEB-INF/classes"/>
  <property name="build.lib"         value="${build.home}/WEB-INF/lib"/>
				
						<!-- ==================== Compilation Classpath =========================== -->
				
		
				
						    <!--
         This section creates the classpath for compilation.
    -->
				
						  <path id="compile.classpath">
				
		
				
						    <!-- The object files for this application -->
    <pathelement location="${classes.home}"/>
				
						    <!-- The lib files for this application -->
    <fileset dir="${lib.home}">
      <include name="*.jar"/>
      <include name="*.zip"/>
    </fileset>
				
						    <!-- All files/jars that Tomcat makes available -->
				
		
				
						
								
  </path>
				
						
								
<!-- ==================== Build Targets below here========================= -->
				
						
								
<!-- ==================== "help" Target =================================== -->
				
						    <!--
         This is the default ant target executed if no target is specified.
         This helps avoid users just typing 'ant' and running a
         default target that may not do what they are anticipating...
    -->
				
						 <target name="help" >
   <echo message="Please specify a target! [usage: ant &lt;targetname&gt;]" />
   <echo message="Here is a list of possible targets: "/>
   <echo message="  clean-all.....Delete build dir, all .class and war files"/>
   <echo message="  prepare.......Creates directories if required" />
   <echo message="  compile.......Compiles source files" />
   <echo message="  build.........Build war file from .class and other files"/>
   <echo message="  deploy........Copy war file to the webapps directory" />
   <echo message="  javadoc.......Generates javadoc for this application" />
 </target>
				
						<!-- ==================== "clean-all" Target ============================== -->
				
		
				
						   <!--
          This target should clean up any traces of the application
          so that if you run a new build directly after cleaning, all
          files will be replaced with what's current in source control
   -->
				
						 <target name="clean-all" >
    <delete dir="${build.home}"/>
    <delete dir="${classes.home}"/>
    <delete dir="${deploy.home}"/>
				
						    <!-- can't delete directory if Tomcat is running -->
    <delete dir="${webapps.home}/${app.name}" failonerror="false"/>
				
						    <!-- deleting the deployed .war file is fine even if Tomcat is running -->
    <delete dir="${webapps.home}/${app.name}.war" />
				
						    <!-- delete the javadoc -->
    <delete dir="${doc.home}"/>
				
						 </target>
				
		
				
						<!-- ==================== "prepare" Target ================================ -->
				
		
				
						    <!--
          This target is executed prior to any of the later targets
          to make sure the directories exist. It only creates them
          if they need to be created....
          Other, similar, preparation steps can be placed here.
    -->
				
						  <target name="prepare">
				
		
				
						    <echo message="Tomcat Home = ${tomcat.home}" />
    <echo message="webapps Home = ${webapps.home}" />
				
						    <mkdir dir="${classes.home}"/>
    <mkdir dir="${deploy.home}"/>
				
						    <mkdir dir="${doc.home}"/>
    <mkdir dir="${doc.home}/api"/>
				
						    <mkdir dir="${build.home}"/>
    <mkdir dir="${build.home}/WEB-INF" />
    <mkdir dir="${build.home}/WEB-INF/classes" />
    <mkdir dir="${build.home}/WEB-INF/lib" />
				
						  </target>
				
		
				
						<!-- ==================== "compile" Target ================================ -->
				
		
				
						    <!--
          This only compiles java files that are newer
          than their corresponding .class files.
     -->
				
						  <target name="compile" depends="prepare" >
    <javac srcdir="${src.home}" destdir="${classes.home}" debug="yes" >
        <classpath refid="compile.classpath"/>
    </javac>
  </target>
				
						<!-- ==================== "build" Target ================================== -->
				
		
				
						    <!--
          This target builds the war file for the application
          by first building the directory structure of the
          application in ${build.home} and then creating the
          war file using the ant <war> task
     -->
				
						  <target name="build" >
				
		
				
						    <!-- Copy all the webapp content (jsp's, html, tld's, xml, etc. -->
    <!-- Note that this also copies the META-INF directory -->
    <copy    todir="${build.home}">
      <fileset dir="${web.home}"/>
    </copy>
				
						    <!-- Now, copy all the Java class files -->
    <copy    todir="${build.home}/WEB-INF/classes">
      <fileset dir="${classes.home}"/>
    </copy>
				
						    <!-- Now, copy all the properties files, etc that go on the classpath -->
    <copy    todir="${build.home}/WEB-INF/classes">
      <fileset dir="${src.home}">
         <include name="**/*.properties" />
         <include name="**/*.prop" />
      </fileset>
    </copy>
				
						    <!-- Now, copy all the jar files we need -->
    <copy    todir="${build.home}/WEB-INF/lib">
      <fileset dir="${lib.home}" />
    </copy>
				
						    <!-- Create the <war> file -->
    <jar jarfile="${deploy.home}/${app.name}.war"
         basedir="${build.home}"/>
				
						  </target>
				
		
				
						<!-- ==================== "deploy" Target ================================= -->
				
		
				
						    <!--
         This target simply copies the war file from the deploy
         directory into the Tomcat webapp directory.
     -->
				
						  <target name="deploy" depends="build" >
				
		
				
						    <!-- Copy the contents of the build directory -->
    <copy todir="${webapps.home}"  file="${deploy.home}/${app.name}.war" />
				
						  </target>
				
		
				
						<!-- ==================== "doc" Target ==================================== -->
				
		
				
						    <!--
         This task creates javadoc. It is dependent upon only the
         'compile' target so it is not executed in a normal build.
         As a result, the target needs to be run on its own.
    -->
				
						  <target name="javadoc" depends="compile">
      <javadoc sourcepath = "${src.home}"
                  destdir = "${doc.home}/api"
             packagenames = "${javadoc.pkg.top}.*"/>
  </target>
 
<!-- ==================== "test" Target ================================== -->
				
						    <!--
        This task runs all test cases. It invokes each test case individually.
        The "test-all" target is tied back to the "struts-test" target which
        actually runs the tests. This allows other test targets to be created
        in this section while maintaining the ability to run each test target
        individually. All individual test targets should be added to the
        "depends" attribute of the "test-all" target to provide a single
        target that runs all tests.
-->
				
						  <target name="test-all" depends="struts-tests" />
				
		
				
						  <target name="struts-tests" depends="build" >
				
		
				
						      <junit printsummary="yes" >
				
		
				
						          <classpath >
              <pathelement location="${classes.home}"/>
              <pathelement location="${build.home}"/>
              <pathelement location="${build.home}/WEB-INF/classes"/>
              <path refid="compile.classpath"/>
          </classpath>
				
						          <formatter type="plain" />
          <test name="hello.mocktest.TestHelloAction" />
          <test name="hello.mocktest.TestHelloActionMultiple" />
      </junit>
   
  </target>
</project>

 

posted on 2006-04-19 21:41 junhong 阅读(377) 评论(0)  编辑  收藏 所属分类: java技术


只有注册用户登录后才能发表评论。


网站导航: