运用maven ant task实现非标准打包[转]
maven很强大,但是总有些事情干起来不是得心应手,没有使用ant时那种想怎么干就怎么干的流畅感。尤其当要打包一个特殊(相对maven的标准架构而且)时,常有不知所措的感觉。当然这个应该和自己对maven的了解不够有关,毕竟,“初学maven”嘛。
但是maven在依赖管理方面实在是太强大了,太喜欢,退回原来的ant方式完全不可能,我想用过maven的人,一般是不会有回到原来在 cvs,subversion中checkin/checkout n个jar包的时代,仅此一项理由就足够继续坚持使用maven了。
然而ant的灵活又难于忘怀,尤其是从ant的build.xml一路走来的人,总是回不知不觉间想到ant的美好。鱼与熊掌,我都想要。最近想打包一 个java应用,很简单但即不是标准的j2ee appication也不是web application, 用maven完全不知道该怎么打包,package出来的完全不是我想要的,在网上四处google maven资料的时候,总有用回ant拉倒的冲动。
先交代一下背景吧,我要打包的程序,是这个样子:
1
2
3
4
5
6
7
8
9
10
11
12
|
demo1
|____lib
|_____demo1.jar
|_____*****.jar
|_____*****.jar
|____config
|_____*****.properties
|_____*****.xml
|____log
|_____*****.log
|____run.bat
|____run.sh
|
这个应用的打包模式很简单,一个bat或者sh脚本用来执行,lib目录下存放所有的jar包,包括自己的源代码编译打包的jar和第三方包。 config下是配置文件,这些文件需要在安装时或者运行前修改,比如监听的端口啊,数据库信息之类的。log目录存放日志文件。最后打包的产物是一个 zip包(或者tar,tar.gz)。
遇到的问题,就是maven标准的打包方式中根本不考虑类似的情况,什么 jar,ear,war完全不适用。而且maven有些理念也诧异,比如maven标准的config目录是src/main/config,但是这个目 录里面的配置文件默认会打包到jar包中,晕,都在jar里面了还让人怎么改啊?
本着尽量只用maven不用ant的想法,我在maven的资料中看了好久,没有找到解决的方法。晕,难道大家都只打包标准的ear,jar,war,只有我这样无聊的人才会有这种打包的需求?
几经寻觅和探索,最后发现,maven ant tasks似乎是一个不错的选择。带着mavenanttasks的官方文档和google上搜到的几篇文章,开始尝试,成功实现功能。现在将过程和方法share给大家。
首先建立java项目anttaskdemo1,按照maven的推荐,文件结构如下:
1
2
3
4
5
6
7
8
9
10
11
|
anttaskdemo1
|____src/main/java
|____src/main/config
|____src/main/bin
|____src/main/resources
|____src/test/java
|____src/test/resources
|____target
|____build.properties
|____build.xml
|____pom.xml
|
其中src/main/java下放java代码;src/main/resources下放一个*.properties文件,这个资源文件是打包到 jar中,内容打包之后不需要改变的。src/main/config下放一个标准的log4j.xml,这个是有在安装运行前临时修改的需要的。src /main/bin下放置可执行文件。
1. 首先看pom.xml,标准内容,很简单,象征性的加入几个依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>
1.3
</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>
1.2
.
13
</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>
5.8
</version>
<scope>test</scope>
<classifier>jdk15</classifier>
</dependency>
|
其中commons-codec,log4j是需要打包到lib中的,运行时需要。testng(或者更一般的junit)是用来单元测试的,不需要打包到lib中。请注意它的设置"<scope>test</scope>"。
2. 然后看看build.properties文件,这个内容不多:
M2_REPO=G:/soft/maven/localRepository
1
2
3
4
5
6
|
path.
package
=
package
path.target.name=anttaskdemo1
path.
package
.lib=lib
path.
package
.log=log
path.
package
.config=config
path.
package
.bin=
|
M2_REPO稍后再详谈,后面的path.package之类的是最终打包时使用的几个目录名称,对应于最终打包的结构。
3. build.xml,这个内容比较多。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
<?xmlversion=
"1.0"
encoding=
"UTF-8"
?>
<projectname=
"demo"
default
=
"all"
xmlns:artifact=
"urn:maven-artifact-ant"
>
<description>
</description>
<propertyfile=
"build.properties"
/>
<targetname=
"init_maven"
>
<!--
remembertosetM2_REPObeforeusethisbuild.xml,forexampleineclispe:
"Window→Preferences→Ant→Runtime"
,addanewpropertynamed
"M2_REPO"
andsetitvaluepointtothepathofyourmaven
localrepository;Oryoucansetitinbuild.properties. Youneeddoone(andonlyone)ofthem.
-->
<pathid=
"maven-ant-tasks.classpath"
path=
"${M2_REPO}/org/apache/maven/maven-ant-tasks/2.0.9/maven-ant-tasks-2.0.9.jar"
/>
<typedefresource=
"org/apache/maven/artifact/ant/antlib.xml"
uri=
"urn:maven-artifact-ant"
classpathref=
"maven-ant-tasks.classpath"
/>
<artifact:pomid=
"maven.project"
file=
"pom.xml"
/>
<artifact:dependenciespathId=
"classpath.build"
filesetid=
"maven.fileset.build"
>
<pomrefid=
"maven.project"
/>
</artifact:dependencies>
<artifact:dependenciespathId=
"classpath.runtime"
filesetid=
"maven.fileset.runtime"
useScope=
"runtime"
>
<pomrefid=
"maven.project"
/>
</artifact:dependencies>
</target>
<targetname=
"all"
depends=
"init_path,compile,jar,package,zip"
description=
"doall"
>
<echo>begintodoalltargettobuildtheresultpackage.</echo>
</target>
<targetname=
"maven_info"
depends=
"init_maven"
>
<echo>Mavenbuilddirectoryis${maven.project.build.directory}</echo>
<echo>MavenbuildfinalNameis${maven.project.build.finalName}</echo>
<echo>MavenbuildsourceDirectorydirectoryis${maven.project.build.sourceDirectory}</echo>
<echo>MavenbuildoutputDirectorydirectoryis${maven.project.build.outputDirectory}</echo>
<echo>MavenbuildscriptSourceDirectorydirectoryis${maven.project.build.testSourceDirectory}</echo>
<echo>MavenbuildtestOutputDirectorydirectoryis${maven.project.build.testOutputDirectory}</echo>
<echo>MavenbuildscriptSourceDirectorydirectoryis${maven.project.build.scriptSourceDirectory}</echo>
<echo>MavenbuildresourceDirectorydirectoryis${maven.project.build.resources}</echo>
<propertyname=
"target.jar.name"
value=
"${maven.project.build.directory}/${maven.project.build.finalName}.jar"
/>
<echo>MavenbuildscriptSourceDirectorydirectoryis${target.jar.name}</echo>
</target>
<targetname=
"clean"
depends=
"init_maven"
>
<echo>cleanbuilddirectory:${maven.project.build.directory}</echo>
<deletedir=
"${maven.project.build.directory}"
includes=
"**/*"
/>
</target>
<targetname=
"init_path"
depends=
"maven_info,clean"
>
<echo>makedirforjavacompile:${maven.project.build.outputDirectory}</echo>
<mkdirdir=
"${maven.project.build.outputDirectory}"
/>
</target>
<targetname=
"compile"
description=
"description"
depends=
"init_maven"
>
<javacsrcdir=
"${maven.project.build.sourceDirectory}"
destdir=
"${maven.project.build.outputDirectory}"
classpathref=
"classpath.build"
/>
</target>
<targetname=
"copyResource"
depends=
"init_maven"
>
<copytodir=
"${maven.project.build.outputDirectory}"
>
<filesetdir=
"src/main/resources"
>
</fileset>
</copy>
</target>
<targetname=
"jar"
depends=
"compile,copyResource"
>
<deletefile=
"${maven.project.build.directory}/${maven.project.build.finalName}.jar"
failonerror=
"false"
/>
<jardestfile=
"${maven.project.build.directory}/${maven.project.build.finalName}.jar"
basedir=
"${maven.project.build.outputDirectory}"
>
</jar>
</target>
<targetname=
"package"
depends=
"package_prepare,copyLib,copyConfig,copyBin"
>
</target>
<targetname=
"package_prepare"
depends=
"init_maven"
>
<echo>cleanpackagedirectory:${maven.project.build.directory}/${path.
package
}</echo>
<deletedir=
"${maven.project.build.directory}/${path.package}"
/>
<mkdirdir=
"${maven.project.build.directory}/${path.package}"
/>
<mkdirdir=
"${maven.project.build.directory}/${path.package}/${path.target.name}"
/>
<mkdirdir=
"${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.lib}"
/>
<mkdirdir=
"${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.config}"
/>
<mkdirdir=
"${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.log}"
/>
</target>
<targetname=
"copyLib"
depends=
"init_maven"
>
<copytodir=
"${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.lib}"
>
<filesetrefid=
"maven.fileset.runtime"
/>
<mappertype=
"flatten"
/>
</copy>
<copytodir=
"${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.lib}"
file=
"${maven.project.build.directory}/${maven.project.build.finalName}.jar"
>
</copy>
</target>
<targetname=
"copyConfig"
depends=
"init_maven"
>
<copytodir=
"${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.config}"
>
<filesetdir=
"src/main/config"
>
</fileset>
</copy>
</target>
<targetname=
"copyBin"
depends=
"init_maven"
>
<copytodir=
"${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.bin}"
>
<filesetdir=
"src/main/bin"
>
</fileset>
</copy>
</target>
<targetname=
"zip"
depends=
"init_maven"
>
<zipdestfile=
"${maven.project.build.directory}/${path.package}/${path.target.name}.zip"
>
<filesetdir=
"${maven.project.build.directory}/${path.package}/${path.target.name}"
></fileset>
</zip>
</target>
</project>
|