天天看点

Spring Boot Cassandra JmxReporter 异常

简述

使用Spring boot 与>cassandra-driver-core时启动出现异常。

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.datastax.driver.core.Session]: Factory method 'createCluster' threw exception; nested exception is java.lang.NoClassDefFoundError: com/codahale/metrics/JmxReporter
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651)
	... 38 common frames omitted
Caused by: java.lang.NoClassDefFoundError: com/codahale/metrics/JmxReporter
	at com.datastax.driver.core.Metrics.<init>(Metrics.java:146)
	at com.datastax.driver.core.Cluster$Manager.init(Cluster.java:1667)
	at com.datastax.driver.core.Cluster.init(Cluster.java:214)
	at com.datastax.driver.core.Cluster.connectAsync(Cluster.java:387)
	at com.datastax.driver.core.Cluster.connect(Cluster.java:338)
	at com.crm.tool.config.CbaseConfig.createCluster(CbaseConfig.java:50)
	at com.crm.tool.config.CbaseConfig$$EnhancerBySpringCGLIB$$6bf97e8e.CGLIB$createCluster$0(<generated>)
	at com.crm.tool.config.CbaseConfig$$EnhancerBySpringCGLIB$$6bf97e8e$$FastClassBySpringCGLIB$$e91419f0.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
	at com.crm.tool.config.CbaseConfig$$EnhancerBySpringCGLIB$$6bf97e8e.createCluster(<generated>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
	... 39 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.codahale.metrics.JmxReporter
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 55 common frames omitted
           

Spring boot 版本:2.2.6.RELEASE

cassandra-driver-core:3.9.0

cassandra配置

@Bean
    public Session createCluster(@Autowired CbaseProperty cbaseProperty) {
        PoolingOptions poolingOptions = new PoolingOptions();
        poolingOptions.setConnectionsPerHost(HostDistance.LOCAL, 4, 10)
            .setConnectionsPerHost(HostDistance.REMOTE, 2, 4);
        String[] hosts = cbaseProperty.getAddresses().split(",");
        poolingOptions.setPoolTimeoutMillis(300000);
        Cluster cluster = Cluster.builder()
            .addContactPoints(hosts).
            .withCredentials(cbaseProperty.getUsername(), cbaseProperty.getPassword())
            .withPoolingOptions(poolingOptions).build();
        log.info("------>>连接Cbase成功");
        return cluster.connect("tt");
    }
           

问题分析

当Spring Boot自动配置Cassandra Cluster bean 时使用spring.data.cassandra.jmx-enabled该属性。通过扩展AbstractReactiveCassandraConfiguration,关闭此自动配置,而使用Cluster所创建的bean AbstractClusterConfiguration的超类AbstractReactiveCassandraConfiguration。结果,该属性无效。

有两种方法可以解决问题:

  • 删除您的AbstractReactiveCassandraConfiguration子类,并使用各种spring.data.cassandra.*属性来配置。
  • 重写cluster上AbstractClusterConfiguration的CassandraConfig,使用super.cluster()拿到CassandraClusterFactoryBean,然后调用setJmxReportingEnabled(false)返回之前在工厂bean。

解决方案

创建连接时加入withoutJMXReporting,上面的连接代码调整如下

Cluster cluster = Cluster.builder()
            .addContactPoints(hosts).withoutJMXReporting()
            .withCredentials(cbaseProperty.getUsername(), cbaseProperty.getPassword())
            .withPoolingOptions(poolingOptions).build();
           

继续阅读