文档章节

Maven 项目打包需要注意到的那点事儿

岁月留痕
 岁月留痕
发布于 2015/12/30 17:40
字数 1169
阅读 1283
收藏 15

1. 关于 Maven 打 war 包

对 J2EE 项目打 war 包。其实很简单,你只需要把 pom.xml 中的 <packaging>jar</packaging> 换成 <packaging>war</packaging> 就可以使用 mvn package 命令对其打 war 包了,而不需要添加任何 maven 插件。只要你遵循了 maven 规范,那你打成的 war 包就肯定包含了第三方依赖包:
maven打的war包里边的第三方依赖包

把这个 war 包丢进 tomcat 的 webapps 目录,重启 tomcat 即可完成了该项目的部署。你唯一需要注意的是,在重启 tomcat 之前把你的 war 重命名为 项目访问路径.war。比如作者打成的 war 包是为 swifton-1.0.0.war,对该项目定义的访问路径是 /swifton,那么我在重启 tomcat 之前需要将其重命名为 swifton.war。

2. 可执行程序打 jar 包

关于可执行程序(需要指定一个 main 类)打 jar 包就没这么方便了,我们需要考虑以下几个问题:

  • 配置文件需要打进 jar 包;

  • 需要指定 main 入口类;

  • 所依赖的第三方库也要打进 jar 包;

只有同时满足以上三点,我们才可以直接使用 java -jar swiftonrsa-1.0.0.jar 命令成功执行该程序。
为了让讨论不那么抽象,我们在 Eclipse 下新建一个 maven 项目 swiftonrsa:
新建maven项目swiftonrsa

其中,com.defonds.RsaEncryptor 是入口 main 类,其源码如下:


  1. package com.defonds;  

  2.   

  3. import org.springframework.context.ApplicationContext;  

  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  

  5.   

  6. import com.defonds.service.LinkPayAntharService;  

  7.   

  8. public class RsaEncryptor {  

  9.   

  10.     public static void main(String[] args) {  

  11.         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  

  12.         LinkPayAntharService linkPayAntharService = (LinkPayAntharService) context.getBean("linkPayAntharService");  

  13.         linkPayAntharService.dealWithYearData();  

  14.     }  

  15. }  


2.1 配置文件打包不需要额外关注

只要你项目所依赖的配置文件都按照 maven 规范放对位置(src/main/resources),那么打好的 jar 包就会把它们一起打包:
配置文件打包不需要额外关注

但是这样打好的 jar 包既没有指定 main 入口类,也没有将依赖包打进来,我们运行它:
swiftonrsa-1.0.0.jar中没有清单属性

提示"swiftonrsa-1.0.0.jar中没有主清单属性",我们查看打好 jar 包下 META-INF 目录中的 MANIFEST.MF,其内容如下:
Manifest-Version: 1.0
Built-By: Defonds
Build-Jdk: 1.7.0_67
Created-By: Apache Maven 3.2.3
Archiver-Version: Plexus Archiver

确实没有指出 main 入口类。

2.2 maven-assembly-plugin 插件

于是我们引入了 maven-assembly-plugin 插件,pom.xml 中加入如下代码:

  1. <build>  

  2.     <plugins>  

  3.         <plugin>  

  4.             <artifactId>maven-assembly-plugin</artifactId>  

  5.             <configuration>  

  6.                 <appendAssemblyId>false</appendAssemblyId>  

  7.                 <descriptorRefs>  

  8.                     <descriptorRef>jar-with-dependencies</descriptorRef>  

  9.                 </descriptorRefs>  

  10.                 <archive>  

  11.                     <manifest>  

  12.                         <mainClass>com.defonds.RsaEncryptor</mainClass>  

  13.                     </manifest>  

  14.                 </archive>  

  15.             </configuration>  

  16.             <executions>  

  17.                 <execution>  

  18.                     <id>make-assembly</id>  

  19.                     <phase>package</phase>  

  20.                     <goals>  

  21.                         <goal>assembly</goal>  

  22.                     </goals>  

  23.                 </execution>  

  24.             </executions>  

  25.         </plugin>  

  26.     </plugins>  

  27. </build>  


执行 mvn assembly:assembly,成功构建 swiftonrsa-1.0.0.jar,查看其打包目录,各种配置文件以及第三方依赖包也都有:
assembly打包后的目录结构

