|  
 1  maven和ant的比较 
 第一:每次和别人说maven的时候,很多会认为是全新的东西而不肯放弃ant。其实,ant脚本是可以直接运行在maven中的。 
如果要说maven和ant有什么差别,我觉得最大的差别就是在于maven的编译以及所有的脚本都有一个基础,就是POM(project object model)。这个模型定义了项目的方方面面,然后各式各样的脚本在这个模型上工作,而ant完全是自己定义,显然maven更胜一筹。 
第二:Maven对所依赖的包有明确的定义,如使用那个包,版本是多少,一目了然。而ant则通常是简单的inclde 所有的jar。导致的最终结果就是,你根本无法确定JBoss中的lib下的common-logging 是哪个版本的,唯一的方法就是打开 META-INF 目录下MANIFEST.MF。估计JBoss迟早会转向Maven的。 
第三:Maven是基于中央仓库的编译,即把编译所需要的资源放在一个中央仓库里,如jar,tld,pom,等。当编译的时候,maven会自动在仓库中找到相应的包,如果本地仓库没有,则从设定好的远程仓库中下载到本地。这一切都是自动的,而ant需要自己定义了。这个好处导致的结果就是,用maven编译的项目在发布的时候只需要发布源码,小得很,而反之,ant的发布则要把所有的包一起发布,显然maven又胜了一筹。 
第四:maven有大量的重用脚本可以利用,如生成网站,生成javadoc,sourcecode reference,等。而ant都需要自己去写。试试 maven site 的效果。 
第五:maven目前不足的地方就是没有象ant那样成熟的GUI界面,不过mavengui正在努力中。目前使用maven最好的方法还是命令行,又快又方便。 
  
最后,总结一下,转向maven会为你节省更多的时间。 
  
2. build.properties 和project.properties 
  build.properties 用来方编译信息比较好,project.properties用来放项目信息比较好。 
Build.properties的实例,把他放在用户目录下(C:\Documents and Settings\user),就可以使用所有项目都共享这个信息。 
maven.repo.local=f:/java/repository 
maven.repo.remote=http://mirrors.sunsite.dk/maven/ 
  
#maven.proxy.host=127.0.0.1 
#maven.proxy.port=80 
  
maven.compile.target = 1.4 
maven.compile.source = 1.4 
  
3 如何进行多个项目的开发。 
  
在用Maven进行一个项目下有多个子项目开发的时候,常用的就是MulitProject 脚本 <maven:reactor >。 
  
举例来看,下图就是一个项目中的子项目,该子项目又有两个子项目,只要在project中定义了继承关系,1.0能够将maven.xml中的脚本及project.properties 和build.properties中的属性 传播到子项目中去,这个特性好像在RC版本中没有完全实现。 
  
 知道了Maven 的这些特性,就可以将大量的公共脚本写在maven。xml中,子项目就可以很方便的调用了。 
  
         <!--==================================================================--> 
<!-- Hibernate Doclet--> 
<!--==================================================================--> 
<goal description="xdoclet for hibernate " name="project:hibernate-xdoclet"> 
<taskdef name="hibernatedoclet"  
classname="xdoclet.modules.hibernate.HibernateDocletTask"  
classpathref="maven.dependency.classpath"/> 
<echo>+---------------------------------------------------+</echo> 
<echo>| Hibernate Doclet......                                       |</echo> 
<echo>+---------------------------------------------------+</echo> 
<mkdir dir="${project.xdoclet.hibernate.destDir}"/> 
<hibernatedoclet destdir="${project.xdoclet.hibernate.destDir}"  
mergedir="${project.xdoclet.hibernate.mergeDir}"  
excludedtags="${project.xdoclet.hibernate.excludedtags}"  
addedtags="${project.xdoclet.hibernate.addedtags}"  
force="${project.xdoclet.hibernate.force}"  
verbose="${project.xdoclet.hibernate.verbose}"> 
<fileset dir="${project.xdoclet.hibernate.srcDir}"> 
<include name="**/*.java"/> 
</fileset> 
<hibernate version="2.0"/> 
<!--  
<jbossservice  
transactionStrategy="${project.xdoclet.hibernate.jbossservice.transactionStrategy}"  
userTransactionName ="${project.xdoclet.hibernate.jbossservice.userTransactionName}"  
serviceName="${project.xdoclet.hibernate.jbossservice.serviceName}" 
jndiName="${project.xdoclet.hibernate.jbossservice.jndiName}" 
dataSource="${project.xdoclet.hibernate.jbossservice.dataSource}" 
dialect="${project.xdoclet.hibernate.jbossservice.dialect}" 
showSql="${project.xdoclet.hibernate.jbossservice.showSql}" 
templateFile="${project.xdoclet.hibernate.jbossservice.templateFile}" 
/> 
--> 
<hibernatecfg  
transactionManagerLookup="${project.xdoclet.hibernate.cfg.transactionManagerLookup}"  
transactionStrategy="${project.xdoclet.hibernate.cfg.transactionStrategy}"  
userTransactionName  
="${project.xdoclet.hibernate.cfg.userTransactionName}"  
jndiName="${project.xdoclet.hibernate.cfg.jndiName}"  
dataSource="${project.xdoclet.hibernate.cfg.dataSource}"  
dialect="${project.xdoclet.hibernate.cfg.dialect}"  
showSql="${project.xdoclet.hibernate.cfg.showSql}" /> 
</hibernatedoclet> 
</goal> 
  
在任何一个子项目中,就可以直接调用project:hibernate-xdoclet脚本了。就可以 
  
