ant的模块化以及java调用

来源:互联网 发布:树莓派 linux游戏 编辑:程序博客网 时间:2024/06/04 19:32

所有的语言都有维护和代码重用的压力,目前为止,Ant已经提供了很多的Task,可以帮助实现Ant脚本的模块化。

 1. Property
  Property Task除了能够定义单个的属性,还可以从一个属性定义文件定义多个property。把公用的属性放到属性文件中,各个build.xml中都载入此属性文件,就可以避免在每个build.xml中重复定义这些属性。

2. AntCall, Ant和SubAnt
  AntCall可以理解为简单的函数调用。举一个例子就清楚了:
  

<target name=”commonTarget”>   <echo message=”${test.param}” />  </target>     <target name=”callingTarget”>   <antcall target="commonTarget">   <param name="test.param" value="Modulation" />   </antcall>   </target>


  从上面的例子可以看到,指明要调用的target,再通过<param>指明调用参数;在被调用的Target中,通过与引用property类似的方式即可引用param的值。
  至于Ant Target,也是调用别的Target,不过那个Target可以是在另外一个ant 文件中。

 3. MacroDef
  AntCall很好用,不过当参数很多时要写很多的<param name=”” value=”” />起来很麻烦,如果你想偷懒,用MacroDef就行了。下面把上面的例子用MacroDef重写:
  

 <macrodef name="showModule">这里是macrodef的定义   <attribute name="test.param1"/>这个是参数的定义,可以再macrodef外部调用   <attribute name="test.param" default="NOT SET"/>内部参数   <sequential>实际执行的内容都在sequential中   <echo message="@{test.param}" />   </sequential>   </macrodef>      <target name="testMacro">   <showModule test.param="Modulation" />   </target>

需要注意的是:

1,在整个build文件里macrodef和target是平级的。

2,macrodef可以调用其他的macrodef,不可以调用target;target可以调用macrodef,也可以调用其他的target。

3,macrodef嵌套的时候,参数名称必须不同。

我们可以象系统提供的其他Task一样引用showModule,的确简洁多了。定义一个Macro,首先定义此宏的attribute,包括attribute的name, default;然后在<sequential>标签中定义此宏的所有操作。注意对attribute的引用是@{attr-name}!实际上,Ant还允许在attribute后面定义一组element,达到极高的动态性。


4. Import
  <antcall>和<marcodef>可以达到类似函数的效果,但是调用者和被调用者还是必须在同一个文件中。Ant从1.6开始引入Import Task,可以真正的实现代码重用:属性,Task 定义,Task, Macro。一个简单的例子:
   
  common.xml:
  

<?xml version="1.0" ?>  <project>   <property name="project.name" value="Ant Modulazation" />      <target name="commonTarget">   <echo message="${test.param}" />   </target>      <macrodef name="showModule">   <attribute name="test.param" default="NOT SET"/>   <sequential>   <echo message="@{test.param}" />   </sequential>   </macrodef>     </project>   


  call.xml:
  
<?xml version="1.0" ?>  <project name="testCommon" default="callingTarget">   <import file="common.xml" />      <target name="callingTarget">   <antcall target="commonTarget">   <param name="test.param" value="Modulation" />   </antcall>   </target>      <target name="testMacro">   <showModule test.param="Modulation" />   </target>  </project>


注意:在common.xml中,不能对project元素设置属性;另外,不要试图使用重名的property,或target以获取覆盖的效果,因为Ant毕竟不是编程语言。


自定义Ant Taskhttp://blog.csdn.net/pipisky2006/article/details/6680379

这里只有task,也可以创建project对象,写一个纯code的build

1:基本环境,建议用Eclipse这个工具来做为Java的基本开发工具,用Eclipse的向导新建一个Java工程test。


