Spring Boot 1.4.1 and Cassandra 3.x

cassandra, cassandra-3.0, java, spring, spring-boot

Solution

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

Problem

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.

Original source