Antx的由来:
<path id="classpath"> <fileset dir="${lib}" includes="*.jar"/> </path> <mkdir dir="${target.classes}"/> <javac srcdir="${src.java}" destdir="${target.classes}" debug="true" optimize="true" deprecation="true" encoding="GBK" source="1.4" target="1.4"> <classpath refid="classpath"/> </javac>
目标是管理:所有jar、war、ear等二进制包,及它们的依赖关系
实战之前,先安装Antx:
svn co http://svn.alibaba-inc.com/repos/opentech/antx/trunk/ antx
antx gen
myproject
│ project.jelly - 项目脚本文件
│ project.xml - 项目描述文件
│
├─docs - 文档目录
│
└─src - 源代码目录
└─java - Java源代码目录
定义一个简单的Antx项目:修改project.xml:
<project id="my/project"> <build> <dependencies> <include uri="jakarta/commons/lang"/> </dependencies> </build> </project>
定义一个简单的Antx项目:添加Java类:
package com.alibaba.myproject;
import org.apache.commons.lang.SystemUtils;
public class MyClass {
public String getGreeting() {
return "hello, " + SystemUtils.USER_NAME;
}
}
定义一个简单的Antx项目:build项目:
java:compile:
[mkdir] Created dir: C:\myproject\target\classes
[javac] Compiling 1 source file to C:\myproject\target\classes
jar:jar:
[jar] Building jar: C:\myproject\target\my-project.jar
<project default="jar">
</project>
package com.alibaba.myproject; import junit.framework.TestCase; public class MyClassTest extends TestCase { private MyClass myClass; protected void setUp() { myClass = new MyClass(); } public void testGetGreeting() { assertEquals("hello, " + System.getProperty("user.name"), myClass.getGreeting()); } }
定义一个简单的Antx项目:执行单元测试:
在myproject目录下, 执行:antx test [mkdir] Created dir: C:\myproject\target\test.report [junit] Running com.alibaba.myproject.MyClassTest [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.01 sec
定义一个简单的Antx项目:用Eclipse来开发:
在myproject目录下, antx eclipse eclipse:project: [echo] Creating C:\myproject/.project ... eclipse:classpath: [echo] Creating C:\myproject/.classpath ... eclipse: [echo] 如果您现在正在使用eclipse,请在project上点击鼠标右键,选择“Refresh”以便刷新项目 在Eclipse中import项目 选择Existing projects into workspace
标准目标结构简介:
myproject │ project.jelly - 项目脚本文件 │ project.xml - 项目描述文件 ├─docs - 文档目录 ├─src - 源目录 │ ├─descriptors - JEE描述符 │ │ ├─ear - application.xml │ │ ├─ejb - ejb-jar.xml │ │ ├─rar - ra.xml │ │ └─web - web.xml │ ├─java - Java代码目录 │ ├─java.test - Java测试代码目录 │ ├─conf - 配置文件目录 │ ├─conf.test - 用于测试的配置文件目录 │ └─webroot - Webapp根目录 │ ├─templates - webx模板目录 │ └─WEB-INF - 标准WEB-INF目录 └─target - 目标目录 └─classes - Java类二进制文件目录
中心Repository——项目的弹药库:
重新看project.xml <dependencies> <include uri="jakarta/commons/lang"/> </dependencies> 这个jakarta/commons/lang是什么意思? 指向repository中的类库的URI 全称为:jar:jakarta/commons/lang,类似还有:war:、ejb:、car:、ear:、rar: 请看antx\repository\jakarta\commons\lang目录 其中的module.xml文件定义了jar包的位置、源代码、javadoc的位置、依赖性等信息。
项目之间的依赖:创建项目2:
让我们创建另一个项目:myproject2 <project id="my/project2"> <build> <dependencies> <include uri="my/project"/> </dependencies> </build> </project>
项目之间的依赖:创建类:
在src/java目录下, 创建package: com\alibaba\myproject2 创建类文件:MyClass2.java package com.alibaba.myproject2; import com.alibaba.myproject.MyClass; public class MyClass2 { public static void main(String[] args) { System.out.println(new MyClass().getGreeting()); } }
项目之间的依赖:编译并运行:
在myproject2目录下 执行:antx 试运行命令: java –cp \myproject2\target\my-project2.jar; \myproject\target\my-project.jar; \antx\repository\jakarta\commons\lang\commons-lang-2.1.jar com.alibaba.myproject2.MyClass2 结果:hello, baobao
project2怎么找到project1的jar:
答案就是:通过repository 请看$HOME\.antx\repository目录 有一个my\project\module.xml文件,告诉project2: 去哪里取得uri="my/project"的jar包 注意: 两个project的源目录之间没有任何关系 两个project只通过repository来通信 不得循环依赖 project1必须在project2之前被build project2间接依赖project1所依赖的一切
多项目开发模式的优点:
可以在$HOME\antx.properties中改变默认值: antx.repository.project=YOUR_2ND_REPO_PATH 取得toolkit类库 进入$HOME\.antx\repository.project目录(或者你所指定的YOUR_2ND_REPO_PATH目录) 执行: svn co http://svn.toolkit.alibaba-inc.com/trunk/binary-release/toolkit 在项目中使用toolkit 在project.xml中写: <dependencies> <include uri="toolkit/webx/turbine"/> </dependencies>
改良多项目开发的模式:推荐的多项目目录结构:
以Taobao网站为例(红色代表子项目,其中包含project.xml和project.jelly文件) taobao │ project.xml - 总控项目描述文件 │ ├─common - 共享utils子项目 │ └─util default goal:jar ├─dal - 数据访问层子项目,default goal:jar ├─biz - 业务层子项目 │ ├─auction default goal:jar,deps:common/dal,common/util │ └─member default goal:jar,deps:common/dal,common/util ├─web - WEB表现层子项目 │ ├─auction default goal:car,deps:biz/auction │ └─member default goal:car,deps:biz/member ├─bundle - 将所有项目打成一个war或ear的子项目 │ └─war default goal:war,deps:car:web/auction,car:web/member └─deploy - 布署环境子项目 default goal:deploy,deps:war:bundle/war
改良多项目开发的模式:简化project.xml:
一组相关的子项目,通常会有类似的项目定义 为了简化,可以这样写: <project id="taobao/dal" extends="../project.xml"> <build> <dependencies> … </dependencies> </build> </project>
改良多项目开发的模式:总控project.xml:
<project id="taobao/all" abstract="true"> <currentVersion>1.0</currentVersion> <build> <property name="java.compiler.source" value="1.5"/> <property name="java.compiler.target" value="1.5"/> </build> <projects name="taobao" version="1.0"> <project id="taobao/common/util" dir="common/util"/> <project id="taobao/dal" dir="dal"/> <project id="taobao/biz/auction" dir="biz/auction"/> <project id="taobao/biz/member" dir="biz/member"/> <project id="taobao/web/auction" dir="web/auction"/> <project id="taobao/web/member" dir="web/member"/> <project id="taobao/bundle/war" dir="bundle/war"/> <project id="taobao/deploy" dir="deploy"/> </projects> <projects name="toolkit-common" version="1.0"> <project id="toolkit/common/lang"/> ... </projects> <projects name="toolkit-webx" version="2.0"> <project id="toolkit/webx/framework"/> ... </projects> </project>
改良多项目开发的模式:build所有项目:
在总项目的根目录下,执行: antx reactor 反应堆:reactor,也可以理解为foreach project 自动扫描目录,找出所有非abstract的project.xml 分析其中的依赖关系,排出build顺序 例如:项目A依赖项目B,则B排在A之前 依次执行每个项目的build指令 Reactor命令的格式 antx reactor goals=指令1,指令2,… projects=项目ID1,项目ID2,… nodeps=true|false goals参数代表要对每个项目执行的指令, 如果省略或值为“default”表示执行project.jelly中定义的default goal。 projects参数代表要build的项目ID, 如果省略,表示build所有项目。 注意,项目所依赖的项目也会被build,除非指定了nodeps=true。 nodeps=true时,不build项目所依赖的其它项目。 你必须自己负责依赖关系。 如果省略,表示nodeps=false。
改良多项目开发的模式:Reactor图解:
改良多项目开发的模式:在eclipse中开发多项目:
antx reactor
antx reactor goals=clean,default
antx reactor goals=eclipse,default
antx reactor projects=project1,project2 nodeps=true
antx–p RELEASE reactor
改良多项目开发的模式:多team合作图:
改进Antx的性能:
Antx启动很慢,是什么原因? 装载repository 装载project 解决方案 Lazy-loading repository 已解决 Antx Console antx –c 原理很简单:执行完后不退出,第二次执行就很快了 使用Antx eclipse插件 http://svn.alibaba-inc.com/repos/opentech/antxclipse/trunk/update/index.html 原理同Antx Console
Antx Console的使用方法:
查看帮助:help help|? - 帮助 quit|exit - 退出 antx - 执行antx命令 list|ls/dir - 列出所有项目 cd <project id|..|/> - 跳转至当前项目|上一级项目|根项目 load <project dir|*> - 装入指定目录下的项目|所有项目 profile <name> - 设置profile section <name> - 设置section
Antx plugin简介:
antx clean 清除target目录 清除docs\api目录 清除docs\api.test目录
Plugin: antx-xar:
antx jar|war|ear|rar|ejb|car|uberjar jar —— 将java类打包 war —— Java EE Web Application包 ear —— Java EE Enterprise Application包 rar —— Java EE Java Connector Adapter包 ejb —— Java EE EJB包 类似jar, 但对于特定服务器,可能会激发额外操作,例如weblogic:ejbc car —— Webx Component包, 结构类似war, 但缺少WEB-INF/lib、WEB-INF/web.xml 多个car可组合成一个war uberjar —— 特殊的jar, 利用classloader技术,将所有的依赖打包在一个普通的jar里,使之可单独执行 目前有严重的性能问题,有待改进
Plugin: antx-java:
antx forrest 根据docs\xdocs中的XML文档,在docs\site中生成HTML静态文档 antx forrest:clean 清除docs\site目录 antx forrest:run 运行jetty server,动态显示XML文档 antx forrest:sync 将当前编辑的XML文档同步到正在运行的jetty server中 antx forrest:demo 生成示范文档
Plugin: antx-gen:
antx gen 生成标准的目录结构 antx gen:basic-test 生成带单元测试的标准目录结构 antx gen:car|ejb|ear|war|rar 生成相应类型项目的标准目录结构
Plugin: antx-javadoc:
antx javadoc 生成API文档,在docs\api和docs\api.test目录下
Plugin: antx-plugin:
antx plugin 创建plugin jar包 antx plugin:install 安装plugin,使之可用
Plugin: antx-reactor:
antx reactor 前面已经介绍
Plugin: antx-eclipse:
antx eclipse 生成eclipse项目文件,包括: .project .classpath
Plugin: antx-config:
创建src/java/META-INF/autoconf/auto-config.xml <?xml version="1.0" encoding="gb2312"?> <config description="自动配置:my-project"> <group name="myproject"> <property name="myproject.workdir" description="工作目录"/> <property name="myproject.domain" defaultValue="localhost" description="用来访问myproject应用的一级域名"> <validator name="hostExist"/> </property> <property name="myproject.port" defaultValue="8080" description="用来访问myproject应用的端口"> <validator name="number"/> </property> </group> <script> <generate template="myconf.xml.vm" destfile="myconf.xml" charset="GBK"/> </script> </config>
创建src/java/META-INF/autoconf/myconf.xml.vm <myconf> <workdir>$myproject_workdir</workdir> <url>http://www.$myproject_domain:$myproject_port/</url> </myconf> Build并配置 antx jar antx config uris=my/project
执行自己的脚本:
修改project.jelly <project default="jar"> <goal name="deploy" prereqs="jar,config"/> </project> 修改project.xml <build> <property name="uris" value="my/project"/> … </build> 执行:antx deploy
执行Ant tasks:
可以在project.jelly中执行任意Ant tasks 修改project.jelly <project default="jar"> <goal name="deploy" prereqs="jar,config"/> <goal name="testant" prereqs="deploy"> <copy file="${jar_destfile.file}" todir="c:/"/> </goal> </project>