<maven:reactor 的不足在于,如果你这样定义 
<maven:reactor basedir="${basedir}" postProcessing="true"  
includes="portal/project.xml,common/project.xml" goals="project:deploy"  
banner="Deploying Service:" ignoreFailures="false" /> 
  
本来原意是想让Portal早于common进行编译,不过reactor实际将先编译common,再编译portal。因为他是以名称来决定编译次序,显然是不好的,因为多个子项目之间往往是有先后关系。解决的方法就是,定义多个reactor 了。 
  
4 定义自己的maven.xml 模板。 
 maven的脚本是基于AOP的,也就是你可以在任何一个goal之前和之后插入自己的代码,所以maven的脚本没有固定的写法。 
这里有我写过的一个maven模板。 
<?xml version="1.0" encoding="gb2312"?> 
<project default="project:deploy" xmlns:maven="jelly:maven" 
xmlns:j="jelly:core" xmlns:util="jelly:util"> 
<!-- 一般项目分为四个里程碑:初始化、精化、构建、部署 --> 
<preGoal name="project:deploy"> 
<attainGoal name="project:inception"/> 
<attainGoal name="project:elaboration"/> 
<attainGoal name="project:construction"/> 
<attainGoal name="project:transition"/> 
</preGoal> 
<goal name="project:deploy"> 
</goal> 
<!--完成一些初始化工作 --> 
<goal name="project:inception"> 
<attainGoal name="clean"/> 
</goal> 
<!-- 主要是xdoclet 产生各种文件--> 
<goal name="project:elaboration"> 
    <attainGoal name="project:ejb-xdoclet"/> 
</goal> 
<!-- 编译项目--> 
<goal name="project:construction"> 
<!-- 调用war 插件 --> 
<attainGoal name="war:war"/> 
</goal> 
<!--  
对编译好的项目进行组合准备部署 
--> 
<goal name="project:transition"> 
</goal> 
</project> 
  
5 很多公共脚本都不正常 
这是很正常的事情,事实上很多脚本 xdoclet,middlegen等都存在一定的问题,如果出现这种情况,最直接的办法就是把它们的脚本自己封装一遍,做成适合自己的脚本。 
比如,xdoclet 1.2之前的脚本就不太好用,我就到maven的cache目录(C:\Documents and Settings\user\.maven\cache),找到想修改的插件目录,里面都会有plugin.jelly,它是一个xml文件,里面就是脚本了,然后copy到自己的maven.xml中,就可以直接调用了。 
以下,是我写的自己常用的web xdoclet脚本 
  
         <!--==================================================================--> 
<!-- WEB Doclet--> 
<!--==================================================================--> 
<goal description="xdoclet for web " name="project:web-xdoclet" > 
<taskdef name="webdoclet" classname="xdoclet.modules.web.WebDocletTask"  
classpathref="maven.dependency.classpath"/> 
<echo>+---------------------------------------------------+</echo> 
<echo>| Running WebDoclet...... |</echo> 
<echo>+---------------------------------------------------+</echo> 
<mkdir dir="${project.xdoclet.web.destDir}"/> 
<webdoclet destdir="${project.xdoclet.web.destDir}"  
mergedir="${project.xdoclet.web.mergeDir}"  
excludedtags="${project.xdoclet.web.excludedtags}"  
addedtags="${project.xdoclet.web.addedtags}"  
force="${project.xdoclet.web.force}"  
verbose="${project.xdoclet.web.verbose}"> 
<fileset dir="${project.xdoclet.web.srcDir}"> 
<include name="**/*.java"/> 
</fileset> 
<deploymentdescriptor servletspec="${project.xdoclet.web.version}"  
destdir="${project.xdoclet.web.webxml.dir}"  
xmlencoding="${project.xdoclet.web.xmlencoding}"  
templateFile="${project.xdoclet.web.templateFile}" /> 
<strutsconfigxml  
destdir="${project.xdoclet.web.strutsconfigxml.dir}"  
xmlencoding="${project.xdoclet.web.strutsconfigxml.xmlencoding}"  
version="${project.xdoclet.web.strutsconfigxml.version}"  
templateFile="${project.xdoclet.web.strutsconfigxml.templateFile}"  
/> 
<jsptaglib jspversion="${project.xdoclet.web.jsptaglib.version}"  
destdir="${project.xdoclet.web.jsptaglib.dir}"  
shortname="${project.xdoclet.web.jsptaglib.shortname}"  
validateXml="${project.xdoclet.web.jsptaglib.validatexml}"  
xmlencoding="${project.xdoclet.web.jsptaglib.xmlencoding}"  
filename="${project.xdoclet.web.jsptaglib.filename}"  
templateFile="${project.xdoclet.web.jsptaglib.templateFile}" /> 
<!--  
<jbosswebxml destdir="${project.xdoclet.web.jbosswebxml.dir}"  
mergeDir="${project.xdoclet.web.jbosswebxml.dir}"/> 
--> 
</webdoclet> 
</goal> 
  
这个脚本可以生成web.xml struts-config.xml  tld jboss-web.xml ,自己可以根据需要很方便的修改了。其实不难看出,这些都是ant脚本。所以,如果没有合适的插件,最好的方法就是自己动手写一个。 
  
6 无法运行maven,报错为 缺少根组件。 
 这个错误是因为你采用的编辑器(比如:ultraedit)在<?xml 前添加了多余的字符,导致xml解析器无法处理xml文件,这个错误常常遇到。解决的方法就是把内容copy下来,重新paste到新的文件,覆盖老文件。或者用别的编辑器把多余字符去掉。 
  
待续。。。 
   
 
  |