Curator 报 NoSuchMethodError: org.apache.zookeeper.server.quorum.flexible.QuorumMaj.(Ljava/u...

方法论:认识问题、分析问题、解决问题。

1. 问题描述

Dubbo 应用使用 ZooKeeper 作为注册中心,启动时发生该异常。

ZooKeeper和Curator的JAR版本

curator-framework-3.3.0
zookeeper-3.4.9

ZooKeeper服务器的版本:3.5.1-alpha

$ echo stat | nc localhost 2181
Zookeeper version: 3.5.1-alpha-1693007, built on 07/28/2015 07:19 GMT

2. 异常日志

2017-10-03 23:57:01.422  INFO 94641 --- [           main] utoConfigurationReportLoggingInitializer :

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-10-03 23:57:01.431 ERROR 94641 --- [           main] o.s.boot.SpringApplication               : Application startup failed

java.lang.NoSuchMethodError: org.apache.zookeeper.server.quorum.flexible.QuorumMaj.<init>(Ljava/util/Map;)V
    at org.apache.curator.framework.imps.EnsembleTracker.<init>(EnsembleTracker.java:59) ~[curator-framework-3.3.0.jar:3.3.0]
    at org.apache.curator.framework.imps.CuratorFrameworkImpl.<init>(CuratorFrameworkImpl.java:158) ~[curator-framework-3.3.0.jar:3.3.0]
    at org.apache.curator.framework.CuratorFrameworkFactory$Builder.build(CuratorFrameworkFactory.java:156) ~[curator-framework-3.3.0.jar:3.3.0]
    at com.alibaba.dubbo.remoting.zookeeper.curator.CuratorZookeeperClient.<init>(CuratorZookeeperClient.java:36) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter.connect(CuratorZookeeperTransporter.java:10) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.remoting.zookeeper.ZookeeperTransporter$Adaptive.connect(ZookeeperTransporter$Adaptive.java) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistry.<init>(ZookeeperRegistry.java:69) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistryFactory.createRegistry(ZookeeperRegistryFactory.java:37) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.registry.support.AbstractRegistryFactory.getRegistry(AbstractRegistryFactory.java:95) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.registry.RegistryFactory$Adaptive.getRegistry(RegistryFactory$Adaptive.java) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.registry.integration.RegistryProtocol.getRegistry(RegistryProtocol.java:201) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.registry.integration.RegistryProtocol.export(RegistryProtocol.java:118) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper.export(ProtocolListenerWrapper.java:54) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper.export(ProtocolFilterWrapper.java:92) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.rpc.Protocol$Adaptive.export(Protocol$Adaptive.java) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.config.ServiceConfig.doExportUrlsFor1Protocol(ServiceConfig.java:550) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.config.ServiceConfig.doExportUrls(ServiceConfig.java:346) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.config.ServiceConfig.doExport(ServiceConfig.java:307) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.config.ServiceConfig.export(ServiceConfig.java:206) ~[dubbo-2.5.5.jar:2.5.5]
    at com.alibaba.dubbo.config.spring.ServiceBean.onApplicationEvent(ServiceBean.java:109) ~[dubbo-2.5.5.jar:2.5.5]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:883) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at spring.guides.dubbo.DubboProviderApplication.main(DubboProviderApplication.java:25) [classes/:na]

3. 问题分析

与本异常相关的关键源代码:

public class EnsembleTracker implements Closeable, CuratorWatcher
{
    ......

    private final AtomicReference<QuorumMaj> currentConfig = new AtomicReference<>(new QuorumMaj(Maps.<Long, QuorumPeer.QuorumServer>newHashMap()));

    ......
}


public class QuorumMaj implements QuorumVerifier {
    ......

    int half;

    /**
     * Defines a majority to avoid computing it every time.
     *
     * @param n number of servers
     */
    public QuorumMaj(int n){
        this.half = n/2;
    }

    ......

}

根据上述源代码,问题根源QuorumMaj类未定义单个Map参数的构造函数,而EnsembleTracker类却引用了它
问题的本质JAR包冲突引发的代码不兼容问题

4. 解决方案

  • 升级 ZooKeeper JAR版本到 zookeeper-3.5.3-beta

祝玩得开心!ˇˍˇ
云舒,2017.10.4,杭州

    原文作者:云舒Lee
    原文地址: https://www.jianshu.com/p/5ac6e7cdbc00
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