- 浏览: 982371 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (826)
- 硬件 (8)
- 软件 (24)
- 软件工程 (34)
- JAVA (229)
- C/C++/C# (77)
- JavaScript (8)
- PHP (1)
- Ruby (3)
- MySQL (14)
- 数据库 (19)
- 心情记事 (12)
- 团队管理 (19)
- Hadoop (1)
- spring (22)
- mybatis(ibatis) (7)
- tomcat (16)
- velocity (0)
- 系统架构 (6)
- JMX (8)
- proxool (1)
- 开发工具 (16)
- python (10)
- JVM (27)
- servlet (5)
- JMS (26)
- ant (2)
- 设计模式 (5)
- 智力题 (2)
- 面试题收集 (1)
- 孙子兵法 (16)
- 测试 (1)
- 数据结构 (7)
- 算法 (22)
- Android (11)
- 汽车驾驶 (1)
- lucene (1)
- memcache (12)
- 技术架构 (7)
- OTP-Erlang (7)
- memcached (17)
- redis (20)
- 浏览器插件 (3)
- sqlite (3)
- Heritrix (9)
- Java线程 (1)
- scala (0)
- Mina (6)
- 汇编 (2)
- Netty (15)
- libevent (0)
- CentOS (12)
- mongod (5)
- mac os (0)
最新评论
-
kingasdfg:
你这里面存在一个错误添加多个任务 应该是这样的 /** * ...
Quartz的任务的临时启动和暂停和恢复【转】 -
kyzeng:
纠正一个错误,long型对应的符号是J,不是L。
Jni中C++和Java的参数传递 -
zhaohaolin:
抱歉,兄弟,只是留下作记录,方便学习,如果觉得资料不好,可以到 ...
netty的个人使用心得【转】 -
cccoooccooco:
谢谢!自己一直以为虚机得使用网线才可以与主机连接呢。。
主机网卡无网线连接与虚拟机通信 -
yuqilin001:
要转别人的东西,请转清楚点嘛,少了这么多类,误人子弟
netty的个人使用心得【转】
“打包“这个词听起来比较土,比较正式的说法应该是”构建项目软件包“,具体说就是将项目中的各种文件,比如源代码、编译生成的字节码、配置文件、文档,按照规范的格式生成归档,最常见的当然就是JAR包和WAR包了,复杂点的例子是Maven官方下载页面的分发包 , 它有自定义的格式,方便用户直接解压后就在命令行使用。作为一款”打包工具“,Maven自然有义务帮助用户创建各种各样的包,规范的JAR包和WAR包 自然不再话下,略微复杂的自定义打包格式也必须支持,本文就介绍一些常用的打包案例以及相关的实现方式,除了前面提到的一些包以外,你还能看到如何生成源 码包、Javadoc包、以及从命令行可直接运行的CLI包。
Packaging的含义
任何一个Maven项目都需要定义POM元素packaging(如果不写则默认值为jar)。顾名思义,该元素决定了项目的打包方式。实际的情形 中,如果你不声明该元素,Maven会帮你生成一个JAR包;如果你定义该元素的值为war,那你会得到一个WAR包;如果定义其值为POM(比如是一个 父模块),那什么包都不会生成。除此之外,Maven默认还支持一些其他的流行打包格式,例如ejb3和ear。你不需要了解具体的打包细节,你所需要做 的就是告诉Maven,”我是个什么类型的项目“,这就是约定优于配置 的力量。
为了更好的理解Maven的默认打包方式,我们不妨来看看简单的声明背后发生了什么,对一个jar项目执行mvn package操作,会看到如下的输出:
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ git-demo --- [INFO] Building jar: /home/juven/git_juven/git-demo/target/git-demo-1.2-SNAPSHOT.jar
相比之下,对一个war项目执行mvn package操作,输出是这样的:
[INFO] --- maven-war-plugin:2.1:war (default-war) @ webapp-demo --- [INFO] Packaging webapp [INFO] Assembling webapp [webapp-demo] in [/home/juven/git_juven/webapp-demo/target/webapp-demo-1.0-SNAPSHOT] [INFO] Processing war project [INFO] Copying webapp resources [/home/juven/git_juven/webapp-demo/src/main/webapp] [INFO] Webapp assembled in [90 msecs] [INFO] Building war: /home/juven/git_juven/webapp-demo/target/webapp-demo-1.0-SNAPSHOT.war
对应于同样的package生命周期阶段,Maven为jar项目调用了maven-jar-plugin,为war项目调用了maven-war-plugin,换言之,packaging直接影响Maven的构建生命周期 。了解这一点非常重要,特别是当你需要自定义打包行为的时候,你就必须知道去配置哪个插件。一个常见的例子就是在打包war项目的时候排除某些web资源文件,这时就应该配置maven-war-plugin如下:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.1.1</version> <configuration> <webResources> <resource> <directory>src/main/webapp</directory> <excludes> <exclude>**/*.jpg</exclude> </excludes> </resource> </webResources> </configuration> </plugin>
源码包和Javadoc包
本专栏的《坐标规划》 一 文中曾解释过,一个Maven项目只生成一个主构件,当需要生成其他附属构件的时候,就需要用上classifier。源码包和Javadoc包就是附属 构件的极佳例子。它们有着广泛的用途,尤其是源码包,当你使用一个第三方依赖的时候,有时候会希望在IDE中直接进入该依赖的源码查看其实现的细节,如果 该依赖将源码包发布到了Maven仓库,那么像Eclipse就能通过m2eclipse插件解析下载源码包并关联到你的项目中,十分方便。由于生成源码 包是极其常见的需求,因此Maven官方提供了一个插件来帮助用户完成这个任务:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>2.1.2</version> <executions> <execution> <id>attach-sources</id> <phase>verify</phase> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin>
类似的,生成Javadoc包只需要配置插件如下:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>2.7</version> <executions> <execution> <id>attach-javadocs</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin>
为了帮助所有Maven用户更方便的使用Maven中央库中海量的资源,中央仓库的维护者强制要求开源项目提交构件的时候同时提供源码包和Javadoc包。这是个很好的实践,读者也可以尝试在自己所处的公司内部实行,以促进不同项目之间的交流。
可执行CLI包
除了前面提到了常规JAR包、WAR包,源码包和Javadoc包,另一种常被用到的包是在命令行可直接运行的CLI(Command Line)包。默认Maven生成的JAR包只包含了编译生成的.class文件和项目资源文件,而要得到一个可以直接在命令行通过java命令运行的 JAR文件,还要满足两个条件:
- JAR包中的/META-INF/MANIFEST.MF元数据文件必须包含Main-Class信息。
- 项目所有的依赖都必须在Classpath中。
Maven有好几个插件能帮助用户完成上述任务,不过用起来最方便的还是maven-shade-plugin , 它可以让用户配置Main-Class的值,然后在打包的时候将值填入/META-INF/MANIFEST.MF文件。关于项目的依赖,它很聪明地将依 赖JAR文件全部解压后,再将得到的.class文件连同当前项目的.class文件一起合并到最终的CLI包中,这样,在执行CLI JAR文件的时候,所有需要的类就都在Classpath中了。下面是一个配置样例:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>1.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.juvenxu.mavenbook.HelloWorldCli</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
上述例子中的,我的Main-Class是com.juvenxu.mavenbook.HelloWorldCli,构建完成后,对应于一个常规 的hello-world-1.0.jar文件,我还得到了一个hello-world-1.0-cli.jar文件。细心的读者可能已经注意到了,这里 用的是cli这个classifier。最后,我可以通过java -jar hello-world-1.0-cli.jar 命令运行程序。
自定义格式包
实际的软件项目常常会有更复杂的打包需求,例如我们可能需要为客户提供一份产品的分发包,这个包不仅仅包含项目的字节码文件,还得包含依赖以及相关脚本文件以方便客户解压后就能运行,此外分发包还得包含一些必要的文档。这时项目的源码目录结构大致是这样的:
pom.xml src/main/java/ src/main/resources/ src/test/java/ src/test/resources/ src/main/scripts/ src/main/assembly/ README.txt
除了基本的pom.xml和一般Maven目录之外,这里还有一个src/main/scripts/目录,该目录会包含一些脚本文件如 run.sh和run.bat,src/main/assembly/会包含一个assembly.xml,这是打包的描述文件,稍后介绍,最后的 README.txt是份简单的文档。
我们希望最终生成一个zip格式的分发包,它包含如下的一个结构:
bin/ lib/ README.txt
其中bin/目录包含了可执行脚本run.sh和run.bat,lib/目录包含了项目JAR包和所有依赖JAR,README.txt就是前面提到的文档。
描述清楚需求后,我们就要搬出Maven最强大的打包插件:maven-assembly-plugin 。 它支持各种打包文件格式,包括zip、tar.gz、tar.bz2等等,通过一个打包描述文件(该例中是src/main /assembly.xml),它能够帮助用户选择具体打包哪些文件集合、依赖、模块、和甚至本地仓库文件,每个项的具体打包路径用户也能自由控制。如下 就是对应上述需求的打包描述文件src/main/assembly.xml:
<assembly> <id>bin</id> <formats> <format>zip</format> </formats> <dependencySets> <dependencySet> <useProjectArtifact>true</useProjectArtifact> <outputDirectory>lib</outputDirectory> </dependencySet> </dependencySets> <fileSets> <fileSet> <outputDirectory>/</outputDirectory> <includes> <include>README.txt</include> </includes> </fileSet> <fileSet> <directory>src/main/scripts</directory> <outputDirectory>/bin</outputDirectory> <includes> <include>run.sh</include> <include>run.bat</include> </includes> </fileSet> </fileSets> </assembly>
- 首先这个assembly.xml文件的id对应了其最终生成文件的classifier。
- 其次formats定义打包生成的文件格式,这里是zip。因此结合id我们会得到一个名为hello-world-1.0-bin.zip的文件。(假设artifactId为hello-world,version为1.0)
- dependencySets用来定义选择依赖并定义最终打包到什么目录,这里我们声明的一个depenencySet默认包含所有所有 依赖,而useProjectArtifact表示将项目本身生成的构件也包含在内,最终打包至输出包内的lib路径下(由 outputDirectory指定)。
- fileSets允许用户通过文件或目录的粒度来控制打包。这里的第一个fileSet打包README.txt文件至包的根目录下,第二个fileSet则将src/main/scripts下的run.sh和run.bat文件打包至输出包的bin目录下。
打包描述文件所支持的配置远超出本文所能覆盖的范围,为了避免读者被过多细节扰乱思维,这里不再展开,读者若有需要可以去参考这份文档 。
最后,我们需要配置maven-assembly-plugin使用打包描述文件,并绑定生命周期阶段使其自动执行打包操作:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.2.1</version> <configuration> <descriptors> <descriptor>src/main/assembly/assembly.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
运行mvn clean package 之后,我们就能在target/目录下得到名为hello-world-1.0-bin.zip的分发包了。
小结
打包是项目构建最重要的组成部分之一,本文介绍了主流Maven打包技巧,包括默认打包方式的原理、如何制作源码包和Javadoc包、如何制作命 令行可运行的CLI包、以及进一步的,如何基于个性化需求自定义打包格式。这其中涉及了很多的Maven插件,当然最重要,也是最为复杂和强大的打包插件 就是maven-assembly-plugin。事实上Maven本身的分发包就是通过maven-assembly-plugin制作的,感兴趣的读 者可以直接查看源码 一窥究竟。
您可能也会喜欢
发表评论
-
调试jdk中的源码,查看jdk局部变量
2013-06-15 23:30 1006调试jdk中的源码,查看jdk局部变量 2012-04 ... -
Eclipse快捷键 10个最有用的快捷键<转>
2013-04-11 23:28 1004Eclipse中10个最有用的快捷键组合 一个Eclip ... -
Lucene 3.6 中文分词、分页查询、高亮显示等
2012-12-09 23:35 17641、准备工作 下载lucene 3.6.1 : htt ... -
基于Maven的web工程如何配置嵌入式Jetty Server开发调试环境(转)
2012-10-12 00:28 8661、首先在web工程的POM文件里添加依赖jar包如下: ... -
轻轻松松学Solr(1)--概述及安装[转]
2012-09-18 14:59 945概述 这段时间对企 ... -
分析Netty工作流程[转]
2012-09-04 19:02 836下面以Netty中Echo的例 ... -
让eclipse在ubuntu下面好看一点
2012-03-27 10:17 877<p> </p> <h1 cla ... -
zookeeper安装和应用场合(名字,配置,锁,队列,集群管理)[转]
2012-01-12 17:59 1609安装和配置详解 本文 ... -
Jakarta-Common-BeanUtils使用笔记[转]
2012-01-10 14:13 1116Jakarta-Common-BeanUtils ... -
一个关于Java Thread wait(),notify()的实用例【转】
2012-01-07 16:05 980///// // ProducerConsume ... -
Java基础:Java中的 assert 关键字解析【转】
2012-01-06 19:50 970J2SE 1.4在语言上提供了 ... -
一篇不错的讲解Java异常的文章(转载)----感觉很不错,读了以后很有启发[转]
2012-01-06 15:02 1214六种异常处理的陋习 ... -
如何解决HP QC(Quality Center)在Windows 7下不能工作的问题
2011-12-26 10:48 1533HP QC(Quantity Center) 是一款不错的测 ... -
JAVA读写文件,中文乱码 【转】
2011-12-19 23:43 2068最近在做HTML静态生成,需要从硬盘上把模版文件的内容读出来。 ... -
Java 6 JVM参数选项大全(中文版)【转】
2011-12-19 19:51 921Java 6 JVM参数选项大全(中文版) 作者 ... -
使用assembly plugin实现自定义打包【转】
2011-12-13 01:58 922在上一篇文章中,讨论到在对maven的机制不熟悉的情况下,为了 ... -
使用maven ant task实现非标准打包[转]
2011-12-13 01:56 1000maven很强大,但是总有些事情干起来不是得心应手,没有使用a ... -
Java日期转换SimpleDateFormat格式大全【转】
2011-12-08 20:22 125924小时制时间 显示: public clas ... -
使用Spring的表单标签库
2011-11-22 20:08 102513.9. 使用Spring的 ... -
WEB界面开发规范(转)
2011-11-02 20:06 895页面设计规则 页面命名规则 1、每个功能 ...
相关推荐
maven入门,maven环境的搭建以及maven配置到eclipse以及pom.xml文件配置等
Maven实战 高清 Maven实战 高清 Maven实战 高清 Maven实战 高清 Maven实战 高清 Maven实战 高清 Maven实战 高清 Maven实战 高清 Maven实战 高清
Maven实战Maven实战Maven的安装、配置及使用入门
maven 实战 所有源代码
真实,绝对完整版 Maven 实战.pdf
Maven实战 好书 学习参考.pdf
Maven实战.pdf 不可多得的权威maven中文书籍
Maven实战
非常好的一本maven书 Maven实战 完整高清版
Maven实战(基于Maven3).pdf(340页)
Maven 实战(361)_12804356.pdf
Maven实战——入门篇.
《Maven实战》徐晓斌 完整高清版.pdf
Maven实战为许晓斌著。资源里面包括Maven实战pdf、程序所带源码。在eclipse开发时,需要下载m2e,下载地址http://download.eclipse.org/technology/m2e/releases/。eclipse 4.5 以上版本带的有Maven 插件,在下载m2e...
《Maven实战》 许晓斌
Maven实战].许晓斌.高清PDF扫描版.
maven打包 maven打jar包详细步骤