Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot 1.4.1 and Cassandra 3.x

I want to use Cassandra 3.x in a Spring Boot project. I found out that the current release version of the Spring Data Cassandra project only supports Cassandra 2.x. So I wanted to use the DataStax Driver instead of the Spring Data Cassandra project. I added

compile 'com.datastax.cassandra:cassandra-driver-core:3.1.1'

as a dependency. Now I can insert values into a keyspace on a Cassandra cluster. But when running tests for a REST controller I get an error

java.lang.NoClassDefFoundError: io/netty/handler/codec/http/FullHttpRequest

So I added

compile 'io.netty:netty-all:4.1.6.Final'

as a dependency and the error went away. But now all tests using

TestRestTemplate.postForObject(...)

or

TestRestTemplate.put(...)

fail. But using

TestRestTemplate.getForObject(...)

works as expected. I assume there's some clash in the dependencies of Spring Boot and the Netty version I added as a dependency.

I found out that the latest version of the DataStax Cassandra driver to work without the additional Netty dependency is 2.1.5 which is dated Mar 2015 and doesn't support Cassandra 3. Using this driver everything works but I don't want to use a driver that old.

UPDATE: I removed the DataStax driver dependency and tried to use the 1.5.0.M1 version of Spring Data Cassandra and overrode the Spring, Spring Data Cassandra and Cassandra driver versions in the buildscript.

ext['spring.version'] = '5.0.0.M2'
ext['spring-data-releasetrain.version'] = 'Ingalls-M1'
ext['cassandra-driver.version'] = '3.1.1'

This resulted in the following error:

java.lang.NoClassDefFoundError: io/netty/util/Timer

when using Cassandra functionality. When I include Netty again, Cassandra functionality works but my tests using TestRestTemplate.put and .post aren't running anymore. I gave it another try upgrading to Spring Boot Version 2.0.0.BUILD-SNAPSHOT which also includes Spring Data Cassandra 1.5.0.M1. Now when I start the app and use DataStax Driver functionality I get the same NoClassDefFoundError as before. Adding Netty as a dependency kills my TestRestTemplate based unit tests again...

UPDATE: TestRestTemplate isn't working because Spring Boot configures it to use Netty4ClientHttpRequestFactory when it finds Netty on the classpath and the Netty4ClientHttpRequestFactory doesn't seem to work.

See https://github.com/spring-projects/spring-boot/issues/7240 and https://jira.spring.io/browse/SPR-14860

For a fix see my answer to this question.

like image 925
Emanuel Seidinger Avatar asked Oct 25 '16 15:10

Emanuel Seidinger


People also ask

Which version of Spring is compatible with Spring boot?

Spring Boot 2.0 builds on and requires Spring Framework 5.

Which version of Spring does spring boot 2.6 2 use?

Spring Boot 2.6 moves to new versions of several Spring projects: Spring Data 2021.1. Spring HATEOAS 1.4. Spring AMQP 2.4.


1 Answers

I stick to using Spring Data Cassandra 1.5.0.M1 and Cassandra driver 3.1.1 using the following version overrides:

ext['spring.version'] = '5.0.0.M2'
ext['spring-data-releasetrain.version'] = 'Ingalls-M1'
ext['cassandra-driver.version'] = '3.1.1'

To make Cassandra driver functionality work I had to add Netty as a dependency.

compile 'io.netty:netty-all:4.1.6.Final'

To make TestRestTemplate.postForObject(...) and TestRestTemplate.put(...) I had to provide a RestTemplateBuilder @Bean and configure it to use SimpleClientHttpRequestFactory.

@TestConfiguration
static class TestConfig {
    @Bean
    public RestTemplateBuilder restTemplateBuilder() {
        return new RestTemplateBuilder().detectRequestFactory(false).requestFactory(SimpleClientHttpRequestFactory.class);
    }
}
like image 57
Emanuel Seidinger Avatar answered Oct 17 '22 22:10

Emanuel Seidinger