spring boot data cassandra reactive JmxReporter problem

locohost picture locohost · Nov 1, 2018 · Viewed 13.1k times · Source

I updated my project to spring-boot Version 2.1.0.RELEASE.
Now i get the following error:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.cassandra.ReactiveSession]: Factory method 'reactiveSession' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'session' defined in class path resource [ch/sbb/kat/fc/config/CassandraConfig.class]: Invocation of init method failed; 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.lambda$instantiate$2(ConstructorResolver.java:615)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:614)
    ... 120 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'session' defined in class path resource [ch/sbb/kat/fc/config/CassandraConfig.class]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: com/codahale/metrics/JmxReporter
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1745)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:576)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:339)
    at ch.sbb.kat.fc.config.CassandraConfig$$EnhancerBySpringCGLIB$$a22674d7.session(<generated>)
    at org.springframework.data.cassandra.config.AbstractCassandraConfiguration.getRequiredSession(AbstractCassandraConfiguration.java:66)
    at org.springframework.data.cassandra.config.AbstractReactiveCassandraConfiguration.reactiveSession(AbstractReactiveCassandraConfiguration.java:47)
    at ch.sbb.kat.fc.config.CassandraConfig$$EnhancerBySpringCGLIB$$a22674d7.CGLIB$reactiveSession$7(<generated>)
    at ch.sbb.kat.fc.config.CassandraConfig$$EnhancerBySpringCGLIB$$a22674d7$$FastClassBySpringCGLIB$$7973a63.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
    at ch.sbb.kat.fc.config.CassandraConfig$$EnhancerBySpringCGLIB$$a22674d7.reactiveSession(<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)
    ... 123 more
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:1501)
    at com.datastax.driver.core.Cluster.init(Cluster.java:208)
    at com.datastax.driver.core.Cluster.connectAsync(Cluster.java:376)
    at com.datastax.driver.core.Cluster.connect(Cluster.java:332)
    at org.springframework.data.cassandra.config.CassandraCqlSessionFactoryBean.connect(CassandraCqlSessionFactoryBean.java:89)
    at org.springframework.data.cassandra.config.CassandraCqlSessionFactoryBean.afterPropertiesSet(CassandraCqlSessionFactoryBean.java:82)
    at org.springframework.data.cassandra.config.CassandraSessionFactoryBean.afterPropertiesSet(CassandraSessionFactoryBean.java:59)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda$invokeInitMethods$5(AbstractAutowireCapableBeanFactory.java:1795)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1794)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1741)
    ... 143 more
Caused by: java.lang.ClassNotFoundException: com.codahale.metrics.JmxReporter
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 155 more

Using the property introduced in this issue https://github.com/spring-projects/spring-boot/issues/14778 seems to have no effect to solve my issue.

How can i disable jmx for cassandra?

My current cassandra config looks like this:

@Configuration
@EnableReactiveCassandraRepositories({"repository"})
public class CassandraConfig extends AbstractReactiveCassandraConfiguration {

    @Value("${cassandra.host}")
    private String host;

    @Override
    protected String getKeyspaceName() {
        return "keyspace";
    }

    @Override
    public String[] getEntityBasePackages() {
        return new String[]{"model"};
    }

    @Override
    public SchemaAction getSchemaAction() {
        return SchemaAction.CREATE_IF_NOT_EXISTS;
    }

    @Override
    public String getContactPoints() {
        return host;
    }
}

Answer

Andy Wilkinson picture Andy Wilkinson · Nov 2, 2018

The spring.data.cassandra.jmx-enabled property is used when Spring Boot is auto-configuring a Cassandra Cluster bean. By extending AbstractReactiveCassandraConfiguration, you are switching off this auto-configuration in favour of the Cluster bean that's created by AbstractClusterConfiguration which is a super-class of AbstractReactiveCassandraConfiguration. As a result, the property has no effect.

There are two ways that you can fix your problem:

  1. Remove your AbstractReactiveCassandraConfiguration sub-class and use the various spring.data.cassandra.* properties to configure things instead.
  2. Override cluster on AbstractClusterConfiguration in CassandraConfig, call super.cluster() to get the CassandraClusterFactoryBean and then call setJmxReportingEnabled(false) on the factory bean before returning it.

Alternatively, if you are not using Dropwizard elsewhere in your application, you may be able to downgrade to an older version that is compatible with Cassandra's JMX reporting by overriding the dropwizard-metrics.version property in your pom.xml or build.gradle.