??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲第一成年人网站,亚洲不卡视频在线观看,精品亚洲成A人无码成A在线观看http://m.tkk7.com/boluobn/category/24675.html大江东去,淘?..zh-cnTue, 14 Aug 2007 13:57:50 GMTTue, 14 Aug 2007 13:57:50 GMT60l合Axis和Ant开发Web服务http://m.tkk7.com/boluobn/articles/136198.html菠萝菠萝Sun, 12 Aug 2007 09:04:00 GMThttp://m.tkk7.com/boluobn/articles/136198.htmlhttp://m.tkk7.com/boluobn/comments/136198.htmlhttp://m.tkk7.com/boluobn/articles/136198.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/136198.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/136198.html本文l合一个简单示例讲解了怎样?/span>Axis?/span>Antl合hq行Web服务的开发。帮助读者从单的java源代码或者从一个服务描q文ӞwsdlQ开始,?/span>Ant工具q行构徏Q设|,q把服务部v?/span>Axis?/span>

 

首先假定您熟?/span> AXIS 处理pȝ?/span>Ant工具。文中示例所需要的软g如下Q?/span>

l         Apache Axis 1.1

l         Apache Ant 1.5.3

l         Jarkat Tomcat 4.1.24

在开始前Q假定上qY件已l安装和配置好了?/span>

 

Axis?/span>Ant?/span>

Axis 框架是来?/span> Apache Group 的、基?/span> java 的、最新的 SOAP 规范Q?/span>SOAP 1.2Q和 SOAP with Attachments 规范Q来?/span> Apache Group Q的开放源代码实现。其本质上是一?/span>SOAP引擎Q-一个构如客L、服务器、网关等SOAP处理器的框架。是Apache SOAP的后l项目。但是,Axis使用SAXQ基于事Ӟ解析器获得了?/span>Apache SOAP早期版本(使用DOM解析)非常明显的速度优势。另外,它还h很强的灵zL和E_性,支持Web服务描述语言1.1版?/span>

Apache Ant?/span>Apache软g基金?/span>jakarta目中的一个子目Q是一个基?/span>Java的构建工PcM?/span>makeQ但它没?/span>make那么复杂J琐?/span>Ant׃些内|Q务(taskQ和可选择的Q务组成,q可以配|第三方提供的Q务。它的构建配|文件基?/span>XML的,所以容易书写和l护Q而且l构清晰?/span>Antq可以集成到一些开发环境中Q例?/span>visual age,jbuilder,Elipse)?/span>

 

Axis?/span>Ant的支?/span>

Axis为支?/span>Ant构徏Q提供了一?/span>axis-ant.jar文g。该文g包含三个可选Q?/span>(task)的定义和实现Q?/span>axis-wsdl2javaQ?/span>axis-java2wsdl?/span>axis-admin。Q?/span>axis-wsdl2java?/span>Axis提供的工?/span>WSDL2Javah同样的功能,Ҏweb服务描述文g生成对应?/span>Java源程序,它的属性设|与WSDL2Java的命令参数设|类伹{而Q?/span>axis-java2wsdl则相反,它与Java2WSDL工具一P是根据已有的cL件来生成Web服务描述文g。最后一个Q?/span>axis-admin是用?/span>web服务的部|和取消部v的,对应?/span>Axis?/span>AminClient工具?/span>

Z?/span>Ant能够正确使用上述三个dQ?/span>taskQ,q需要做一些配|。注意:Apache Ant的版本必L1.5.1或更高版本?/span>

1Q设|系l的环境变量CLASSPATH包含Axis提供?/span>axis-ant.jar文gQ或者在Ant的配|文Ӟ通常?/span>build.xmlQ中讄路径包含它。例如,

    <path id="axis.classpath">

     <fileset dir="${axis.home}/lib">

               <include name="**/*.jar" />

      </fileset>

    </path>

   

2Q然后?/span><taskdef>声明导入axis-ant.jar文g中的属性文件所定义的Q务(taskQ列表?/span>

    <taskdef resource="axis-tasks.properties"

 classpathref="axis.classpath" />

    3Q设|在构徏q程中可能要需要的java包,例如Q?/span> Axis所有的jar包,wsdl4j.jarQ?/span>junit.jar{等?/span>

 

实例开?/span>

下面q一个实例来讲解怎样?/span>Ant?/span>Axisl合来开?/span>Web服务。ؓ了注重本文的目的Q我们开发一个比较简单的Web服务Q它接受客户端传入的字符串数l,如果传入的参CؓnullQ则抛出一个自定义的异常,否则把每个字W串q接hq回l客L?/span>

首先定义一?/span>Web服务接口HelloQ如下所C:

 

 package com.bidlink.hello;

 public interface Hello{

     public String echo(String[] content ) throws                       

               java.rmi.RemoteException,com.bidlink.hello.MyException;

 }

 

 自定义异?/span>MyException包含一个时间|以记录异常出现的旉Q如下:

 

 package com.bidlink.hello;

public class MyException extends org.apache.axis.AxisFault implements java.io.Serializable{

    private java.util.Calendar occurTime;

   

    public MyException() {

    }

 

    public MyException(

           java.util.Calendar occurTime) {

        super();

        this.occurTime = occurTime;

    }

 

    public java.util.Calendar getOccurTime() {

        return occurTime;

    }

 

    public void setOccurTime(java.util.Calendar occurTime) {

        this.occurTime = occurTime;

    }           

}

 

1Q?/span>axis-java2wsdlQ从cL件生成服务描q文?/span>

~译上面定义的两个文?/span>Hell.java?/span>MyException.java。接着~写Ant的配|文?/span>build.xmlQ文件详l信息请查看CZ源代码)Q?/span>axis-java2wsdldҎc?/span>Hello来生?/span>Web服务描述文ghello.wsdl。Q务具体配|如下:

    <axis-java2wsdl classname="com.bidlink.hello.Hello"

                        location="http://localhost:8080/axis/services/Hello"

                        namespace="http://hello.bidlink.com"

                        output="hello.wsdl"

                        style="RPC"

                        extraclasses="com.bidlink.hello.MyException">

         <classpath>

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

         </classpath>

        </axis-java2wsdl>

       

其中Q?/span><pathelement path="${dist}"/>指出Hello.class?/span>MyException.class文g的位|?/span>

q行命oant java2wsdlQ构建出Web服务描述文ghello.wsdl?/span>

2Q?/span>axis-wsdkl2javaQ从服务描述文g生成服务源程?/span>

下面讲解怎样Ҏ刚刚得到?/span>hello.wsdl文g生成服务所需要的java源程序。在q里需要用CQ?/span>axis-wsdl2java。Q务属性设|如下:

     <axis-wsdl2java all="true"

                     url="hello.wsdl"

                     deployscope="Request"

                     output="${gensrc}"

                     serverside="true"

                     skeletondeploy="false"

                     testcase="true"

                     noimports="false"

                     typemappingversion="1.2">

       

        </axis-wsdl2java>

     q行ant wsdl2javaQ根?/span>axis-wsdl2javad的属性配|生成相应的java源程序,本例所生成的文件包括:服务端服务接口文?/span>Hello.java及其实现HelloSoapBindingImpl.javaQ以及客L?/span>HelloService.javaQ?/span>HelloServiceLocator.javaQ?/span>HelloServiceLocator.java和客L存根文gHelloSoapBindingStub.java。又因ؓ属?/span>testcase="true"Q所以还生成了测试文?/span>HelloServiceTestCase.java。当Ӟ自定义异?/span>MyException也是重新生成的?/span>

3Q?/span>axis-adminQ向Axis部vHello服务

服务源程序生成后Q需要根据服务的功能修改HelloSoapBindingImpl.java文gQ以真正实现?/span>Web服务。修改如下:

 /**

 * HelloSoapBindingImpl.java

 *

 * This file was auto-generated from WSDL

 * by the Apache Axis WSDL2Java emitter.

 */

 

package com.bidlink.hello;

 

public class HelloSoapBindingImpl implements com.bidlink.hello.Hello{

    public java.lang.String echo(java.lang.String[] in0) throws java.rmi.RemoteException, com.bidlink.hello.MyException {

        if(in0 == null)

           throw new MyException(java.util.Calendar.getInstance());

          

       

        String retStr = "";

        for(int i=0; i< in0.length; i++)

           retStr += in0[i];

        return retStr;

    }

 

}

   

~译所有的生成的源E序Q最后?/span>axis-admind?/span>Axis部vHello Web服务?/span>

    <axis-admin

           port="${target.port}"

               hostname="${target.server}"

            failonerror="true"

            servletpath="${target.appname}/services/AdminService"

            debug="true"

            xmlfile="deploy.wsdd"/>

       q行ant deployQ部|?/span>Hello服务?/span>

    

现在可以试所部v?/span>Web服务hello。可以通过览器,也可以利用刚才生成的试文gHelloServiceTestCase.java来进行该工作。如果利用测试文?/span>HelloServiceTestCase.javaQ那么还需要对它进行稍作修攏V具体来_是d一?/span>main函数Q然后修Ҏ生成的测试方法?/span>



菠萝 2007-08-12 17:04 发表评论
]]>
axis with anthttp://m.tkk7.com/boluobn/articles/136197.html菠萝菠萝Sun, 12 Aug 2007 09:03:00 GMThttp://m.tkk7.com/boluobn/articles/136197.htmlhttp://m.tkk7.com/boluobn/comments/136197.htmlhttp://m.tkk7.com/boluobn/articles/136197.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/136197.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/136197.html  按照axis的ant相关文档配置的时候,需要引入相应的ant taskQ我在做q个配置的时候遇C些障,开始的build.xml如下所C:

<?xml version="1.0"?>
<project default="axis" basedir=".">

<property name="axis.home" location="../" />

<path id="axis.classpath">
  <fileset dir="${axis.home}/WebRoot/WEB-INF/lib">
    <include name="**/*.jar" />
  </fileset>
  <fileset dir="${axis.home}/WebRoot/WEB-INF/classes">
    <include name="**/*.class" />
  </fileset>
</path>

<taskdef resource="axis-tasks.properties" classpathref="/axis.classpath" />

<target name="init" />

