## 四、maven-shade-plugin插件
### 4.1 官方文档说明
第三种方式是使用maven-shade-plugin,既然已经有了maven-assembly-plugin,为什么还需要maven-shade-plugin,这一点在官方文档中也是有所说明的,来自于官方对HDFS整合讲解的章节[Storm HDFS Integration](http://storm.apache.org/releases/2.0.0-SNAPSHOT/storm-hdfs.html),原文如下:
>When packaging your topology, it's important that you use the [maven-shade-plugin](http://storm.apache.org/releases/2.0.0-SNAPSHOT/storm-hdfs.html) as opposed to the [maven-assembly-plugin](http://storm.apache.org/releases/2.0.0-SNAPSHOT/storm-hdfs.html).
>
>The shade plugin provides facilities for merging JAR manifest entries, which the hadoop client leverages for URL scheme resolution.
>
>If you experience errors such as the following:
>
>```
>java.lang.RuntimeException: Error preparing HdfsBolt: No FileSystem for scheme: hdfs
>```
>
>it's an indication that your topology jar file isn't packaged properly.
>
>If you are using maven to create your topology jar, you should use the following `maven-shade-plugin` configuration to create your topology jar。
这里第一句就说的比较清晰,在集成HDFS时候,你必须使用maven-shade-plugin来代替maven-assembly-plugin,否则会抛出
RuntimeException异常。
采用maven-shade-plugin打包有很多好处,比如你的工程依赖很多的JAR包,而被依赖的JAR又会依赖其他的JAR包,这样,当工程中依赖到不同的版本的 JAR时,并且JAR中具有相同名称的资源文件时,shade插件会尝试将所有资源文件打包在一起时,而不是和assembly一样执行覆盖操作。
### 4.2 配置
采用`maven-shade-plugin`进行打包时候,配置示例如下:
```xml
org.apache.maven.pluginsmaven-shade-plugintrue*:*META-INF/*.SFMETA-INF/*.sfMETA-INF/*.DSAMETA-INF/*.dsaMETA-INF/*.RSAMETA-INF/*.rsaMETA-INF/*.ECMETA-INF/*.ecMETA-INF/MSFTSIG.SFMETA-INF/MSFTSIG.RSAorg.apache.storm:storm-corepackageshade
```
以上配置示例来源于Storm在Github上的examples,这里做一下说明:
在上面的配置中,排除了部分文件,这是因为有些JAR包生成时,会使用jarsigner生成文件签名(完成性校验),分为两个文件存放在META-INF目录下:
+ a signature file, with a .SF extension;
+ a signature block file, with a .DSA, .RSA, or .EC extension;
如果某些包的存在重复引用,这可能会导致在打包时候出现`Invalid signature file digest for Manifest main attributes`异常,所以在配置中排除这些文件。
### 4.3 打包命令
使用maven-shade-plugin进行打包的时候,打包命令和普通的一样:
```shell
# mvn package
```
打包后会生成两个JAR包,提交到服务器集群时使用非original开头的JAR.
如果你不排除storm-core,通常会抛出下面的异常:
```properties
Caused by: java.lang.RuntimeException: java.io.IOException: Found multiple defaults.yaml resources.
You're probably bundling the Storm jars with your topology jar.
[jar:file:/usr/app/apache-storm-1.2.2/lib/storm-core-1.2.2.jar!/defaults.yaml,
jar:file:/usr/appjar/storm-hdfs-integration-1.0.jar!/defaults.yaml]
at org.apache.storm.utils.Utils.findAndReadConfigFile(Utils.java:384)
at org.apache.storm.utils.Utils.readDefaultConfig(Utils.java:428)
at org.apache.storm.utils.Utils.readStormConfig(Utils.java:464)
at org.apache.storm.utils.Utils.(Utils.java:178)
... 39 more
```