HBase用到了Guava,并且版本较旧,hbase-1.1使用的是guava-12.0.1,我们的项目中有时候也会用到guava,往往使用的是新版本的,在version 16之后好像是不能向后兼容的,这里也没多说,这时候项目启动会报一些依赖错误,要么是hbase依赖的方法找不到,要么是自家项目依赖的方法找不到,这时候怎么办?
java.lang.ClassNotFoundException: com.google.common.base...
java.lang.IllegalAccessError: tried to access method com.google.common.base...
我们不太可能修改hbase的源码,所以只能改自家的项目呗。但是非要降低自己项目的依赖版本吗?未必。这时候幸好有maven-shade-plugin,它可以把依赖的包打包进项目的jar,并且可以修改依赖包的包名(relocate),这样一来,自己项目就可以随心所欲使用任意版本的guava包了,因为编译后它使用的是另一个包名下guava类了。shaded后的它不再需要依赖guava了。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>shaded.com.google.common</shadedPattern>
</relocation>
</relocations>
<artifactSet>
<includes>
<include>*:*</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
mvn clean install打包完,target目录的jar包已经被动过手脚了,其他项目可以引用这个包而不用顾虑它使用的guava版本了;项目下还会生成一个dependency-reduced-pom.xml,里面已经看不到guava了。可以用这个pom来一起发布jar。
但有时候hbase和某个第三方的jar的依赖有冲突怎么办?比如ES和hbase打架了?答案还是shade。热心的社区已经为hbase编译好了shaded的版本,可以直接使用:http://mvnrepository.com/artifact/org.apache.hbase/hbase-shaded-client
参考链接:
https://www.elastic.co/blog/to-shade-or-not-to-shade
https://issues.apache.org/jira/browse/HBASE-16403
https://bryantsai.com/how-to-resolve-dependency-conflict-out-of-your-control-e75ace79e54f