然后查看 META-INF 目录中的 MANIFEST.MF,内容如下:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: Defonds
Build-Jdk: 1.7.0_67
Main-Class: com.defonds.RsaEncryptor

怀着兴奋的心情执行之:
assembly打包后的执行情况

maven-assembly-plugin 插件没有给我们带来惊喜。错误信息如下:
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/context]
原来这是 assembly 插件的一个 bug:http://jira.codehaus.org/browse/MASSEMBLY-360,它在对第三方打包时,对于 META-INF 下的 spring.handlers,spring.schemas 等多个同名文件进行了覆盖,遗漏掉了一些版本的 xsd 本地映射。

2.3 maven-shade-plugin 插件

有破必有立。http://jira.codehaus.org/browse/MASSEMBLY-360 跟帖中有网友推荐了 maven-shade-plugin 插件。于是我们使用 maven-shade-plugin 将 maven-assembly-plugin 替代:


  1. <build>  

  2.     <plugins>  

  3.         <plugin>  

  4.             <groupId>org.apache.maven.plugins</groupId>  

  5.             <artifactId>maven-shade-plugin</artifactId>  

  6.             <version>1.4</version>  

  7.             <executions>  

  8.                 <execution>  

  9.                     <phase>package</phase>  

  10.                     <goals>  

  11.                         <goal>shade</goal>  

  12.                     </goals>  

  13.                     <configuration>  

  14.                         <transformers>  

  15.                             <transformer  

  16.                                 implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">  

  17.                                 <mainClass>com.defonds.RsaEncryptor</mainClass>  

  18.                             </transformer>  

  19.                             <transformer  

  20.                                 implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  

  21.                                 <resource>META-INF/spring.handlers</resource>  

  22.                             </transformer>  

  23.                             <transformer  

  24.                                 implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  

  25.                                 <resource>META-INF/spring.schemas</resource>  

  26.                             </transformer>  

  27.                         </transformers>  

  28.                     </configuration>  

  29.                 </execution>  

  30.             </executions>  

  31.         </plugin>  

  32.     </plugins>  

  33. </build>  


对于多个第三方包 META-INF 下的同名的 spring.handlers 文件它采取的态度是追加而不是覆盖。执行 maven clean package,成功构建 swiftonrsa-1.0.0.jar,查看其打包目录,各种配置文件以及第三方依赖包也都有,以及 META-INF 目录中的 MANIFEST.MF 的内容,基本如 maven-assembly-plugin 打包后的样子,执行之:
shade插件打包后执行情况

