[置顶] 使用 maven 插件 maven-shade-plugin 对可执行 java 工程及其全部依赖 jar 进行打包
作者:chenzhou123520
出处:http://chenzhou123520.iteye.com/blog/1706242
使用 maven 插件 maven-shade-plugin 对 java 工程及其全部依赖 jar 进行打包
现在基本上都是采用 maven 来进行开发管理,我有一个需求是需要把通过 maven 管理的 java 工程打成可执行的 jar 包,这样也就是说必需把工程依赖的 jar 包也一起打包。而使用 maven 默认的 package 命令构建的 jar 包中只包括了工程自身的 class 文件,并没有包括依赖的 jar 包。我们可以通过配置插件来对工程进行打包,pom 具体配置如下:
maven-assembly-plugin (使用此插件会有一些问题)
- <plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <configuration>
- <appendAssemblyId>false</appendAssemblyId>
- <descriptorRefs>
- <descriptorRef>jar-with-dependencies</descriptorRef>
- </descriptorRefs>
- <archive>
- <manifest>
- <mainClass>com.chenzhou.examples.Main</mainClass>
- </manifest>
- </archive>
- </configuration>
- <executions>
- <execution>
- <id>make-assembly</id>
- <phase>package</phase>
- <goals>
- <goal>assembly</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
其中 <mainClass></mainClass> 的值表示此工程的入口类,也就是包含 main 方法的类,在我的例子中就是 com.chenzhou.examples.Main。配置完 pom 后可以通过执行 mvn assembly:assembly 命令来启动插件进行构建。构建成功后会生成 jar 包,这样我们就可以在命令行中通过 java -jar XXX.jar 来运行 jar 文件了。
不过使用此插件会有一些问题:我在工程中依赖了 spring 框架的 jar 包,我打包成功后使用命令来调用 jar 包时报错如下(内网环境):
- : Failed to read schema document 'http://www.springframework.org/schema/beans/spring-beans-3.0.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
关于此问题报错的原因,我在网上找到一篇文章对此有比较详细的解释:http://blog.csdn.net/bluishglc/article/details/7596118 简单来说就是
spring 在启动时会加载 xsd 文件,它首先会到本地查找 xsd 文件(一般都会包含在 spring 的 jar 包中),如果找不到则会到 xml 头部定义的 url 指定路径下中去寻找 xsd,如果找不到则会报错。
附:在 spring jar 包下的 META-INF 文件夹中都会包含一个 spring.schemas 文件,其中就包含了对 xsd 文件的路径定义,具体如下图所示:

图:spring-aop.jar 包下 META-INF 文件夹下的内容

