【问题标题】:spring boot data cassandra reactive JmxReporter problemspring boot 数据 cassandra 反应式 JmxReporter 问题
【发布时间】:2019-04-05 16:55:48
【问题描述】:

我将我的项目更新为 spring-boot 版本 2.1.0.RELEASE。
现在我收到以下错误:

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

使用本期介绍的属性https://github.com/spring-projects/spring-boot/issues/14778似乎对解决我的问题没有效果。

如何禁用 cassandra 的 jmx?

我当前的 cassandra 配置如下所示:

@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;
    }
}

【问题讨论】:

  • ch.sbb.kat.fc.config.CassandraConfig 在做什么?从它的名字来看,我猜你是手动配置 Cassandra。因此,Boot 的自动配置将退出,因此该属性将无效。
  • @AndyWilkinson CassandraConfig 扩展了 AbstractReactiveCassandraConfiguration 我覆盖了键空间、接触点、实体库包和模式操作。集群bean是spring创建的。

标签: spring spring-boot spring-data-cassandra


【解决方案1】:

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

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

  1. 删除您的 AbstractReactiveCassandraConfiguration 子类并使用各种 spring.data.cassandra.* 属性来配置内容。
  2. CassandraConfig 中覆盖AbstractClusterConfiguration 上的cluster,调用super.cluster() 以获取CassandraClusterFactoryBean,然后在返回工厂bean 之前调用setJmxReportingEnabled(false)

或者,如果您没有在应用程序的其他地方使用 Dropwizard,则可以通过覆盖 pom.xmlbuild.gradle 中的 dropwizard-metrics.version 属性来降级到与 Cassandra 的 JMX 报告兼容的旧版本。

【讨论】:

  • 感谢您的帮助。
  • ticket 中的降级提示:问题是 cassandra-driver-core 3.6.0 依赖于 dropwizard 版本 3.2.2。 4.0.3 版包含一个导致类未找到错误的重大更改。
  • 对于那些使用 TestContainers 的人,请注意 CassandraContainer 在执行 CQL 初始化脚本时使用 JMX 报告:github.com/testcontainers/testcontainers-java/issues/1011
【解决方案2】:

除了像 Andy Wilkinson 提到的那样覆盖 cluster 之外,您还可以覆盖 getMetricsEnabled 以便始终返回 false

@Override
protected boolean getMetricsEnabled() { return false; }

【讨论】:

  • 感谢您指出这一点。我也在寻找覆盖该值的方法,但总是寻找名称中带有 jmx 的东西;)这也比从超类中获取集群更方便
  • 不客气。 cluster 的默认实现调用 getMetricsEnabled。通过仅覆盖getMetricsEnabled,我们可以保留cluster的默认实现(和行为)
  • 这是一种更简洁的禁用指标的方法,喜欢它。
【解决方案3】:

我在这里尝试了答案,我不知道如何但错误仍然存​​在。 我从docs.datastax.com 读到这篇文章,他们谈到将Metrics 4 中的JMX reporting 移动到一个单独的模块metrics-jmx。他们明确表示这可能会导致问题/错误。

要解决此问题,我只需调用此方法 .withoutJMXReporting(),如下所示。

Cluster cluster = Cluster.builder()
        .withoutJMXReporting()
        .build();

你可以悄悄关注here

【讨论】:

    【解决方案4】:

    包含旧版本的库也修复了问题:

    implementation("io.dropwizard.metrics:metrics-core:3.2.2")

    【讨论】:

      【解决方案5】:

      @豆 公共 CassandraClusterFactoryBean 集群(){ CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean(); cluster.setContactPoints(environment.getProperty("spring.data.cassandra.contact-points")); cluster.setPort(Integer.parseInt(environment.getProperty("spring.data.cassandra.port"))); cluster.setJmxReportingEnabled(false); 返回集群; }

      cluster.setJmxReportingEnabled(false) 似乎是答案。

      【讨论】:

        猜你喜欢
        • 2017-07-01
        • 2020-12-02
        • 2015-11-16
        • 1970-01-01
        • 2020-11-04
        • 2020-04-05
        • 2018-06-24
        • 2017-07-26
        • 2021-08-31
        相关资源
        最近更新 更多