错误信息如下:
java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
这是由于一些包重复引用,打包后的 META-INF 目录多出了一些 *.SF 等文件所致。
有破必有立。博客 http://zhentao-li.blogspot.com/2012/06/maven-shade-plugin-invalid-signature.html 给出了解决方案,pom.xml 添加:


  1. <configuration>  

  2.   <filters>  

  3.     <filter>  

  4.       <artifact>*:*</artifact>  

  5.       <excludes>  

  6.         <exclude>META-INF/*.SF</exclude>  

  7.         <exclude>META-INF/*.DSA</exclude>  

  8.         <exclude>META-INF/*.RSA</exclude>  

  9.       </excludes>  

  10.     </filter>  

  11.   </filters>  

  12. </configuration>  


于是我们对 maven-shade-plugin 的配置变成这样:


  1. <build>  

  2.     <plugins>  

  3.         <plugin>  

  4.             <groupId>org.apache.maven.plugins</groupId>  

  5.             <artifactId>maven-shade-plugin</artifactId>  

  6.             <version>1.4</version>  

  7.             <executions>  

  8.                 <execution>  

  9.                     <phase>package</phase>  

  10.                     <goals>  

  11.                         <goal>shade</goal>  

  12.                     </goals>  

  13.                     <configuration>  

  14.                         <filters>  

  15.                             <filter>  

  16.                                 <artifact>*:*</artifact>  

  17.                                 <excludes>  

  18.                                     <exclude>META-INF/*.SF</exclude>  

  19.                                     <exclude>META-INF/*.DSA</exclude>  

  20.                                     <exclude>META-INF/*.RSA</exclude>  

  21.                                 </excludes>  

  22.                             </filter>  

  23.                         </filters>  

  24.                         <transformers>  

  25.                             <transformer  

  26.                                 implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">  

  27.                                 <mainClass>com.defonds.RsaEncryptor</mainClass>  

  28.                             </transformer>  

  29.                             <transformer  

  30.                                 implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  

  31.                                 <resource>META-INF/spring.handlers</resource>  

  32.                             </transformer>  

  33.                             <transformer  

  34.                                 implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  

  35.                                 <resource>META-INF/spring.schemas</resource>  

  36.                             </transformer>  

  37.                         </transformers>  

  38.                     </configuration>  

  39.                 </execution>  

  40.             </executions>  

  41.         </plugin>  

  42.     </plugins>  

  43. </build>  


再次执行 maven clean package,再次执行成功构建后的 swiftonrsa-1.0.0.jar:
再次执行shade插件打包后的swiftonrsa

最后两行是具体业务实现类 com.defonds.service.LinkPayAntharServiceImpl 成功执行打印出的 log 日志。  

转载:http://blog.csdn.net/defonds/article/details/43233131

© 著作权归作者所有

岁月留痕
粉丝 3
博文 25
码字总数 25341
作品 0
郑州
私信 提问
【Maven 那点事儿】中的图是拿什么画的呀

@黄勇 你好,想跟你请教个问题: 【Maven 那点事儿】中的图http://my.oschina.net/huangyong/blog/194583是拿什么画的呀?

bopjiang
2014/12/12
136
0
Docker的那点事儿

Docker是什么? Docker是一个基于轻量级虚拟化技术的容器,整个项目基于Go语言开发,并采用了Apache 2.0协议。Docker可以将我们的应用程序打包封装到一个容器中,该容器包含了应用程序的代码...

SylvanasSun
2017/11/19
0
0
maven根据不同环境 不同配置打包

1.正确打包 项目有三种环境: 1.本地开发环境(local) 2.开发测试环境(dev) 3.线上生产环境(product) 不同的环境有不同的配置,比如数据库连接什么的....maven打包时默认去resources文件夹下打...

努力学的程序员
2016/04/28
4.3K
1
5分钟 maven3 快速入门指南

前提条件 你首先需要了解如何在电脑上安装软件。如果你不知道如何做到这一点,请询问你办公室,学校里的人,或花钱找人来解释这个给你。 不建议给Maven的服务邮箱来发邮件寻求支持。 安装Mav...

fanl1982
2014/01/23
10.9K
6
《maven官方文档》5分钟开始Maven

原文地址 前提 你必须明白如何在电脑上安装软件。如果你不知道如何做,请向你学校、办公室里等的人请教下,或者付费给他人让他们解释给你。Maven邮件组不是寻求这个建议的最好地方。 安装 Ma...

GarfieldEr007
2018/01/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Kafka 原理和实战

本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/bV8AhqAjQp4a_iXRfobkCQ 作者简介:郑志彬,毕业于华南理工大学计算机科学与技术(双语班)。先后从事过电子商务、开放平...

vivo互联网技术
56分钟前
17
0
java数据类型

基本类型: 整型:Byte,short,int,long 浮点型:float,double 字符型:char 布尔型:boolean 引用类型: 类类型: 接口类型: 数组类型: Byte 1字节 八位 -128 -------- 127 short 2字节...

audience_1
今天
8
0
太全了|万字详解Docker架构原理、功能及使用

一、简介 1、了解Docker的前生LXC LXC为Linux Container的简写。可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C++中的NameSpa...

Java技术剑
今天
21
0
Wifiphisher —— 非常非常非常流氓的 WIFI 网络钓鱼框架

编者注:这是一个非常流氓的 WIFI 网络钓鱼工具,甚至可能是非法的工具(取决于你的使用场景)。在没有事先获得许可的情况下使用 Wifiphisher 攻击基础网络设施将被视为非法活动。使用时请遵...

红薯
今天
87
1
MongoDB 4 on CentOS 7安装指南

本教程为CentOS x86_64 7.x操作系统下,MongoDB Community x86_64 4.2(GA)安装指南。 安装方式一:yum repo在线安装 [此方式较为简单,官方推荐] Step1:新建MongDB社区版Yum镜像源。 # vim ...

王焱君
今天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部