Java Example with Cassandra 0.7

Last Friday release candidate 2 of the upcoming Cassandra 0.7 version saw the light of the day. It took a while to get some old Java test code working again using Thrift directly. Let's use this Maven project file:


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>javasplitter</groupId>
<artifactId>cassandra-test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<repositories>
<repository>
<id>riptano</id>
<name>Riptano Repository</name>
<url>http://mvn.riptano.com/content/repositories/riptano/</url>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>org.apache.cassandra</groupId>
<artifactId>apache-cassandra</artifactId>
<version>0.7.0-rc2</version>
</dependency>
<dependency>
<groupId>libthrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.5</version>
</dependency>
</dependencies>
</project>


You want to use the Riptano repository as these guys have all the latest artifacts very fast. Here is a snippet of my new yaml based Cassandra configuration - yammi:


...
keyspaces:
- name: "javasplitter"
replica_placement_strategy: org.apache.cassandra.locator.SimpleStrategy
replication_factor: 1
column_families:
- name: author
compare_with: BytesType


Straightforward, no advanced use cases. Some Java code involving Thrift that works.


TTransport framedTransport = new TFramedTransport(new TSocket("localhost", 9160));
TProtocol framedProtocol = new TBinaryProtocol(framedTransport);

Cassandra.Client client = new Cassandra.Client(framedProtocol);
framedTransport.open();

client.set_keyspace("javasplitter");
String columnFamily = "author";

ColumnParent cp = new ColumnParent(columnFamily);
byte[] userIDKey = "nadine".getBytes();
client.insert(
ByteBuffer.wrap(userIDKey),
cp,
new Column(
ByteBuffer.wrap("lastname".getBytes("UTF-8")),
ByteBuffer.wrap("schatz".getBytes("UTF-8")),
System.currentTimeMillis()
),
ConsistencyLevel.ONE);


One new thing is the use of framed transports. Make sure your cassandra.yaml has this line (which it does by default):


# Frame size for thrift (maximum field length).
# 0 disables TFramedTransport in favor of TSocket. This option
# is deprecated; we strongly recommend using Framed mode.
thrift_framed_transport_size_in_mb: 15


Make really sure you are using the above code against a 0.7 Cassandra installation otherwise you will get a lot of weird errors which are not really self explaining. For instance running the Java code above against Cassandra 0.6.8 would just freeze on the line containing framedTransport.open(). It is still possible to use plain TSocket transport or even to mix. Cassandra.Client has a constructor that takes two TProtocol instances (in and out).

Another thing that has changed is the use of java.nio.ByteBuffer from the Thrift based Cassandra.Client. Everything expects a ByteBuffer now (I think it took byte[] before) so the the code becomes a bit more verbose. Also make sure you are running with libthrift 0.5 (see pom.xml) otherwise you will get errors like:


java.lang.NoSuchMethodError: org.apache.thrift.protocol.TProtocol.writeBinary(Ljava/nio/ByteBuffer;)


I think 0.7 beta 2 used another version of libthrift (959516) so be careful. Anyway, you should probably use Hector from production code anyway. Should work well with 0.7 of Cassandra. I was however interested in Thrift since apparently Cassandra is moving away from Thrift to Avro. No idea yet, why Avro is better. It can't be the performance.