<target name="axis">
    <axis-java2wsdl
  classname="axis.service.SimpleObjectCreator"    
  location="http://localhost:8080/axis/services/SimpleObjectCreator"
      namespace="service.axis"
      output="simpleObject.wsdl"
      style="RPC"
      extraclasses="axis.bean.SimpleObject"
    >
      <classpath refid="axis.classpath"/>
    </axis-java2wsdl>
    <axis-wsdl2java all="true"
        url="simpleObject.wsdl"
        deployscope="Request"
        output="${axis.home}/src"
        serverside="true"
        skeletondeploy="false"
        testcase="true"
        noimports="false"
        typemappingversion="1.2"
    />
</target>

<target name="deploy">
 <axis-admin
  port="8080"
  hostname="localhost"
  failonerror="true"
  servletpath="axis/services/AdminService"
  debug="true"
  xmlfile="${axis.home}\src\axis\service\deploy.wsdd"
 />
</target>
   
</project>

  在执行ant的时候,L?br>    java.util.zip.ZipException: error in opening zip file
的错误,百思不得其解,后来扑ֈ了错误的原因Q原来出?br>    <path id="axis.classpath">...</path>
的定义上Q因里包?br>  <fileset dir="${axis.home}/WebRoot/WEB-INF/classes">
    <include name="**/*.class" />
  </fileset>
部分Q?lt;taskdef>解析时会把我指定的class文g当作一个压~文件进行解压,产生异常Q改成如下定义即可:
<path id="axis.classpath">
  <fileset dir="${axis.home}/WebRoot/WEB-INF/lib">
    <include name="**/*.jar" />
  </fileset>
  <pathelement location="${axis.home}/WebRoot/WEB-INF/classes"/>
</path>
W二个filesetҎpathelementQ当<taskdef>解析时会把指定的location当作一个\径,不会报错?br>  对于开源的ant真是又爱又恨啊,可恨的是文档太少了,?lt;path>,<taskdef>的说明等Q惜墨如金啊?/p>

菠萝 2007-08-12 17:03 发表评论
]]>
Axis开发之工业化-ant使用http://m.tkk7.com/boluobn/articles/136183.html菠萝菠萝Sun, 12 Aug 2007 08:24:00 GMThttp://m.tkk7.com/boluobn/articles/136183.htmlhttp://m.tkk7.com/boluobn/comments/136183.htmlhttp://m.tkk7.com/boluobn/articles/136183.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/136183.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/136183.htmlAxis为支?/span>Ant构徏Q提供了一?/span>axis-ant.jar文g。该文g包含三个可选Q?/span>(task)的定义和实现Q?/span>axis-wsdl2javaQ?/span>axis-java2wsdl?/span>axis-admin?/span>

