ant集成maven

  • Post author:
  • Post category:其他


ant是著名的构建工具,maven则是著名的依赖管理工具,要说谁好用,我还真说不出来,因为各有各的擅长,maven对于从源码,编译一直到打包这块完全无可挑剔,因为约定大于配置,所以maven简单到最后只有一个命令maven clean install就搞定所有事情,最重要的是搞定包依赖;而ant则是一个相对万能的工具,有些像shell脚本,因为已经定义好了无数好用的task,而且还允许随意扩展。

有的情况需要利用两个工具的优势。比如,你需要一键运行一个jar包,如果放在无工具时代,你需要自己敲一串很长的命令(需要带上依赖的jar包),据我所知,maven也是不能直接运行jar的,所以只有ant可以;再比如,需要查找替换某个特殊的文件,然后才开始install,这个过程,maven应该也是不能做的(没有调查过写插件是不是可以)。但是叫ant管理包依赖……杀了我吧。

所以我们有了一个场景,需要结合二者。为了更好的自由控制,我选择的是ant调用maven,选用的插件是maven ant task,地址是

http://maven.apache.org/ant-tasks/

,而不是反过来maven调用ant,有另一个maven的插件antrun。

使用ant集成maven,如下的步骤很重要,即定义maven ant task这个插件的的tag去哪找,记得要把maven-ant-tasks-2.1.3.jar拷贝到跟build.xml同目录

<project name="test" default="deploy" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
	
	<path id="maven-ant-tasks.classpath" path="maven-ant-tasks-2.1.3.jar" />
	
	<typedef resource="org/apache/maven/artifact/ant/antlib.xml"
	       uri="antlib:org.apache.maven.artifact.ant"
	       classpathref="maven-ant-tasks.classpath" />
	
	<target name="git-update">
...

接下来就可以自由的使用maven的各种命令了,比如clean install,记住这里的arg一次只能写一个,不能写到一起去;另外,fork=true一定要加上,由于这个artifact:mvn这个task是集成java task,因而fork=”true”表示在一个新的jvm中去执行maven任务,之前的折腾了的问题就是因为没有这句,导致build成功后出现一个权限异常。

<target name="maven-clean-install">
		<artifact:mvn pom="pom.xml" mavenHome="${maven.home}" fork="true">
			<arg value="clean"/>
		    <span style="white-space:pre">	</span><arg value="install"/>
			<arg value="-DskipTests"/>
		</artifact:mvn>
	</target>

顺便提一下

maven如何打一个可执行的包

,这个话题网上很多文章。比如

https://www.ibm.com/developerworks/cn/java/j-5things13/

其实主要的就是两个步骤:

1.是配置maven-jar-plugin,这个地方是帮助你生成manifest的,关于manifest,有两个地方比较重要,一个是main-class,一个是classpath。

如果你打算使用java -jar -classpath …这样的命令,那么最终classpath是不能生效的,因为java默认限制了jar的加载路径在当前可执行的jar里,因而需要在manifest里指定classpath。可以参考这些文章

http://www.zeali.net/entry/15



http://www.ibm.com/developerworks/cn/java/j-jar/

。pom的配置如下:

<plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-jar-plugin</artifactId>
             <configuration>
                 <archive>
		             <manifest>
		             		<addClasspath>true</addClasspath>
                        	<span style="white-space:pre">	</span><classpathPrefix>lib/</classpathPrefix>
		                    <span style="white-space:pre">	</span><mainClass>org........MainClass</mainClass>
		             </manifest>
                 </archive>
             </configuration>
         </plugin>

2. 这步完成之后第二步是利用maven的依赖管理帮你把依赖的包到copy到当前jar目录或者子目录。

<plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-dependency-plugin</artifactId>
             <executions>
                 <execution>
                     <id>copy</id>
                     <phase>install</phase>
                     <goals>
                         <goal>copy-dependencies</goal>
                     </goals>
                     <configuration>
                         <outputDirectory>
                           ${project.build.directory}/lib
                         </outputDirectory>
                     </configuration>
                 </execution>
             </executions>
         </plugin>

这两步完成后就可以直接用java -jar xxx.jar运行了。

当然了,我遇到的问题更特殊一点,因为我有一个jar是不在中央仓库中的,scope是system,因而maven的打包插件不会自动将这个jar加入manifest,导致运行起来会报错。(当然我可以建一个本地中央仓库,将该jar托管到本地仓库中也可以搞定)

查了很多资料,貌似在addClass过程中很难干预他的打包,想想也对,如果他能够将system scope的东西也打包进去,那还不乱套了。

所以我的解决办法是在执行之前使用ant做替换,简单讲就是先解压,替换,再压缩。整个过程看起来如下

		<unzip dest="${test.start}/target/test-start-1.0"> 
			<fileset dir="${test.start}/target/">
				<include name="${test.start.name}"/>
			</fileset>
		</unzip>
		<replace file="${test.start}/target/test-start-1.0/META-INF/MANIFEST.MF" token="${line.separator}${line.separator}" value=" lib/special.jar${line.separator}${line.separator}"/>
		<zip destfile="${test.start}/target/${test.start.name}"
		       basedir="${test.start}/target/test-start-1.0"/>		

需要注意的是,在ant中,换行符使用${line.separator},我用\r\n试了无效,其次,再次打包回来不能用jar这个task,否则他会自动生成manifest,你就白改了。


maven pom编辑后,jar包有了,但是Referenced Libraries没有这个新增jar包

解决办法如下:删除当前eclipse工程下的.classpath,mvn eclipse:eclipse  重新构建了.classpath,刷新Eclipse工程

maven类包冲突解决技巧 http://stamen.iteye.com/blog/2030552



版权声明:本文为liweisnake原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。