【前提】
我们的项目是一个父子项目,基本上每个子项目都依赖了org.apache.spark:spark-core_2.11:2.1.1;
其中个别子项目除了依赖spark-core_2.11外,还依赖org.elasticsearch.client:transport:5.6.2
【现象】
包编译正常,但在linux环境下运行时,引用了elasticsearch的模块运行正常;其它未引用的模块执行时报下面的错误。
java.lang.AbstractMethodError: io.netty.util.concurrent.MultithreadEventExecutorGroup.newChild(....)
【网上资源】
网上有对此问题的分析,比较好的帖子:
https://blog.csdn.net/blomule/article/details/43058111
https://blog.csdn.net/jiahao1186/article/details/97899713
【问题解决】
根据网上帖子的说明,进入父项目有pom.xml文件的目录,执行以下命令看到所有子项目对第三方包的依赖关系,也可以进行某个子项目有pom.xml文件的目录,执行下面命令,只查看该子项目对第三方包的依赖关系:
mvn dependency:tree -Dverbose
结合网上资源的说明,大致了解问题的原因:
org.apache.spark:spark-core_2.11:2.1.1 依赖:
io-netty:netty-all:jar:4.0.42
org.elasticsearch.client:transport:5.6.2 依赖:
io.netty:netty-buffer:4.1.13, io.netty:netty-codec:4.1.13, io.netty:netty-common:4.1.13 ...等
io.netty:netty-buffer:4.1.13, io.netty:netty-codec:4.1.13, io.netty:netty-common:4.1.13 ...等
个人猜测:
netty-all 与 io.netty:netty-buffer:4.1.13 + io.netty:netty-codec:4.1.13 + io.netty:netty-common:4.1.13是等同的,但两者间有某个类或者方法的定义发生了改变。具体原因未知。
最终解决修改:
step1: 父项目的pom.xml文件中,添加如下项:
<dependencyManagement><dependencies>...<dependency><groupId>org.elasticsearch.client</groupId><artifactId>transport</artifactId><version>5.6.2</version><exclusions><exclusion><groupId>io.netty</groupId><artifactId>netty-buffer</artifactId></exclusion><exclusion><groupId>io.netty</groupId><artifactId>netty-codec</artifactId></exclusion><exclusion><groupId>io.netty</groupId><artifactId>netty-codec-http</artifactId></exclusion><exclusion><groupId>io.netty</groupId><artifactId>netty-common</artifactId></exclusion><exclusion><groupId>io.netty</groupId><artifactId>netty-handler</artifactId></exclusion><exclusion><groupId>io.netty</groupId><artifactId>netty-resolver</artifactId></exclusion><exclusion><groupId>io.netty</groupId><artifactId>netty-transport</artifactId></exclusion></exclusions></dependency>...</dependencies></dependencyManagement>
两点说明:
1) 在dependencyManagement中的依赖,只是定义,并没有真正的引入
2) 上面挨个排除了netty-buffer、netty-codec、netty-common等,不能使用*或netty-*方式
step2: 在使用elasticsearch子项目的pom.xml文件中,正常引入即可
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>transport</artifactId></dependency>
说明:
也可以step1不做,这样的话,step2中就需要增加exclusions信息;并且每个引用了elasticsearch子项目的pom.xml文件中都需要做相同的设置。