1Q?span>   daxis-wsdl2java?/span>Axis提供的工?/span>WSDL2Javah同样的功能,Ҏweb服务描述文g生成对应?/span>Java源程序,它的属性设|与WSDL2Java的命令参数设|类伹{?/span>

2Q?span>   daxis-java2wsdl则相反,它与Java2WSDL工具一P是根据已有的cL件来生成Web服务描述文g?/span>

3Q?span>   axis-admin是用?/span>web服务的部|和取消部v的,对应?/span>Axis?/span>AminClient工具?/span>

Z使用ant来徏构,首先需要将axis-ant.jar包拷贝到ant?/span>lib目录下?/span>

一、下面是详细的步骤,列了一?/span>1Q?/span>2Q?/span>3Q?/span>4Q?/span>5Q看h清楚一?/span>

1Q?span>   ?/span><taskdef>声明导入axis-ant.jar文g中的属性文件所定义的Q务(taskQ列表?/span>

<taskdef resource="axis-tasks.properties" classpathref="axis.classpath"/>

2Q?span>   ?/span>axis的包都导q来

<property name="axis.home" value="G:/package/axis-1_3"/>

<!--定义classpath-->

<path id="axis.classpath">

     <!?q里导入的是axis的所有包-->

    <fileset dir="${axis.home}/lib">

        <include name="**/*.jar" />

    </fileset>

     <!?

q里导入的是javamail的包Q如?/span>web服务有附件的时候要用到Q如果没有包含进来会有一个警?/span>

-->

    <fileset dir="G:/workpackage/j2ee">

        <include name="**/*.jar" />

    </fileset>

     <!?其他的包-->

    <fileset dir="${basedir}">

        <include name="other.jar" />

    </fileset>

</path>

3Q?span>   生成web描述文g和根据描q文件生?/span>java源程?/span>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<target name="axis" depends="init">

<axis-java2wsdl

classname="net.wide.axis.service.SimpleObjectCreator"     location="http://localhost:8080/axis/services/SimpleObjectCreator"

    namespace="service.axis.wide.net"

    output="simpleObject.wsdl"

    style="RPC"

    extraclasses="net.wide.axis.bean.SimpleObject"

    />

    <axis-wsdl2java all="true"

        url="simpleObject.wsdl"

        deployscope="Request"

        output="${basedir}/src"

        serverside="true"

        skeletondeploy="false"

        testcase="true"

        noimports="false"

        typemappingversion="1.2"/>

    </target>

3行:我们要发布的web服务接口Q需要先定义q个接口Q如果是一个具体的c,下面?/span>axis-wsdl2java来生?/span>java文g的时候,会生成该接口和他的实现文件?/span>

4行:web服务发布的位|?/span>

5行:namespaceQ这一行用U字标出来,是要注意的,“service.axis.wide.netQ跟我的包结构刚好倒过来,当用axis-wsdl2java来生?/span>java文g的时候,包结构就?#8220;net.wide.axis.service”?/span>

6行:生成?/span>webservice描述文gQ?/span>axis-wsdl2java正是用他来生?/span>java文g?/span>

4Q?span>   生成的java文g~译Q解下就是部|?/span>

1

2

3

4

5

6

7

8

9

<target name="deploy" depends="init">

<axis-admin

port="8080"

hostname="localhost"

failonerror="true"

servletpath="axis/services/AdminService"

debug="true"

xmlfile="${basedir}\src\net\wide\axis\service\deploy.wsdd"/>

</target>

6行:servletpath要跟web.xml中的保持一?/span>

8行:上一步生成的部v文g

5Q?span>  

二、实例,通过一个实例来看看使用ant的开发步骤。包括下面的内容Q?/span>

1Q?span>   服务端创Z?/span>JavaBeanQƈ且返回给客户?/span>

2Q?span>   客户端将一?/span>JavaBean做ؓ参数传递给服务器端

3Q?span>   服务器端q回一?/span>JavaBean数组

1Q?span>   定义JavaBean

package net.wide.axis.bean;

public class SimpleObject implements Serializable {

    private String name;

    public getName() {

        return name;

    }

public void setName(String name) {

        this.name = name;

    }

}

注意JavaBean需要实?/span>Serializable接口

2Q?span>   定义web服务接口

package net.wide.axis.service;

import net.wide.axis.bean.SimpleObject;

public interface SimpleObjectCreator{

    public SimpleObject createSimpleObject(String name);

    public void storeSimpleObject(SimpleObject simpleObject);

    public SimpleObject[] createSimpleObjects();

}

3Q?span>   q行Ant axisQ生成了下面的文?/span>

4Q?span>   实现SimpleObjectCreatorSoapBindingImpl.javaQ这?/span>java文g是SimpleObjectCreator的实现文Ӟ单实现如下:

public class SimpleObjectCreatorSoapBindingImpl

implements net.wide.axis.service.SimpleObjectCreator{

    public SimpleObject createSimpleObject(java.lang.String name)

throws java.rmi.RemoteException {

         System.out.println("创徏SimpleObject...");

        SimpleObject simpleObject = new SimpleObject();

        simpleObject.setName(name);

        return simpleObject;

    }

    public void storeSimpleObject(SimpleObject simpleObject)

throws java.rmi.RemoteException {

         System.out.println("Store");

        System.out.println(simpleObject.getName());

    }

    public SimpleObject[] createSimpleObjects()

throws java.rmi.RemoteException {

        SimpleObject[] simpleObjects = new SimpleObject[2];

        simpleObjects[0] = new SimpleObject();

        simpleObjects[1] = new SimpleObject();

        simpleObjects[0].setName("First Object");

        simpleObjects[1].setName("Second Object");

        return simpleObjects;

    }

}

5Q?span>   部vant deploy

6Q?span>  

public static void main(String[] args)

throws ServiceException, RemoteException {

        String endPoint =

 "http://localhost:8080/axis/services/SimpleObjectCreator?wsdl";

        Service service = new Service();

        Call call = (Call) service.createCall();

        call.setTargetEndpointAddress(endPoint);

        QName qname =

new QName("http://bean.axis.wide.net","SimpleObject");

        //createSimpleObjectҎQ它创徏一?/span>SimpleObjectq且q回该对?/span>

        call.registerTypeMapping(SimpleObject.class,

qname,

new BeanSerializerFactory(SimpleObject.class, qname),

new BeanDeserializerFactory(SimpleObject.class, qname));

        call.setOperationName("createSimpleObject");

        SimpleObject simpleObject =

(SimpleObject) call.invoke(new Object[]{"Hello"});

        System.out.println(simpleObject.getName());

        //storeSimpleObjectQ客L传递一?/span>SimpleObject

        call.setOperationName("storeSimpleObject");

        call.invoke(new Object[]{simpleObject});   

        //试服务端返回一?/span>SimpleObject数组Q打印出数组的长?/span>

        qname =

new QName("service.axis.wide.net","ArrayOf_tns1_SimpleObject");

        call.registerTypeMapping(SimpleObject.class,

qname,

new BeanSerializerFactory(SimpleObject.class, qname),

new BeanDeserializerFactory(SimpleObject.class, qname));

        call.setOperationName("createSimpleObjects");

        SimpleObject[] simpleObjects =

(SimpleObject[]) call.invoke(new Object[]{});

        System.out.println(simpleObjects.length);

    }

7Q?span>   l合/WEB-INF/server-config.wsdd来分析,部v的时候会生成q个部v描述文g

<service name="SimpleObjectCreator" provider="java:RPC">

    <operation name="createSimpleObject"

qname="ns2:createSimpleObject"

               returnQName="createSimpleObjectReturn"

            soapAction=""

xmlns:ns1=http://bean.axis.wide.net/

returnType="ns1:SimpleObject"

            xmlns:ns2="service.axis.wide.net">

       <parameter

name="in0"

type="xsd:string"

           xmlns:xsd="http://www.w3.org/2001/XMLSchema" />

    </operation>

    <operation name="storeSimpleObject"

qname="ns3:storeSimpleObject"

               soapAction=""

xmlns:ns3="service.axis.wide.net">

       <parameter name="in0" type="ns4:SimpleObject"

           xmlns:ns4="http://bean.axis.wide.net" />

    </operation>

    <operation name="createSimpleObjects"

       qname="ns5:createSimpleObjects"

       returnQName="createSimpleObjectsReturn"

       returnType="ns5:ArrayOf_tns1_SimpleObject"

soapAction=""

       xmlns:ns5="service.axis.wide.net" />

    <parameter name="wsdlServicePort" value="SimpleObjectCreator" />

    <parameter name="className"     value="net.wide.axis.service.SimpleObjectCreatorSoapBindingImpl" />

    <parameter name="typeMappingVersion" value="1.2" />

    <parameter name="allowedMethods"

       value="storeSimpleObject createSimpleObject createSimpleObjects" />

    <parameter name="wsdlServiceElement"

       value="SimpleObjectCreatorService" />

    <parameter name="wsdlTargetNamespace"

value="service.axis.wide.net" />

    <parameter name="wsdlPortType" value="SimpleObjectCreator" />

    <parameter name="scope" value="Request" />

    <parameter name="schemaUnqualified"

       value="service.axis.wide.net,http://bean.axis.wide.net" />

    <typeMapping

        deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"

       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"

       qname="ns6:SimpleObject"

       serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"

       type="java:net.wide.axis.bean.SimpleObject"

       xmlns:ns6="http://bean.axis.wide.net" />

    <arrayMapping innerType="ns8:SimpleObject"

       languageSpecificType="java:net.wide.axis.bean.SimpleObject[]"

       qname="ns7:ArrayOf_tns1_SimpleObject"

       xmlns:ns7="service.axis.wide.net"

       xmlns:ns8="http://bean.axis.wide.net" />

</service>

q一D|SimpleObjectCreator的描q。结?/span>createSimpleObjectҎ的描qC试代码中的Q?/span>

    QName qname = new QName("http://bean.axis.wide.net","SimpleObject");

?/span>createSimpleObjectҎ的描qC有下面的一D?/span>

xmlns:ns1=http://bean.axis.wide.net/

returnType="ns1:SimpleObject"

Ҏq道了Q我们用的命名I间?span>Q?/span>http://bean.axis.wide.net/

其他几个也是q样?/span>



菠萝 2007-08-12 16:24 发表评论
]]>
Ant?/title><link>http://m.tkk7.com/boluobn/articles/136156.html</link><dc:creator>菠萝</dc:creator><author>菠萝</author><pubDate>Sun, 12 Aug 2007 04:43:00 GMT</pubDate><guid>http://m.tkk7.com/boluobn/articles/136156.html</guid><wfw:comment>http://m.tkk7.com/boluobn/comments/136156.html</wfw:comment><comments>http://m.tkk7.com/boluobn/articles/136156.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/boluobn/comments/commentRss/136156.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/boluobn/services/trackbacks/136156.html</trackback:ping><description><![CDATA[<strong> </strong>Ant的概?<br>可能有些读者ƈ不连接什么是Ant以及入可使用它,但只要用通过Linuxpȝ得读者,应该知道makeq个命o。当~译Linux内核及一些Y件的源程序时Q经常要用这个命令。Make命o其实是一个项目管理工P而Ant所实现功能与此cM。像makeQgnumake和nmakeq些~译工具都有一定的~陷Q但是Ant却克服了q些工具的缺陗最初Ant开发者在开发跨q_的应用时Q用样也是基于这些缺陷对Ant做了更好的设计? <p>Ant ?makefile <br>Makefile有一些不之处,比如很多人都会碰到的烦h的Tab问题。最初的Ant开发者多ơ强?#8221;只是我在Tab前面加了一个空|所以我的命令就不能执行”。有一些工具在一定程度上解决了这个问题,但还是有很多其他的问题。Ant则与一般基于命令的工具有所不同Q它是Javacȝ扩展。Antq行需要的XML格式的文件不是Shell命o文g。它是由一个Projectl成的,而一个Project又可分成可多targetQtarget再细分又分成很多taskQ每一个task都是通过一个实现特定接口的javacL完成的?/p> <p>Ant的优?/p> <p>Ant是Apache软g基金会JAKARTA目录中的一个子目Q它有以下的优点?<br>跨^台性。Ant是存Java语言~写的,所C具有很好的跨^台性?<br>操作单。Ant是由一个内|Q务和可选Q务组成的。Antq行旉要一个XML文g(构徏文g)。Ant通过调用target树,可以执行各Utask。每个task实现了特定接口对象。由于Ant构徏文g时XML格式的文Ӟ所以和Ҏl护和书写,而且l构很清晰?<br>Ant可以集成到开发环境中。由于Ant的跨q_性和操作单的特点Q它很容易集成到一些开发环境中厅R?/p> <p>Ant 开?/p> <p>Ant的构建文?<br>当开始一个新的项目时Q首先应该编写Ant构徏文g。构建文件定义了构徏q程Qƈ被团队开发中每个Z用。Ant构徏文g默认命名为build.xmlQ也可以取其他的名字。只不过在运行的时候把q个命名当作参数传给Ant。构建文件可以放在Q何的位置。一般做法是攑֜目层目录中,q样可以保持目的简z和清晰。下面是一个典型的目层次l构?<br>(1) src存放文g?<br>(2) class存放~译后的文g?<br>(3) lib存放W三方JAR包?<br>(4) dist存放打包Q发布以后的代码?<br>Ant构徏文g是XML文g。每个构建文件定义一个唯一的项?Project元素)。每个项目下可以定义很多目标(target元素)Q这些目标之间可以有依赖关系。当执行q类目标Ӟ需要执行他们所依赖的目标?每个目标中可以定义多个Q务,目标中还定义了所要执行的d序列。Ant在构建目标时必须调用所定义的Q务。Q务定义了Ant实际执行的命令。Ant中的d可以?cR?<br>Q?Q?核心d。核心Q务是Ant自带的Q务?<br>Q?Q?可选Q务。可选Q务实来自W三方的dQ因此需要一个附加的JAR文g?<br>Q?Q?用户自定义的d。用戯定义的Q务实用户自己开发的d?<br>1.<project>标签 <br>每个构徏文g对应一个项目?lt;project>标签时构建文件的Ҏ{。它可以有多个内在属性,</p> <p>如代码中所C,其各个属性的含义分别如下?<br>(1) default表示默认的运行目标,q个属性是必须的?<br>(2) basedir表示目的基准目录?<br>(3) name表示目名?<br>(4) description表示目的描q?<br>每个构徏文g都对应于一个项目,但是大型目l常包含大量的子目Q每一个子目都可以有自己的构建文件?/p> <p>2.<target>标签 <br>一个项目标{下可以有一个或多个target标签。一个target标签可以依赖其他的target标签。例如,有一个target用于~译E序Q另一个target用于声称可执行文件。在生成可执行文件之前必d~译该文Ӟ因策可执行文件的target依赖于编译程序的target。Target的所有属性如下?<br>(1).name表示标明Q这个属性是必须的?<br>(2).depends表示依赖的目标?<br>(3)if表示仅当属性设|时才执行?<br>(4)unless表示当属性没有设|时才执行?<br>(5)description表示目的描q?<br>Ant的depends属性指定了target的执行顺序。Ant会依照depends属性中target出现序依次执行每个target。在执行之前Q首先需要执行它所依赖的target。程序中的名为run的target?/p> <p>depends属性compileQ而名为compile的target的depends属性是prepareQ所以这几个target?/p> <p>行的序是prepare->compile->run?<br>一个target只能被执行一ơ,即有多个target依赖于它。如果没有if或unless属性,target?/p> <p>会被执行?/p> <p>3.<mkdir>标签 <br>该标{于创Z个目录,它有一个属性dir用来指定所创徏的目录名Q其代码如下Q?<br><mkdir dir=”${class.root}”/> <br>通过以上代码创Z一个目录,q个目录已经被前面的property标签所指定?/p> <p>4<jar>标签 <br>该标{来生成一个JAR文gQ其属性如下?<br>(1) destfile表示JAR文g名?<br>(2) basedir表示被归档的文g名?<br>(3) includes表示别归档的文g模式?<br>(4) exchudes表示被排除的文g模式?/p> <p>5Q?lt;javac标签> <br>该标{于编译一个或一ljava文gQ其属性如下?<br>(1).srcdir表示源程序的目录?<br>(2).destdir表示class文g的输出目录?<br>(3).include表示被编译的文g的模式?<br>(4).excludes表示被排除的文g的模式?<br>(5).classpath表示所使用的类路径?<br>(6).debug表示包含的调试信息?<br>(7).optimize表示是否使用优化?<br>(8).verbose 表示提供详细的输Z息?<br>(9).fileonerror表示当碰到错误就自动停止?/p> <p>6Q?lt;java>标签 <br>该标{来执行编译生成的.class文gQ其属性如下?<br>(1).classname 表示执行的cd?<br>(2).jar表示包含该类的JAR文g名?<br>(3).classpath所表示用到的类路径?<br>(4).fork表示在一个新的虚拟机中运行该cR?<br>(5).failonerror表示当出现错误时自动停止?<br>(6).output 表示输出文g?<br>(7).append表示q加或者覆盖默认文件?/p> <p>7.<delete>标签 <br>该标{于删除一个文件或一l文Ӟd性如下?<br>(1)/file表示要删除的文g?<br>(2).dir表示要删除的目录?<br>(3).includeEmptyDirs 表示指定是否要删除空目录Q默认值是删除?<br>(4).failonerror 表示指定当碰到错误是否停止,默认值是自动停止?<br>(5).verbose表示指定是否列出所删除的文Ӟ默认gؓ不列出?/p> <p>8.<copy>标签 <br>该标{于文件或文g集的拯Q其属性如下?<br>(1).file 表示源文件?<br>(2).tofile 表示目标文g?<br>(3).todir 表示目标目录?<br>(4).overwrite 表示指定是否覆盖目标文gQ默认值是不覆盖?<br>(5).includeEmptyDirs 表示制定是否拯I目录,默认gؓ拯?<br>(6).failonerror 表示指定如目标没有发现是否自动停止,默认值是停止?<br>(7).verbose 表示制定是否昄详细信息Q默认g昄?/p> <p>Ant的数据类?<br>在构建文件中Z标识文g或文件组Q经帔R要用数据类型。数据类型包含在</p> <p>org.apache.tool.ant.types包中。下面镜单介l构建文件中一些常用的数据cd?/p> <p>1. argument cd <br>由Ant构徏文g调用的程序,可以通过<arg>元素向其传递命令行参数Q如apply,exec和javad均可接受嵌套<arg>元素Q可以ؓ各自的过E调用指定参数。以下是<arg>的所有属性?<br>(1).values 是一个命令参数。如果参数种有空|但又惛_它作为单独一个|则用此属性?<br>(2).file表示一个参数的文g名。在构徏文g中,此文件名相对于当前的工作目录?<br>(3).line表示用空格分隔的多个参数列表?<br>(4).path表示路径?/p> <p>2.ervironment cd <br>由Ant构徏文g调用的外部命令或E序Q?lt;env>元素制定了哪些环境变量要传递给正在执行的系l命令,<env>元素可以接受以下属性?<br>(1).file表示环境变量值得文g名。此文g名要被{换位一个绝对\径?<br>(2).path表示环境变量的\径。Ant会将它{换ؓ一个本地约定?<br>(3).value 表示环境变量的一个直接变量?<br>(4).key 表示环境变量名?<br>注意 file path ?value只能取一个?/p> <p>3.filelistcd <br>Filelist 是一个支持命名的文g列表的数据类型,包含在一个filelistcd中的文g不一定是</p> <p>存在的文件。以下是其所有的属性?<br>(1).dir是用于计绝Ҏ件名的目录?<br>(2).files 是用逗号分隔的文件名列表?<br>(3).refid 是对某处定义的一?lt;filelist>的引用?<br>注意 dir ?files 都是必要的,除非指定了refid(q种情况下,dir和files都不允许使用)?/p> <p>4.filesetcd <br>Fileset 数据cd定义了一l文Ӟq常表示?lt;fileset>元素。不q,许多antd构徏成了隐式的fileset,q说明他们支持所有的fileset属性和嵌套元素。以下ؓfileset 的属性列表?(1).dir表示fileset 的基目录?<br>(2).casesensitive的值如果ؓfalseQ那么匹配文件名Ӟfileset不是区分大小写的Q其默认</p> <p>gؓtrue. <br>(3).defaultexcludes 用来定是否使用默认的排除模式,默认为true?<br>(4).excludes 是用逗号分隔的需要派出的文g模式列表?<br>(5).excludesfile 表示每行包含一个排除模式的文g的文件名?<br>(6).includes 是用逗号分隔的,需要包含的文g模式列表?<br>(7).includesfile 表示每行包括一个包含模式的文g名?/p> <p>5.patternset cd <br>Fileset 是对文g的分l,而patternset是对模式的分l,他们是紧密相关的概念?lt;patternset>支持4个属性:includes excludex includexfile ?excludesfile,与fileset相同。Patternset q允总下嵌套元素:include,exclude,includefile ?excludesfile.</p> <p>6.filterset cd <br>Filterset定义了一l过滤器Q这些过滤器在文gUd或复制时完成文g的文本替换?<br>主要属性如下: <br>(1).begintoken 表示嵌套qo器所搜烦的记Pq是标识其开始的字符丌Ӏ?<br>(2).endtoken表示嵌套qo器所搜烦的记可是标识其l束的字W串?<br>(3).id是过滤器的唯一标志W?<br>(4).refid是对构徏文g中某处定义一个过滤器的引用?/p> <p>7.Pathcd <br>Path元素用来表示一个类路径Q不q它q可以用于表C其他的路径。在用作揖个属性时Q\l中的各用分号或冒号隔开。在构徏的时候,此分隔符代替当前^C所有的路径分隔W,其拥有的属性如下?<br>(1).location 表示一个文件或目录。Ant在内部将此扩展ؓ一个绝对\径?<br>(2).refid 是对当前构徏文g中某处定义的一个path的引用?<br>(3).path表示一个文件或路径名列表?/p> <p>8.mappercd <br>Mappercd定义了一l输入文件和一l输出文仉的关p,其属性如下?<br>(1).classname 表示实现mappercȝcd。当内置mapper不满求时Q用于创建定制mapper. <br>(2).classpath表示查找一个定制mapper时所用的cd路径?<br>(3).classpathref是对某处定义的一个类路径的引用?<br>(4).from属性的含义取决于所用的mapper. <br>(5).to属性的含义取决于所用的mapper. <br>(6).type属性的取gؓidentityQflatten glob merge regexp 其中之一Q它定义了要是用的内|mapper的类型?/p> <p>Ant 的运?<br>安装好Antq且配置好\径之后,在命令行中切换到构徏文g的目录,输入Ant命o可以运行Ant.若没有指定Q何参敎ͼAnt会在当前目录下查询build.xml文g。如果找Cq该文件作为构建文件。如果用了 –find 选项QAnt ׃在上U目录中找构建文Ӟ直至到达文gpȝ得跟目录。如果构建文件的名字不是build.xml Q则Antq行的时候就可以使用 –buildfile file ,q里file 指定了要使用的构建文件的名称Q示例如下: <br>Ant <br>如下说明了表C当前目录的构徏文g为build.xml q行 ant 执行默认的目标?/p> <p>Ant –buildfile test.xml <br>使用当前目录下的test.xml 文gq行Ant ,执行默认的目标?/p> <img src ="http://m.tkk7.com/boluobn/aggbug/136156.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/boluobn/" target="_blank">菠萝</a> 2007-08-12 12:43 <a href="http://m.tkk7.com/boluobn/articles/136156.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ant中文教程http://m.tkk7.com/boluobn/articles/135078.html菠萝菠萝Tue, 07 Aug 2007 13:29:00 GMThttp://m.tkk7.com/boluobn/articles/135078.htmlhttp://m.tkk7.com/boluobn/comments/135078.htmlhttp://m.tkk7.com/boluobn/articles/135078.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/135078.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/135078.html1 Ant是什么?
Apache Ant 是一个基?Java的生成工兗?br>生成工具在Y件开发中用来源代码和其他输入文件{换ؓ可执行文件的形式Q也有可能{换ؓ可安装的产品映像形式Q。随着应用E序的生成过E变得更加复杂,保在每ơ生成期间都使用_相同的生成步骤,同时实现可能多的自动化Q以便及时生一致的生成版本
2 下蝲、安装Ant
安装Ant
下蝲.zip文gQ解压羃到c:\ant1.3(后面引用?ANT_HOME%)

2.1 在你q行Ant之前需要做一些配|工作?br>? bin目录加入PATH环境变量?
? 讑֮ANT_HOME环境变量Q指向你安装Ant的目录。在一些OS上,Ant的脚本可以猜ANT_HOMEQUnix和Windos NT/2000Q-但最好不要依赖这一Ҏ?
? 可选地Q设定JAVA_HOME环境变量Q参考下面的高񔞮节Q,该变量应该指向你安装JDK的目录?br>注意Q不要将Ant的ant.jar文g攑ֈJDK/JRE的lib/ext目录下。Ant是个应用E序Q而lib/ext目录是ؓJDK扩展使用的(如JCEQJSSE扩展Q。而且通过扩展装入的类会有安全斚w的限制?br>2.2 q行Ant

q行Ant非常单,当你正确地安装Ant后,只要输入ant可以了?br>
? 没有指定M参数ӞAnt会在当前目录下查询build.xml文g。如果找Cq该文件作为buildfile。如果你?-find 选项。Ant׃在上U目录中LbuildfileQ直臛_达文件系l的栏V要惌Ant使用其他的buildfileQ可以用参数 -buildfile fileQ这里file指定了你想用的buildfile?br>
? 可以指定执行一个或多个target。当省略targetӞAnt使用标签<project>的default属性所指定的target?br>

命o行选项ȝQ?br>ant [options] [target [target2 [target3] ...]]
Options:
-help print this message
-projecthelp print project help information
-version print the version information and exit
-quiet be extra quiet
-verbose be extra verbose
-debug print debugging information
-emacs produce logging information without adornments
-logfile file use given file for log output
-logger classname the class that is to perform logging
-listener classname add an instance of class as a project listener
-buildfile file use specified buildfile
-find file search for buildfile towards the root of the filesystem and use the first one found
-Dproperty=value set property to value
例子
ant
使用当前目录下的build.xmlq行AntQ执行缺省的target?br>ant -buildfile test.xml
使用当前目录下的test.xmlq行AntQ执行缺省的target?br>ant -buildfile test.xml dist
使用当前目录下的test.xmlq行AntQ执行一个叫做dist的target?br>ant -buildfile test.xml -Dbuild=build/classes dist
使用当前目录下的test.xmlq行AntQ执行一个叫做dist的targetQƈ讑֮build属性的gؓbuild/classes?br>
3 ~写build.xml

Ant的buildfile是用XML写的。每个buildfile含有一个project?br>
buildfile中每个task元素可以有一个id属性,可以用这个id值引用指定的d。这个值必L唯一的。(详情请参考下面的Task节Q?br>
3.1 Projects

project有下面的属性:
Attribute Description Required
name 目名称. No
default 当没有指定target时用的~省target Yes
basedir 用于计算所有其他\径的\径。该属性可以被basedir property覆盖。当覆盖Ӟ该属性被忽略。如果属性和basedir property都没有设定,׃用buildfile文g的父目录?No
目的描qC一个顶U的<description>元素的Ş式出玎ͼ参看description节Q?br>
一个项目可以定义一个或多个target。一个target是一pd你想要执行的。执行AntӞ你可以选择执行那个target。当没有l定targetӞ使用project的default属性所定的target?br>
3.2 Targets

一个target可以依赖于其他的target。例如,你可能会有一个target用于~译E序Q一个target用于生成可执行文件。你在生成可执行文g之前必须先编译通过Q所以生成可执行文g的target依赖于编译target。Ant会处理这U依赖关pR?br>
然而,应当注意刎ͼAnt的depends属性只指定了target应该被执行的序Q如果被依赖的target无法q行Q这Udepends对于指定了依赖关pȝtarget没有媄响?br>
Ant会依照depends属性中target出现的顺序(从左到右Q依ơ执行每个target。然而,要记住的是只要某个target依赖于一个targetQ后者就会被先执行?br><target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>
假定我们要执行target D。从它的依赖属性来看,你可能认为先执行CQ然后BQ最后A被执行。错了,C依赖于BQB依赖于AQ所以先执行AQ然后BQ然后CQ最后D被执行?br>
一个target只能被执行一ơ,x有多个target依赖于它Q看上面的例子)?br>
如果Q或如果不)某些属性被讑֮Q才执行某个target。这P允许Ҏpȝ的状态(java version, OS, 命o行属性定义等{)来更好地控制build的过E。要惌一个targetq样做,你就应该在target元素中,加入ifQ或unlessQ属性,带上target因该有所判断的属性。例如:
<target name="build-module-A" if="module-A-present"/>
<target name="build-own-fake-module-A" unless="module-A-present"/>
如果没有if或unless属性,targetM被执行?br>
可选的description属性可用来提供关于target的一行描qͼq些描述可由-projecthelp命o行选项输出?br>
你的tstamp task在一个所谓的初始化target是很好的做法Q其他的target依赖q个初始化target。要保初始化target是出现在其他target依赖表中的第一个target。在本手册中大多数的初始化target的名字是"init"?br>
target有下面的属性:
Attribute Description Required
name target的名?Yes
depends 用逗号分隔的target的名字列表,也就是依赖表?No
if 执行target所需要设定的属性名?No
unless 执行target需要清除设定的属性名?No
description 关于target功能的简短描q?No

3.3 Tasks

一个task是一D可执行的代码?br>
一个task可以有多个属性(如果你愿意的话,可以其UC为变量)。属性只可能包含对property的引用。这些引用会在task执行前被解析?br>
下面是Task的一般构造Ş式:
<name attribute1="value1" attribute2="value2" ... />
q里name是task的名字,attributeN是属性名QvalueN是属性倹{?br>
有一套内|的Qbuilt-inQtaskQ以及一些可选taskQ但你也可以~写自己的task?br>
所有的task都有一个task名字属性。Ant用属性值来产生日志信息?br>
可以ltask赋一个id属性:
<taskname id="taskID" ... />
q里taskname是task的名字,而taskID是这个task的唯一标识W。通过q个标识W,你可以在脚本中引用相应的task。例如,在脚本中你可以这P
<script ... >
task1.setFoo("bar");
</script>
讑֮某个task实例的foo属性。在另一个task中(用java~写Q,你可以利用下面的语句存取相应的实例?br>project.getReference("task1").
注意1Q如果task1q没有运行,׃会被生效Q例如:不设定属性)Q如果你在随后配|它Q你所作的一切都会被覆盖?br>
注意2Q未来的Ant版本可能不会兼容q里所提的属性,因ؓ很有可能Ҏ没有task实例Q只有proxies?br>
3.4 Properties

一个project可以有很多的properties。可以在buildfile中用property task来设定,或在Ant之外讑֮。一个property有一个名字和一个倹{property可用于task的属性倹{这是通过属性名攑֜"${"?}"之间q放在属性值的位置来实现的。例如如果有一个property builddir的值是"build"Q这个property可用于属性|${builddir}/classes。这个值就可被解析为build/classes?br>
内置属?br>
如果你用了<property> task 定义了所有的pȝ属性,Ant允许你用这些属性。例如,${os.name}对应操作pȝ的名字?br>
要想得到pȝ属性的列表可参考the Javadoc of System.getProperties?br>
除了Java的系l属性,Antq定义了一些自q内置属性:
basedir project基目录的l对路径 (?lt;project>的basedir属性一??br>ant.file buildfile的绝对\径?br>ant.version Ant的版本?br>ant.project.name 当前执行的project的名字;?lt;project>的name属性设?
ant.java.version Ant到的JVM的版本; 目前的值有"1.1", "1.2", "1.3" and "1.4".

例子
<project name="MyProject" default="dist" basedir=".">

<!-- set global properties for this build -->
<property name="src" value="."/>
<property name="build" value="build"/>
<property name="dist" value="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">
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>

<target name="dist" depends="compile">
<!-- 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">
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>

</project>
3.5 Path-like Structures
你可以用":"?;"作ؓ分隔W,指定cMPATH和CLASSPATH的引用。Ant会把分隔W{换ؓ当前pȝ所用的分隔W?br>
当需要指定类D\径的值时Q可以用嵌套元素。一般的形式?br><classpath>
<pathelement path="${classpath}"/>
<pathelement location="lib/helper.jar"/>
</classpath>
location属性指定了相对于project基目录的一个文件和目录Q而path属性接受逗号或分号分隔的一个位|列表。path属性一般用作预定义的\径-Q其他情况下Q应该用多个location属性?br>
为简zv见,classpath标签支持自己的path和location属性。所以:
<classpath>
<pathelement path="${classpath}"/>
</classpath>
可以被简写作Q?br><classpath path="${classpath}"/>
也可通过<fileset>元素指定路径。构成一个fileset的多个文件加入path-like structure的顺序是未定的?br><classpath>
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
</classpath>
上面的例子构造了一个\径值包括:${classpath}的\径,跟着lib目录下的所有jar文gQ接着是classes目录?br>
如果你想在多个task中用相同的path-like structureQ你可以?lt;path>元素定义他们Q与target同Q,然后通过id属性引用-Q参考Referencs例子?br>
path-like structure可能包括对另一个path-like structurede的引用(通过嵌套<path>元素Q:
<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>
前面所提的关于<classpath>的简z写法对?lt;path>也是有效的,如:
<path id="tests.path">
<path refid="base.path"/>
<pathelement location="testclasses"/>
</path>
可写成:
<path id="base.path" path="${classpath}"/>
命o行变?br>
有些task可接受参敎ͼq将其传递给另一个进E。ؓ了能在变量中包含I格字符Q可使用嵌套的arg元素?br>Attribute Description Required
value 一个命令行变量Q可包含I格字符?只能用一?br>line I格分隔的命令行变量列表?
file 作ؓ命o行变量的文g名;会被文g的绝对名替代?
path 一个作为单个命令行变量的path-like的字W串Q或作ؓ分隔W,Ant会将其{变ؓ特定q_的分隔符?

例子
<arg value="-l -a"/>
是一个含有空格的单个的命令行变量?br><arg line="-l -a"/>
是两个空格分隔的命o行变量?br><arg path="/dir;/dir2:\dir3"/>
是一个命令行变量Q其值在DOSpȝ上ؓ\dir;\dir2;\dir3Q在Unixpȝ上ؓ/dir:/dir2:/dir3 ?br>
References

buildfile元素的id属性可用来引用q些元素。如果你需要一遍遍的复制相同的XML代码块,q一属性就很有用-Q如多次使用<classpath>l构?br>
下面的例子:
<project ... >
<target ... >
<rmic ...>
<classpath>
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</classpath>
</rmic>
</target>
<target ... >
<javac ...>
<classpath>
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</classpath>
</javac>
</target>
</project>
可以写成如下形式Q?br><project ... >
<path id="project.class.path">
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</path>
<target ... >
<rmic ...>
<classpath refid="project.class.path"/>
</rmic>
</target>
<target ... >
<javac ...>
<classpath refid="project.class.path"/>
</javac>
</target>
</project>
所有用PatternSets, FileSets ?path-like structures嵌套元素的task也接受这U类型的引用?br>


4.1 FileQDirectoryQ类
4.1.1 Mkdir
? 创徏一个目录,如果他的父目录不存在Q也会被同时创徏?br>? 例子Q?br><mkdir dir="build/classes"/>
? 说明Q?如果build不存在,也会被同时创?br>4.1.2 Copy
? 拯一个(l)文g、目?br>? 例子Q?br>1. 拯单个的文Ӟ
<copy file="myfile.txt" tofile="mycopy.txt"/>
2. 拯单个的文件到指定目录?br><copy file="myfile.txt" todir="../some/other/dir"/>
3. 拯一个目录到另外一个目录下
<copy todir="../new/dir">
<fileset dir="src_dir"/>
</copy>
4. 拯一Ҏ件到指定目录?br><copy todir="../dest/dir">
<fileset dir="src_dir">
<exclude name="**/*.java"/>
</fileset>
</copy>

<copy todir="../dest/dir">
<fileset dir="src_dir" excludes="**/*.java"/>
</copy>
5. 拯一Ҏ件到指定目录下,文件名后增加。Bak后缀
<copy todir="../backup/dir">
<fileset dir="src_dir"/>
<mapper type="glob" from="*" to="*.bak"/>
</copy>
6. 拯一l文件到指定目录下,替换其中的@标签@内容
<copy todir="../backup/dir">
<fileset dir="src_dir"/>
<filterset>
<filter token="TITLE" value="Foo Bar"/>
</filterset>
</copy>
4.1.3 Delete
? 删除一个(l)文g或者目?br>? 例子
1. 删除一个文?br><delete file="/lib/ant.jar"/>
2. 删除指定目录及其子目?br><delete dir="lib"/>
3. 删除指定的一l文?br><delete>
<fileset dir="." includes="**/*.bak"/>
</delete>
4. 删除指定目录及其子目录,包括他自?br><delete includeEmptyDirs="true">
<fileset dir="build"/>
</delete>
4.1.4 Move
? Ud或重命名一个(l)文g、目?br>? 例子Q?br>1. Ud或重命名一个文?br><move file="file.orig" tofile="file.moved"/>
2. Ud或重命名一个文件到另一个文件夹下面
<move file="file.orig" todir="dir/to/move/to"/>
3. 一个目录移到另外一个目录下
<move todir="new/dir/to/move/to">
<fileset dir="src/dir"/>
</move>
4. 一l文件移动到另外的目录下
<move todir="some/new/dir">
<fileset dir="my/src/dir">
<include name="**/*.jar"/>
<exclude name="**/ant.jar"/>
</fileset>
</move>
5. Ud文gq程中增加。Bak后缀
<move todir="my/src/dir">
<fileset dir="my/src/dir">
<exclude name="**/*.bak"/>
</fileset>
<mapper type="glob" from="*" to="*.bak"/>
</move>




4.2 Java相关
4.2.1 Javac
? ~译java原代?br>? 例子
1. <javac srcdir="${src}"
destdir="${build}"
classpath="xyz.jar"
debug="on"
/>
~译${src}目录及其子目录下的所有。Java文gQ。Class文g放?{build}指定的目录下,classpath表示需要用到的cL件或者目录,debug讄为on表示输出debug信息
2. <javac srcdir="${src}:${src2}"
destdir="${build}"
includes="mypackage/p1/**,mypackage/p2/**"
excludes="mypackage/p1/testpackage/**"
classpath="xyz.jar"
debug="on"
/>
~译${src}?{src2}目录及其子目录下的所有。Java文gQ但是package/p1/**,mypackage/p2/**被~译Q而mypackage/p1/testpackage/**不会被~译。Class文g放?{build}指定的目录下,classpath表示需要用到的cL件或者目录,debug讄为on表示输出debug信息
3. <property name="classpath" value=".;./xml-apis.jar;../lib/xbean.jar;./easypo.jar"/>

<javac srcdir="${src}"
destdir="${src}"
classpath="${classpath}"
debug="on"
/>
路径是在property中定义的
4.2.2 java
? 执行指定的javac?br>

? 例子Q?br>1. <java classname="test.Main">
<classpath>
<pathelement location="dist/test.jar"/>
<pathelement path="${java.class.path}"/>
</classpath>
</java>
classname中指定要执行的类Qclasspath讑֮要用的环境变量
2. <path id="project.class.path">
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</path>

<target ... >
<rmic ...>
<classpath refid="project.class.path"/>
</rmic>
</target>





4.3 打包相关
4.3.1 jar
? 一l文件打?br>? 例子Q?br>1. <jar destfile="${dist}/lib/app.jar" basedir="${build}/classes"/>
?{build}/classes下面的所有文件打包到${dist}/lib/app.jar?br>2. <jar destfile="${dist}/lib/app.jar"
basedir="${build}/classes"
includes="mypackage/test/**"
excludes="**/Test.class"
/>
?{build}/classes下面的所有文件打包到${dist}/lib/app.jar中,但是包括mypackage/testQ所有文件不包括所有的Test.class
3. <jar destfile="${dist}/lib/app.jar"
basedir="${build}/classes"
includes="mypackage/test/**"
excludes="**/Test.class"
manifest=”my.mf”
/>
manifest属性指定自qMETA-INF/MANIFEST.MF文gQ而不是由pȝ生成
4.3.2 war
? 对Jar的扩展,用于打包Web应用
? 例子Q?br>? 假设我们的文件目录如下:
thirdparty/libs/jdbc1.jar
thirdparty/libs/jdbc2.jar
build/main/com/myco/myapp/Servlet.class
src/metadata/myapp.xml
src/html/myapp/index.html
src/jsp/myapp/front.jsp
src/graphics/images/gifs/small/logo.gif
src/graphics/images/gifs/large/logo.gif
? 下面是我们的d的内容:
<war destfile="myapp.war" webxml="src/metadata/myapp.xml">
<fileset dir="src/html/myapp"/>
<fileset dir="src/jsp/myapp"/>
<lib dir="thirdparty/libs">
<exclude name="jdbc1.jar"/>
</lib>
<classes dir="build/main"/>
<zipfileset dir="src/graphics/images/gifs"
prefix="images"/>
</war>
? 完成后的l果Q?br>WEB-INF/web.xml
WEB-INF/lib/jdbc2.jar
WEB-INF/classes/com/myco/myapp/Servlet.class
META-INF/MANIFEST.MF
index.html
front.jsp
images/small/logo.gif
images/large/logo.gif
4.3.3 ear
? 用于打包企业应用
? 例子
<ear destfile="${build.dir}/myapp.ear" appxml="${src.dir}/metadata/application.xml">
<fileset dir="${build.dir}" includes="*.jar,*.war"/>
</ear>



4.4 旉?br>在生成环境中使用当前旉和日期,以某U方式标记某个生成Q务的输出Q以便记录它是何时生成的Q这l常是可取的。这可能涉及~辑一个文Ӟ以便插入一个字W串来指定日期和旉Q或这个信息合q到 JAR ?zip 文g的文件名中?br>q种需要是通过单但是非常有用的 tstamp d来解决的。这个Q务通常在某ơ生成过E开始时调用Q比如在一?init 目标中。这个Q务不需要属性,许多情况下只需 <tstamp/> p够了?br>tstamp 不生Q何输出;相反Q它Ҏ当前pȝ旉和日期设|?Ant 属性。下面是 tstamp 讄的一些属性、对每个属性的说明Q以及这些属性可被设|到的值的例子Q?br>属?说明 例子
DSTAMP 讄为当前日期,默认格式为yyyymmdd 20031217
TSTAMP 讄为当前时_默认格式?hhmm 1603
TODAY 讄为当前日期,带完整的月䆾 2003 q?12 ?17 ?br>例如Q在前一节中,我们按如下方式创Z一?JAR 文gQ?br>
<jar destfile="package.jar" basedir="classes"/>

在调?tstamp d之后Q我们能够根据日期命名该 JAR 文gQ如下所C:

<jar destfile="package-${DSTAMP}.jar" basedir="classes"/>

因此Q如果这个Q务在 2003 q?12 ?17 日调用,?JAR 文g被命名?package-20031217.jar?br>q可以配|?tstamp d来设|不同的属性,应用一个当前时间之前或之后的时间偏U,或以不同的方式格式化该字W串。所有这些都是用一个嵌套的 format 元素来完成的Q如下所C:

<tstamp>
<format property="OFFSET_TIME"
pattern="HH:mm:ss"
offset="10" unit="minute"/>
</tstamp>

上面的清单将 OFFSET_TIME 属性设|ؓ距离当前旉 10 分钟之后的小时数、分钟数和秒数?br>用于定义格式字符串的字符?java.text.SimpleDateFormat cL定义的那些格式字W相?br>


4.5 执行SQL语句
? 通过jdbc执行SQL语句
? 例子Q?br>1. <sql
driver="org.gjt.mm.mysql.Driver"
url="jdbc:mysql://localhost:3306/mydb"
userid="root"
password="root"
src="data.sql"
/>
2. <sql
driver="org.database.jdbcDriver"
url="jdbc:database-url"
userid="sa"
password="pass"
src="data.sql"
rdbms="oracle"
version="8.1."
>
</sql>
只有在oracle、版本是8.1的时候才执行



4.6 发送邮?br>? 使用SMTP服务器发送邮?br>? 例子Q?br><mail mailhost="smtp.myisp.com" mailport="1025" subject="Test build">
<from address="me@myisp.com"/>
<to address="all@xyz.com"/>
<message>The ${buildname} nightly build has completed</message>
<fileset dir="dist">
<includes name="**/*.zip"/>
</fileset>
</mail>
? mailhostQ?SMTP服务器地址
? mailportQ?服务器端?br>? subjectQ?主题
? fromQ?发送h地址
? toQ?接受人地址
? messageQ?发送的消息
? filesetQ?讄附g


菠萝 2007-08-07 21:29 发表评论
]]>
Ant十五大最佛_?/title><link>http://m.tkk7.com/boluobn/articles/134828.html</link><dc:creator>菠萝</dc:creator><author>菠萝</author><pubDate>Mon, 06 Aug 2007 15:53:00 GMT</pubDate><guid>http://m.tkk7.com/boluobn/articles/134828.html</guid><wfw:comment>http://m.tkk7.com/boluobn/comments/134828.html</wfw:comment><comments>http://m.tkk7.com/boluobn/articles/134828.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/boluobn/comments/commentRss/134828.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/boluobn/services/trackbacks/134828.html</trackback:ping><description><![CDATA[<table style="WORD-BREAK: break-all" cellSpacing=0 cellPadding=0 width=700 align=center border=0> <tbody> <tr> <td align=middle height=25><font face=黑体 size=4></font></td> </tr> <tr bgColor=#f9f9f9> <td id=fontzoom style="LINE-HEIGHT: 200%"> <p align=center>作者:Eric M. Burke     来自Qonjava</p> <p>  ?<a target=_blank><u><font color=#0000ff>Ant</font></u></a> 出现之前Q构建和部vJava应用需要用包括特定^台的脚本、Make文g、各U版本的IDE甚至手工操作?#8220;大杂?#8221;。现在,几乎所有的开源Java目都在使用AntQ大多数公司的内部项目也在用Ant。Ant在这些项目中的广泛用自然导致了读者对一整套Ant最佛_늚q切需求?/p> <p>  本文ȝ了我喜爱的Ant技巧或最佛_践,多数是从我亲w经历的目错误或我听说的其他hl历?“恐?#8221;故事中得到灵感的。比如,有h告诉我有个项目把XDoclet 生成的代码放入带有锁定文件功能的版本控制工具中。当开发者修Ҏ代码Ӟ他必记住手工检出(Check outQƈ锁定所有将要重新生成的文g。然后,手工q行代码生成器,只到q时他才能够让Ant~译代码Q这一Ҏq存在如下一些问题:</p> <p>  ?生成的代码无法存储在版本控制pȝ中?<br>  ?AntQ本案例中是XdocletQ应该自动确定下一ơ构建涉及的源文Ӟ而不应由E序员手工确定?<br>  ?Ant的构建文件应该定义好正确的Q务依赖关p,q样E序员就不必Z完成构徏而不得不按照特定序调用d?</p> <p>  当我开始一个新目Ӟ我首先编写Ant构徏文g。Ant文g明确地定义构建的q程Qƈ被团队中的每个程序员使用。本文所列的技巧基于这L假定QAnt构徏文g是一个必Ml编写的重要文gQ它应在版本控制pȝ中得到维护,q被定期q行重构。下面是我的十五大Ant最佛_c?/p> <p>  <strong>1. 采用一致的~码规范</strong></p> <p>  Ant用户有的喜欢有的痛恨其构建文件的XML语法。与其蟩q这一令hqh的争ZQ不如让我们先看一些能保持XML构徏文gz的Ҏ?/p> <p>  首先也是最重要的,p旉格式化你的XML让它看上d清晰。不论XML是否观QAnt都可以工作。但是丑陋的XML很难令hL。倘若你在d之间留出IQ有规则的羃q,每行文字不超q?0列左叻I那么XML令h惊讶地易诅R再加上使用能够高亮XML语法的优U~辑器或IDE工具Q你׃会有阅读的麻烦?/p> <p>  同样Q精选含意明、容易读懂的词汇来命名Q务和属性。比如,dir.reports比rpts好。特定的~码规范q不重要Q只要拿Z套规范ƈ坚持使用p?/p> <p>  <strong>2. build.xml攑֜目根目录中</strong></p> <p>  Ant构徏文gbuild.xml可以攑֜M位置Q但是放在项目顶U目录中可以保持目z。这是最常用的规范,开发者能够在目录中找到预期的build.xml。把构徏文g攑֜根目录中Q也能够使hҎ了解目目录树中不同目录之间的逻辑关系。以下是一个典型的目目录层次Q?/p> <p style="BACKGROUND: #eeeeee">[root dir]<br>  | build.xml  <br>  +--src <br>  +--lib (包含W三?JAR? <br>  +--build (?buildd生成)  <br>  +--dist (?buildd生成) </p> <p>  当build.xml在顶U目录时Q假设你处于目某个子目录中Q只要输入:ant -find compile 命oQ不需要改变工作目录就能够以命令行方式~译代码。参?find告诉AntL存在于上U目录中的build.xmlq执行?/p> <p>  <strong>3. 使用单一的构建文?/strong></p> <p>  有h喜欢一个大目分解成几个小的构建文Ӟ每个构徏文g分担整个构徏q程的一部分工作。这实是看法不同的问题Q但是应该认识到Q将构徏文g分割会增加对整体构徏q程的理解难度。要注意在单一构徏文g能够清楚表现构徏层次的情况下不要q工E化(over-engineer)?/p> <p>  即你把目划分为多个构建文Ӟ也应使程序员能够在项目根目录下找到核心build.xml。尽该文g只是实际构建工作委z下构徏文gQ也应保证该文g可用?/p> <p>  <strong>4. 提供良好的帮助说?/strong></p> <p>  应尽量构徏文g自文档化。增加Q务描q是最单的Ҏ。当你输入ant -projecthelpӞ你就可以看到带有描述的Q务清单。比如,你可以这样定义Q务:</p> <p style="BACKGROUND: #eeeeee"><target name="compile"  <br>   description="Compiles code, output goes to the build dir."> </p> <p>  最单的规则是把所有你惌E序员通过命o行就可以调用的Q务都加上描述。对于一般用来执行中间处理过E的内部dQ比如生成代码或建立输出目录{,无法用描q属性?/p> <p>  q时Q可以通过在构建文件中加入XML注释来处理。或者专门定义一个helpdQ当E序员输入ant help时来昄详细的用说明?/p> <p style="BACKGROUND: #eeeeee"><target name="help" description="Display detailed usage information"><br>  <echo>Detailed help...</echo></target> </p> <p>  <strong>5. 提供清除d</strong></p> <p>  每个构徏文g都应包含一个清除Q务,用来删除所有生成的文g和目录,使系l回到构建文件执行前的初始状态。执行清IZQ务后q存在的文g都应处在版本控制pȝ的管理之下。比如:</p> <p style="BACKGROUND: #eeeeee"><target name="clean" <br>    description="Destroys all generated files and dirs."><br>  <delete dir="${dir.build}"/><br>  <delete dir="${dir.dist}"/><br></target> </p> <p>  除非是在产生整个pȝ版本的特DQ务中Q否则不要自动调用cleand。当E序员仅仅执行编译Q务或其他dӞ他们不需要构建文件事先执行既令h讨厌又没有必要的清空d。要怿E序员能够确定何旉要清I所有文件?/p> <p>  <strong>6. 使用ANT理d从属关系</strong></p> <p>  假设你的应用由Swing GUIlg、Web界面、EJB层和公共应用代码l成。在大型pȝ中,你需要清晰地定义每个Java包属于系l的哪一层。否则Q何一点修攚w要被q重新编译成百上千个文g。糟p的d从属关系理会导致过度复杂而脆qpȝ。改变GUI面板的设计不应造成Servlet和EJB的重~译?/p> <p>  当系l变得庞大后Q稍不注意就可能依赖于客户端的代码引入到服务端。这是因为典型的IDE目文g~译M文g都用单一的classpath。而Ant能让你更有效地控制构建活动?/p> <p>  设计你的Ant构徏文g~译大型目的步骤:首先Q编译公共应用代码,编译结果打成JAR包文件。然后,~译上一层的目代码Q编译时依靠W一步生的JAR文g。不断重复这一q程Q直到最高层的代码编译完成?/p> <p>  分步构徏强化了Q务从属关pȝ理。如果你工作在底层Java框架上,偶然引用到高层的GUI模板lgQ这时代码不需要编译。这是由于构建文件在~译底层框架时在源\径中没有包含高层GUI面板lg的代码?/p> <p>  <strong>7. 定义q用文件\?/strong></p> <p>  如果文g路径在一个地方一ơ性集中定义,q在整个构徏文g中得到重用,那么构徏文g更易于理解。以下是q样做的一个例子:</p> <p style="BACKGROUND: #eeeeee"><project name="sample" default="compile" basedir="."><br>  <path id="classpath.common"><br>    <pathelement location="${jdom.jar.withpath}"/><br>    ...etc  </path><br>  <path id="classpath.client"><br>    <pathelement location="${guistuff.jar.withpath}"/><br>    <pathelement location="${another.jar.withpath}"/><br>    <!-- reuse the common classpath --><br>    <path refid="classpath.common"/><br>  </path><br>  <target name="compile.common" depends="prepare"><br>    <javac destdir="${dir.build}" srcdir="${dir.src}"><br>          <classpath refid="classpath.common"/><br>          <include name="com/oreilly/common/**"/><br>    </javac><br>  </target><br></project> </p> <p>  当项目不断增长构建日益复杂时Q这一技术越发体现出其h倹{你可能需要ؓ~译不同层次的应用定义各自的文g路径Q比如运行单元测试的、运行应用程序的、运行Xdoclet的、生成JavaDocs的等{不同\径。这U组件化路径定义的方法比为每个Q务单独定义\径要优越得多。否则,很容易丢׃Q务从属关pȝ轨迹?/p> <p>  <strong>8. 定义恰当的Q务从属关p?/strong></p> <p>  假设distd从属于jardQ那么哪个Q务从属于compiled哪个d从属于prepared呢?Ant构徏文g最l定义了d的从属关pdQ它必须被仔l地定义和维护?/p> <p>  应该定期查Q务的从属关系以保证构建工作得到正执行。大的构建文仉着旉推移向于增加更多的dQ所以到最后可能由于不必要的从属关pd致构建工作非常困难。比如,你可能发现在E序员只需~译一些没有用EJB的GUI代码时又重新生成了EJB代码?/p> <p>  ?#8220;优化”的名义忽略Q务的从属关系是另一U常见的错误。这U错误迫使程序员Z得到恰当的结果必记住ƈ按照特定的顺序调用一串Q务。更好的做法是:提供描述清晰的公׃Q务,q些d包含正确的Q务从属关p;另外提供一?#8220;专家”d让你能够手工执行个别的构建步骤,q些d不提供完整的构徏q程Q但是让那些专家用户在快速而恼人的~码期间能够跌某些步骤?/p> <p>  <strong>9.使用属?/strong></p> <p>  M需要配|或可能发生变化的信息都应作为Ant属性定义下来。对于在构徏文g中多ơ出现的g同样处理。属性既可以在构建文件头部定义,也可以ؓ了更好的灉|性而在单独的属性文件中定义。以下是在构建文件中定义属性的样式Q?/p> <p style="BACKGROUND: #eeeeee"><project name="sample" default="compile" basedir="."><br>  <property name="dir.build" value="build"/><br>  <property name="dir.src" value="src"/><br>  <property name="jdom.home" value="../java-tools/jdom-b8"/><br>  <property name="jdom.jar" value="jdom.jar"/><br>  <property name="jdom.jar.withpath"<br>                    value="${jdom.home}/build/${jdom.jar}"/><br>    etc...<br></project> </p> <p>  或者你可以使用属性文Ӟ</p> <p style="BACKGROUND: #eeeeee"><project name="sample" default="compile" basedir="."><br>  <property file="sample.properties"/><br>   etc...<br></project> </p> <p>  在属性文?sample.properties?</p> <p style="BACKGROUND: #eeeeee">dir.build=build<br>dir.src=src<br>jdom.home=../java-tools/jdom-b8<br>jdom.jar=jdom.jarjdom.jar.withpath=${jdom.home}/build/${jdom.jar} </p> <p>  用一个独立的文g定义属性是有好处的Q它可以清晰地定义构Z的可配置部分。另外,在开发者工作在不同操作pȝ的情况下Q你可以在不同的q_上提供该文g的不同版本?/p> <p>  <strong>10. 保持构徏q程独立</strong></p> <p>  Z最大限度的扩展性,不要应用外部路径和库文g。最重要的是不要依赖于程序员的CLASSPATH讄。取而代之的是,在构建文件中使用相对路径q定义自q路径。如果你引用了绝对\径如C:\java\toolsQ其他开发者未必用与你相同的目录l构Q所以就无法使用你的构徏文g?/p> <p>  如果你部|开放源码项目,应该提供包含~译代码所需的所有JAR文g的发行版本。当Ӟq是在遵守许可协议的基础上。对于内部项目,相关的JAR文g都应在版本控制系l的理中,q捡出(check outQ到大家都知道的位置?/p> <p>  当你必须引用外部路径Ӟ应将路径定义为属性。ɽE序员能够用适合他们自己的机器环境的参数重蝲q些属性。你也可以用以下语法引用环境变量:</p> <p style="BACKGROUND: #eeeeee"><property environment="env"/><br><property name="dir.jboss" value="${env.JBOSS_HOME}"/> </p> <p>  <strong>11. 使用版本控制pȝ</strong></p> <p>  构徏文g是一个重要的制品Q应该像代码一栯行版本控制。当你标C的代码时Q也应用同样的标{标记构建文件。这样当你需要回溯到旧版本ƈq行构徏Ӟ能够使用相应版本的构建文件?/p> <p>  除构建文件之外,你还应在版本控制中维护第三方JAR文g。同Pq你能够重新构建旧版本的Y件。这也能够更Ҏ保证所有开发者拥有一致的JAR文gQ因Z们都是同构徏文g一起从版本控制pȝ中捡出的?/p> <p>  通常应避免在版本控制pȝ中存放构建成果。倘若你的源代码很好地得到了版本控Ӟ那么通过构徏q程你能够重新生成Q何版本的产品?/p> <p>  <strong>12. 把Ant作ؓ“最公分母”</strong></p> <p>  假设你的开发团队用IDE工具Q当E序员通过点击图标p够构建整个应用时Z么还要ؓAnt而烦恼呢Q?/p> <p>  IDE的问题是一个关于团队一致性和重现性的问题。几乎所有的IDE设计初衷都是Z提高E序员的个h生率,而不是开发团队的持箋构徏。典型的IDE要求每个E序员定义自q目文g。程序员可能拥有不同的目录结构,可能使用不同版本的库文gQ还可能工作在不同的q_上。这导致出现这U情况:在Bob那里q行良好的代码,到Sally那里无法运行?/p> <p>  不管你的开发团队用何UIDEQ一定要建立所有程序员都能够用的Ant构徏文g。要建立一个程序员在将C码提交版本控制系l前必须执行Ant构徏文g的规则。这确保代码是l过同一个Ant构徏文g构徏的。当出现问题Ӟ要用项目标准的Ant构徏文gQ而不是通过某个IDE来执行一个干净的构建?/p> <p>  E序员可以自由选择M他们习惯使用的IDE工具或编辑器。但是Ant应作为公共基U以保证代码永远是可构徏的?/p> <p>  <strong>13. 使用zipfileset属?/strong></p> <p>  Zl常使用Ant产生WAR、JAR、ZIP?EAR文g。这些文仉常都要求有一个特定的内部目录l构Q但其往往与你的源代码和编译环境的目录l构不匹配?/p> <p>  一个最常用的方法是写一个AntdQ按照期望的目录l构把一大堆文g拯C时目录中Q然后生成压~文件。这不是最有效的方法。用zipfileset属性是更好的解x案。它让你从Q何位|选择文gQ然后把它们按照不同目录l构放进压羃文g中。以下是一个例子:</p> <p style="BACKGROUND: #eeeeee"><ear earfile="${dir.dist.server}/payroll.ear"<br>    appxml="${dir.resources}/application.xml"><br>  <fileset dir="${dir.build}" includes="commonServer.jar"/><br>  <fileset dir="${dir.build}"><br>    <include name="payroll-ejb.jar"/><br>  </fileset><br>  <zipfileset dir="${dir.build}" prefix="lib"><br>    <include name="hr.jar"/><br>    <include name="billing.jar"/><br>  </zipfileset><br>  <fileset dir="."><br>    <include name="lib/jdom.jar"/><br>    <include name="lib/log4j.jar"/><br>    <include name="lib/ojdbc14.jar"/><br>  </fileset><br>  <zipfileset dir="${dir.generated.src}" prefix="META-INF"><br>    <include name="jboss-app.xml"/><br>  </zipfileset><br></ear> </p> <p>  在这个例子中Q所有JAR文g都放在EAR文g包的lib目录中。hr.jar和billing.jar是从构徏目录拯q来的。因此我们用zipfileset属性把它们Ud到EAR文g包内部的lib目录。prefix属性指定了其在EAR文g中的目标路径?/p> <p>  <strong>14. 试Cleand</strong></p> <p>  假设你的构徏文g中有clean和compile的Q务,执行以下的测试。第一步,执行ant cleanQ第二步Q执行ant compileQ第三步Q再执行ant compile。第三步应该不作M事情。如果文件再ơ被~译Q说明你的构建文件有问题?/p> <p>  构徏文g应该只在与输出文件相兌的输入文件发生变化时执行d。一个构建文件在不必执行诸如~译、拷贝或其他工作d的时候执行这些Q务是低效的。当目规模增长Ӟ即是小的低效工作也会成为大的问题?/p> <p>  <strong>15. 避免特定q_的Ant装</strong></p> <p>  不管什么原因,有h喜欢用简单的、名U叫做compile之类的批文g或脚本装载他们的产品。当你去看脚本的内容你会发现以下内容Q?/p> <p style="BACKGROUND: #eeeeee">  ant compile</p> <p>  其实开发h员都很熟悉AntQƈ且完全能够自己键入ant compile。请不要仅仅Z调用Ant而用特定^台的脚本。这只会使其他h在首ơ用你的脚本时增加学习和理解的烦扰。除此之外,你不可能提供适用于每个操作系l的脚本Q这是真正烦扰其他用L地方?/p> <p>  <strong>ȝ</strong></p> <p>  太多的公怾靠手工方法和特别E序来编译代码和生成软g发布版本。那些不使用Ant或类似工具定义构E的开发团队,p了太多的旉来捕捉代码编译过E中出现的问题:在某些开发者那里编译成功的代码Q到另一些开发者那里却p|了?/p> <p>  生成q维护构本不是一富有魅力的工作Q但却是一必需的工作。一个好的Ant构徏文g你能够集中到更喜Ƣ的工作——写代码中去Q?/p> <p>  <strong>参?/strong></p> <p>  ?<a target=_blank><u><font color=#0000ff>http://ant.apache.org/</font></u></a>  Ant<br>  ?<a target=_blank><u><font color=#0000ff>http://www.ericburke.com/</font></u></a>  AntGraph: Ant依赖性的可视化工?<br>  ?<a target=_blank><u><font color=#0000ff>http://www.oreilly.com/catalog/anttdg/index.html?CMP=IL7015</font></u></a>  Ant: The Definitive Guide, O'Reilly <br>  ?<a target=_blank><u><font color=#0000ff>http://www.oreilly.com/catalog/jextprockbk/index.html?CMP=IL7015</font></u></a>  Java Extreme Programming Cookbook, O'Reilly</p> <p>  原文Q?a target=_blank><u><font color=#0000ff>http://www.onjava.com/pub/a/onjava/2003/12/17/ant_bestpractices.html</font></u></a><br>  译Q徐?MSN:xt121@hotmail.com</p> </td> </tr> </tbody> </table> <img src ="http://m.tkk7.com/boluobn/aggbug/134828.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/boluobn/" target="_blank">菠萝</a> 2007-08-06 23:53 <a href="http://m.tkk7.com/boluobn/articles/134828.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://m.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://99999pp.com" target="_blank">91޾Ʒר</a>| <a href="http://c7vl.com" target="_blank">С˵</a>| <a href="http://45-po.com" target="_blank">ĻӰԺַ</a>| <a href="http://jiujiujingpin.com" target="_blank">99޾Ʒ242</a>| <a href="http://w5524.com" target="_blank">˳ɫ77777߹ۿ </a>| <a href="http://jybelt.com" target="_blank">һ</a>| <a href="http://xsdin.com" target="_blank">޵ӰĻ</a>| <a href="http://html5text.com" target="_blank">ѹۿëƬֻƵ</a>| <a href="http://xacfdq.com" target="_blank">ƷƵ</a>| <a href="http://8888kkk.com" target="_blank">ŷ޹Ʒ㽶</a>| <a href="http://988938.com" target="_blank">ŮŮվѿ</a>| <a href="http://wwyw99977.com" target="_blank">㽶Ѳ</a>| <a href="http://zuahowan.com" target="_blank">ŷպһ</a>| <a href="http://by23336.com" target="_blank">ƷŮߵӰ </a>| <a href="http://youtobey.com" target="_blank">Ƶ߹ۿ</a>| <a href="http://yese889.com" target="_blank">޳AVƬWWWɫè</a>| <a href="http://dazngt.com" target="_blank">һһëƬa</a>| <a href="http://xseporn.com" target="_blank">ƬվɫƬѹۿcn </a>| <a href="http://bb9234.com" target="_blank">aѦƬƵվ </a>| <a href="http://jggbk.com" target="_blank">һѹۿ</a>| <a href="http://321fafa.com" target="_blank">ƷһëƬ</a>| <a href="http://mlhcd.com" target="_blank">Ʒa߹ۿ</a>| <a href="http://www664660a.com" target="_blank">ŷëƬAƵ޷</a>| <a href="http://502274.com" target="_blank">99reƵ</a>| <a href="http://www65axax.com" target="_blank">޾ƷպAV</a>| <a href="http://nmgqsyg.com" target="_blank">޳aƬ߹</a>| <a href="http://www-333346.com" target="_blank">þAAAƬ69</a>| <a href="http://qinglou31.com" target="_blank">Ʒjizz߹ۿ</a>| <a href="http://xsdggzs.com" target="_blank">6080ҹһëƬѿ</a>| <a href="http://bjjs365.com" target="_blank">jizz߹ۿ</a>| <a href="http://www77714.com" target="_blank">AV˾Ʒһ</a>| <a href="http://hjndgb.com" target="_blank">˳ַ߹ۿ</a>| <a href="http://hkcdk.com" target="_blank">޾Ʒ</a>| <a href="http://xixidhw.com" target="_blank">Ʒҹѹۿ</a>| <a href="http://mtripmall.com" target="_blank">ԻȫƵַ</a>| <a href="http://sd-ll.com" target="_blank">Ůվ߹ۿƵѵ</a>| <a href="http://km9c.com" target="_blank">޹Ʒ߹ۿ</a>| <a href="http://www-135888.com" target="_blank">ҹδʮ</a>| <a href="http://xiaojiejieav.com" target="_blank">߹ۿ޳</a>| <a href="http://wwwfac286.com" target="_blank">˳Ƶx8x8</a>| <a href="http://huahui1866.com" target="_blank">ԸŮƵվҹ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>