今天遇到一个问题,maven项目里面配置的使用assembly插件打包,我在项目中使用同包名类名的方式覆盖依赖jar中的类,但就是自己项目的类打包不进去,改为shade就i一下就可以了,所以我想研究 shade assembly区别。
1.assembly的优点
thin jar
如果打fat jar,所有相关的类(含依赖)会被打进一个jar包,此时的问题是这个包除了比较大外,还失去了通过替换jar包更新程序的灵活性。assembly不会将依赖的jar包合并,仅仅是将它们放在一个压缩包中。
打包脚本,配置文件等
assembly除了打包依赖外,还能include用户定义的目录或文件。如一般项目都会在bin目录中放启动脚本等。
自定义依赖
assembly默认打包所有依赖的依赖,默认行为可能会打出很多jar包,可以手动include/exclude。
2.assembly的缺点
手动依赖修剪
assembly虽然可以通过定义include/exclude修剪依赖,但是需要用户明确自己的代码中用到了哪些,没用到哪些,否则如果该include没有include或被exclude了,那么很容易出No Class Found Exception
3.shade的优点
shade支持修剪不必要的依赖
不像assembly需要用户自己进行修剪,shade能过通过字节码分析自动修剪掉不必要的依赖。
能够通过替换包名避免依赖冲突
如果一个项目中同时依赖了某个库的两个版本,比如spark程序中,自己的代码依赖okhttp 3, spark本身的代码依赖okhttp 2.此时除了重写自己的代码,更改依赖外,还可以通过shade解决依赖冲突。巧用maven-shade-plugin解决依赖冲突 - 简书
4.shade的缺点
不能打thin jar
即使shade能够修剪依赖,最终也只能将所有类打到一个jar包中。
无法打包脚本,配置文件等
总结
Assembly 插件不仅会将 Dependency 中的 Class 文件打入最终的 Jar 包,还会将 Dependency 中的资源文件,诸如 properties 文件打入最终的 Jar 包。
当项目和其 Dependency 中有同名的资源文件是,就会发生冲突,项目中的同名文件便不会加入到最终的 Jar 包中。
如果这个文件是一个关键的配置文件,便会导致问题。而 Shade Plugin 不存在这样的问题。