2:将ANT的以下几个jar文件添加到刚才新建的test工程的构建引用路径下面,即添加到classpath中去:ant-lanucher.jar、ant.jar、ant-jakarta-log4j.jar这三个jar文件是最基本的,必须添加进去,如果要用到ANT的一些其它类,需要添加相应的jar文件,具体可以参考ANT的帮助文件。这三个文件简单说明一下,ant-lanucher.jar里面的类是ANT程序启动时必须要用到的,在Java代码中调ANT时,是需要通过这个包中的类来启动ANT里面的类去执行定义的动作,这个包是启动入口类; ant.jar这个包里面是ant定义的一些核心功能类的class,如copy文件,删除文件,执行数据库脚本,打包等等,即是具体的核心功能实现类,如果是一些附加的ant功能,则在其它jar包里面,这个只有非常核心的类在里面; ant-jakarta-log4j.jar是ant重新包装了log4j的类,实现ANT自己格式的log4j的日志文件记录。


3:在test工程里面新建一个类,类里面增加一个Java的main方法,在main方法中添加如下代码,并导入相关的package:

PrintStream logstream = null; //这里是定义一个ANT执行时日志文件的输出流对象Project pj=new Project(); //初始化一个ant的Project对象pl.setName("ant_project"); //设置project的名称,具体的值可以随意改成其它字符串都可以pj.init(); //ANT自己的方法初始化Project对象
DefaultLogger cl=new DefaultLogger(); //定义一个默认的日志流,默认的日志流是采用log4j来记录的,所以在前面要求将ant-jakarta-log4j.jar这个文件加到classpath中去。logstream=new PrintStream(new FileOutputStream("C:/test.log"),true);//下面两行是设置ANT执行过程中要输出的一些信息流,必须设置,否则后面将得不到具体的日志消息cl.setErrorPrintStream(logstream);cl.setOutputPrintStream(logstream);//设置ANT记录日志的消息级别,MSG_VERBOSE是表示记录详细的日志消息cl.setMessageOutputLevel(Project.MSG_VERBOSE);//将前面定义好的消息记录器绑定到Project上pj.addBuildListenter(cl);//生成一个Target对象,为后面添加具体的Task做准备Target tg=new Target();tg.setProject(pj); //设置target的Project归属,必须设置,Target必须属于某一个Projecttg.setName("target1"); //设置Target的名称pj.addTarget(tg); //将Target添加到Project中Copy cp=new Copy(); //具体生成一个功能Task类对象,复制文件的对象cp.setTodir(new File("C:/bbb")); //设置要将文件复制的目的地FileSet set=new FileSet(); //定义目录集,这样在后面可以自己定义一些规则set.setDir(new File("C:/aaa")); //定义目录集关联的实际目录路径set.createInclude().setName("**/*.txt"); //设置这个目录集包括的规则,即这个目录下面所有的.txt后缀的文件cp.addFileset(set); //将目录集绑定到具体的对象中cp.setOverwrite(true);//设置在复制文件时,如果目标文件己经存在,将采用直接覆盖的方式cp.setFailOnError(true); //设置在复制文件过程中有文件复制失败时,则中断执行这个过程cp.setPreserveLastModified(true); //设置复制文件时保留文件的最后修改时间cp.setProject(pj); //设置Task的Project归属cp.setTaskName("cp"); //设置Task的名称tg.addTask(cp); //将Task添加到Target中,Task不能单独存在,也不能直接添加到Project中Throwable ta=null;try {pj.executeTarget(tg.getName()); //开始执行Project中指定的Target}catch (Exception e){ta=e;} finally {/*    在日志文件当中生成执行成功或失败的消息,调用这个方法后,如果ANT的Project执行成功,则会在日志文件当中生成一行“BUILD SUCCESSFUL”或"BUILD FAILED"这样的字符串,在执行失败时,同时会将异常消息打印在日志文件中,所以这个方法比较重要   */pj.fireBuildFinished(ta);logstream.close();}


转自:http://blog.csdn.net/pipisky2006/article/details/7101778


0 0