2018-08-29 01:50:59 +0000   |     tools git ant   |   Viewed times   |    

这是一个用ant来编译,部署,执行一个小型项目的Demo

代码一多,用shell脚本编译部署就有点吃力了。这是一个系列,试用3个最常用的部署工具,

  1. ant
  2. maven
  3. gradle

这是其中ant的Demo。

安装Ant

如果未安装Ant,从下面地址下载最新的安装包,

http://ant.apache.org

解压,

tar -vxzf apache-ant-1.10.5-bin.tar.gz

Linux系统复制到下面路径,

/usr/local/

一般来说,/usr/bin存放系统预装的程序,/usr/local/bin存放用户自己安装的程序。但Ant安装包里的程序数量较多,如果不想给/usr/local/bin制造混乱,最好将解压以后的apache-ant-1.10.5包直接放在/usr/local/路径下,所以最终ant程序的绝对路径为,

/usr/local/apache-ant-1.10.5/bin

修改~/.bash_profile,把上面这个路径添加到环境变量PATH

export ANT_HOME="/usr/local/apache-ant-1.10.5"
export PATH="${ANT_HOME}/bin:${PATH}"

因为我用的是zsh,还需要在改一下~/.zshrc,方法不变。重启终端后,输入下面命令检查,

ant -version

看到如下显示,说明安装完成,

Apache Ant(TM) version 1.10.5 compiled on July 10 2018

创建一个简单计算器项目

项目只有一个Calculator.java类,以及一个Antbuild.xml构建文件,具体拓扑如下,

.
├── bin
│   └── com
│       └── ciaoshen
│           └── ant
│               └── demo
│                   └── Calculator.class
├── build.xml
├── lib
└── src
    ├── main
    │   └── com
    │       └── ciaoshen
    │           └── ant
    │               └── demo
    │                   └── Calculator.java
    └── test
        └── com
            └── ciaoshen
                └── ant
                    └── demo

源代码在src文件夹下,类文件在bin文件夹。项目源代码和测试代码分开放,项目代码在src/main路径下,而src/test是预留给以后Junit测试类源码的。项目源代码和测试类代码属于同一个包com.ciaoshen.ant.demo

Calculator.java是一个最简单的只能做加减乘除的计算器。main()函数里运行一个简单的测试。

package com.ciaoshen.ant.demo;
import java.util.Random;

public class Calculator {

    public static int add(int a, int b) {
        return a + b;
    }
    public static int minus(int a, int b) {
		return a - b;
	}
	public static int multiply(int a, int b) {
		return a * b;
	}
    public static int divide(int a, int b) {
        if (b == 0) {
            throw new IllegalArgumentException("Dividor can not be 0! Your param a = " + a + ", b = " + b);
        }
		return a / b;
	}

    // traditional unit test
    private static void test(int a, int b) {
        System.out.println(a + " + " + b + " = " + add(a,b) + "\t[answer=" + (a + b) + "]");
        System.out.println(a + " - " + b + " = " + minus(a,b) + "\t[answer=" + (a - b) + "]");
        System.out.println(a + " * " + b + " = " + multiply(a,b) + "\t[answer=" + (a * b) + "]");
        int quotient = divide(a,b);
        if (b != 0) {
            System.out.println(a + " / " + b + " = " + divide(a,b) + "\t[answer=" + (a / b) + "]");
        } else {
            System.out.println(a + " / " + b + " = " + divide(a,b) + "\t[ERR: should throw IllegalArgumentException!]");
        }
    }

    public static void main(String[] args) {
        int max = 1000;
        Random r = new Random();
        test(r.nextInt(max), r.nextInt(max) + 1);
    }
}

部署的规则都写在build.xml文件里。它其实很简单,就做了2件事,

  1. 定义环境变量(主要是路径)
  2. 定义像编译,运行,清理等这些目标任务以及他们之间的依赖关系

定义变量主要用<property>标签,

<target>标签封装了像“编译”,“执行”,“清理”等一系列具体的任务,

另外还定义了两条不同的主线任务来串联这些任务,

还有一些内置标签很重要。

  1. <javac>
  2. <java>
  3. <mkdir>
  4. <echo>

从这些标签可以看出来,ant只是让我们可以用XML来配置环境参数以及依赖关系,ant负责把这些配置收集起来,统一执行shell脚本。本质上和我用shell脚本部署项目是一样的。

<?xml version="1.0"?>
<project name="Ant Demo" basedir="." default="traditional">
    <!-- project meta info -->
    <property name="ant.file" value="./build.xml"/>
    <property name="ant.home" value="/usr/local/apache-ant-1.10.5"/>
    <property name="ant.version" value="1.10.5"/>
    <!-- main path -->
    <property name="main.dir" value="src/main"/>
    <property name="test.dir" value="src/test"/>
    <property name="bin.dir" value="bin"/>
    <property name="lib.dir" value="lib"/>
    <!-- entry points -->
    <property name="traditional.entry" value="com.ciaoshen.ant.demo.Calculator"/>
    <property name="junit.entry" value="com.ciaoshen.ant.demo.CalculatorTest/"/>

    <!-- build classpath collection with a path-like structure -->
    <path id="build.classpath">
        <pathelement path="${bin.dir}"/>
        <fileset dir="${lib.dir}">
            <include name="*.jar"/>
        </fileset>
    </path>

    <!-- targets -->
    <target name="traditional"
        depends="info,compile,traditional.exec">
        <echo>Finish!</echo>
    </target>
    <target name="junit"
        depends="info,compile,junit.exec">
    </target>
    <target name="info">
        <echo>This is ${project-name}!</echo>
    </target>
    <target name="compile" description="Compile java source codes.">
        <echo>Compile .java source file under ${main.dir}!</echo>
        <mkdir dir="${bin.dir}"/>
        <javac destdir="${bin.dir}" srcdir="${main.dir}" source="1.6" debug="on" includeantruntime="false">
            <include name="**/*.java"/>
            <classpath refid="build.classpath"/>
        </javac>
    </target>
    <target name="traditional.exec" description="Launch traditional test.">
        <echo>Run ${traditional.entry}!</echo>
        <java classname="${traditional.entry}">
            <classpath refid="build.classpath"/>
        </java>
    </target>
    <target name="junit.exec" description="Launch Junit test.">
        <echo>Run ${junit.entry}!</echo>
        <java classname="${junit.entry}">
            <classpath refid="build.classpath"/>
        </java>
    </target>
    <target name="clean" description="Clean output directories.">
        <delete>
            <fileset dir="${bin.dir}">
                <include name="**/*.class"/>
            </fileset>
        </delete>
    </target>
</project>