图:spring.schemas 文件内容
由于我的工程是在内网,所以通过 url 路径去寻找肯定是找不到的,但是比较奇怪的是既然 spring 的 jar 包中都会包含,那为什么还是找不到呢?
原来这是 assembly 插件的一个 bug,具体情况参见:http://jira.codehaus.org/browse/MASSEMBLY-360
该 bug 产生的原因如下:工程一般依赖了很多的 jar 包,而被依赖的 jar 又会依赖其他的 jar 包,这样,当工程中依赖到不同的版本的 spring 时,在使用 assembly 进行打包时,只能将某一个版本 jar 包下的 spring.schemas 文件放入最终打出的jar包里,这就有可能遗漏了一些版本的 xsd 的本地映射,所以会报错。
所以一般推荐使用另外的一个插件来进行打包,插件名称为:maven-shade-plugin,shade 插件打包时在对 spring.schemas 文件处理上,它能够将所有 jar 里的 spring.schemas 文件进行合并,在最终生成的单一 jar 包里,spring.schemas 包含了所有出现过的版本的集合,要使用 shade 插件,必须在 pom 进行如下配置:
- <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.AppendingTransformer">
- <resource>META-INF/spring.handlers</resource>
- </transformer>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <mainClass>com.chenzhou.examples.Main</mainClass>
- </transformer>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
- <resource>META-INF/spring.schemas</resource>
- </transformer>
- </transformers>
- </configuration>
- </execution>
- </executions>
- </plugin>
上面配置文件中有一段定义:
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
- <resource>META-INF/spring.handlers</resource>
- </transformer>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
- <resource>META-INF/spring.schemas</resource>
- </transformer>
上面这段配置意思是把 spring.handlers 和 spring.schemas 文件以 append 方式加入到构建的 jar 包中,这样就不会出现 xsd 找不到的情况。
配置完 pom 后,调用 mvn clean install 命令进行构建,构建成功后打开工程 target 目录,发现生成了 2 个 jar 包,一个为:original-XXX-0.0.1-SNAPSHOT.jar,另一个为:XXX-0.0.1-SNAPSHOT.jar,其中 original...jar 里只包含了工程自己的 class 文件,而另外的一个 jar 包则包含了工程本身以及所有依赖的 jar 包的 class 文件。我们只需要使用第二个
jar 包就可以了。
参考资料:
http://hi.baidu.com/yuzhi2217/item/2c1714363f25c4f62684f442
[置顶] 使用 maven 插件 maven-shade-plugin 对可执行 java 工程及其全部依赖 jar 进行打包的更多相关文章
- groovy入门(2-1)Groovy的Maven插件安装:Plugin execution not covered by lifecycle configuration
参考链接:http://www.cnblogs.com/rightmin/p/4945797.html 1.引入groovy的jar包 2.引入groovy编译插件 3.遇到问题 Plugin exe ...
- Eclipse下Maven插件配置
要做一个基于C/S架构的汽车租赁系统,由于在实习期间接触过一些Java和SpringMVC,Spring,Hibernate的东西,所以决定使用这个框架组合来完成这个项目. 首先是Maven的配置,为 ...
- 【mybatis源码学习】利用maven插件自动生成mybatis代码
[一]在要生成代码的项目模块的pom.xml文件中添加maven插件 <!--mybatis代码生成器--> <plugin> <groupId>org.mybat ...
- Maven学习(十六)-----Maven插件
Maven插件 Maven 是一个执行插件的框架,每一个任务实际上是由插件完成的.Maven 插件通常用于: 创建 jar 文件 创建 war 文件 编译代码文件 进行代码单元测试 创建项目文档 创建 ...
- Java-Maven-Runoob:Maven 插件
ylbtech-Java-Maven-Runoob:Maven 插件 1.返回顶部 1. Maven 插件 Maven 有以下三个标准的生命周期: clean:项目清理的处理 default(或 bu ...
- 使用maven插件dockerfile-maven-plugin生成Docker镜像并推送到镜像仓库
1.引入maven插件 <build> <plugins> <plugin> <groupId>com.spotify</groupId> ...
- Maven插件的简介,安装及在eclipse中配置
1.Maven简介 1.Maven介绍 Maven是一个基于项目对象模型(POM:project object model)的概念的纯java开发的开源的项目管理工具.Maven把我们的工程抽像一个对 ...
- maven课程 项目管理利器-maven 3-4 eclipse安装maven插件和新建maven项目
本节主要讲了两个主要内容, 1 eclipse安装maven插件 2 新建maven项目 3 本人实操 1 eclipse安装maven插件 eclipse4.0以上和myec ...
- eclipse插件——maven
项目开发中遇到的问题 都是同样的代码,为什么在我的机器上可以编译执行,而在他的机器上就不行? 为什么在我的机器上可以正常打包,而配置管理员却打不出来? 项目组加入了新的人员,我要给他说明编译环境如何设 ...
随机推荐
- 【JavaScript框架封装】公共框架的封装
/* * @Author: 我爱科技论坛 * @Time: 20180706 * @Desc: 实现一个类似于JQuery功能的框架 // 公共框架 // 种子模块:命名空间.对象扩展.数组化.类型的 ...
- [luogu1600 noip2016] 天天爱跑步 (树上差分)
题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵 ...
- 【codeforces 799A】Carrot Cakes
[题目链接]:http://codeforces.com/contest/799/problem/A [题意] 你有一个烤炉; 每t秒能同时烤出k个蛋糕; 你可以在第一个烤炉在烤的时候;同时花费d秒建 ...
- Myeclipse学习总结(6)——MyEclipse断点调试
当程序写好之后,如何调试呢? 我们在MyEclipse中jav添加断点,运行debug as-->open debug Dialog,然后在对话框中选类后--> Run在debug视图下. ...
- 教你十分钟构建好 SpringBoot + SSM 框架
目前最主流的 java web 框架应该是 SSM,而 SSM 框架由于更轻便与灵活目前受到了许多人的青睐.而 SpringBoot 的轻量化,简化项目配置, 没有 XML 配置要求等优点现在也得到了 ...
- PatentTips - Optimizing power usage by factoring processor architectural events to PMU
BACKGROUND Processor power consumption has become a major issue in recent years. The current trend o ...
- T4系列文章之2:T4工具简介、调试以及T4运行原理
一.前言 经过第一篇,我想大家现在对T4有了基本的印象,应该对T4有了一个大致的了解吧.现在,我们接着来讲一下T4的工具,然后下一篇我就开始T4的用法了.各位客官,就等了. 二.工具介绍 2.1 上图 ...
- 在ActivityA中关闭还有一个ActivityB
1.对于简单的两个Activity public class A_activity extends Activity { public static A_activity _instance = nu ...
- 0x27 A*
终于完全了解A*到底是什么玩意儿了 对于当前的决策,选取当前花费+预估花费最小来拓展. 因为假如预估出现失误,那么很可能就会延伸到一个错误的决策点,而这个决策点偏偏就是ed,而由于预估失误,其他点的当 ...
- Python·Jupyter Notebook各种使用方法记录
标签(空格分隔): Python 一 Jupyter NoteBook的安装 1 新版本Anaconda自带Jupyter 2 老版本Anacodna需自己安装Jupyter 二 更改Jupyter ...