uber jar,shade jar和包冲突

我们日常遇到的包冲突主要是依赖jar的版本冲突。在包都向下兼容的前提下,这类问题比较容易解决,exclusion对低版本的依赖即可。但也有不兼容导致多个依赖无法兼顾的情况,如何解决,下文再说。

考虑另一种情况,完全不同的jar实现了同名类,而且包名也一模一样。此时对java类加载器而言,和上一类问题是同质的。基于JVM的有则运行,无则加载的类处理原则,实际上生效的也将是加载顺序在前的类。

这种情况在uber jar中出现机会较多。uber jar简单地说就是使用maven-shade-plugin直接打入了依赖类的jar,减少了对外部jar lib的依赖。举个例子,hive-exec-2.0.0就是个典型的uber jar。我们看一下他的pom文件和类文件就明白了。



……
com.google.protobuf:protobuf-java
……


include的项可以是直接的也可以是间接的,实际include的版本号可以从pom下的dependency中找到。 在hive-exec-2.0.0的jar下能看到com.google.protobuf包以及该包名下的所有class文件。

从外部来看,相当于hive-exec用一样的包名类名自己实现了谷歌上面这一堆类,而且不是外部依赖,所以无法用exclusion排除。于是问题来了,当项目原来依赖了和hive-exec中的protobuf版本不兼容的protobuf,冲突就不可避免。

那么,怎么解决这个问题呢?解铃还须系铃人,maven-shade-plugin除了构建uber jar之外,还能构建shade jar。shade jar有一个好,就是能按开发者的意图把jar封装一层,从而java的类加载器就能把这些类区分开,同时加载进去。对原有com.google.protobuf的处理如pom文件所示。


                            
com.google.protobuf                           
xxx.com.google.protobuf



在项目代码中,除hive外原有的对com.google.protobuf的依赖变更为对xxx.com.google.protobuf的依赖即可。同时,hive-exec中用的依然是他自有的com.google.protobuf,如此则两全其美。上文中第一类不兼容也可以用这个方法解决。

你可能感兴趣的:(uber jar,shade jar和包冲突)