Table of Contents

Java

For Java we recommend using the XMemcached client. There is also the SpyMemcached client which we have recommended in the past. Many MemCachier customers reported problems with SpyMemcached in the presence of network issues. SpyMemcached seems to have trouble coping with connection timeouts or resets. For this reason we now recommend XMemcached.

We also recommend using Apache Maven or Gradle as a build tool. Here we show the dependency configuration for Maven but they are similar for Gradle. If you aren’t using Maven or Gradle and are instead using Apache Ant or your own build system, then simply add the xmemcached or spymemcached jar file as a dependency of your application.

XMemcached

To use XMemcached with Maven you need to add the xmemcached library to your dependencies in your pom.xml file:

<dependency>
  <groupId>com.googlecode.xmemcached</groupId>
  <artifactId>xmemcached</artifactId>
  <version>2.4.3</version>
</dependency>

If you are using a version older than 2.4.3, please update to the latest version as it contains important bug fixes.

Once your build system is configured, you can start adding caching to your Java app:

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.auth.AuthInfo;
import net.rubyeye.xmemcached.command.BinaryCommandFactory;
import net.rubyeye.xmemcached.exception.MemcachedException;
import net.rubyeye.xmemcached.utils.AddrUtil;

import java.lang.InterruptedException;
import java.net.InetSocketAddress;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeoutException;

public class App {
  public static void main( String[] args ) {
    List<InetSocketAddress> servers =
      AddrUtil.getAddresses(System.getenv("MEMCACHIER_SERVERS").replace(",", " "));
    AuthInfo authInfo =
      AuthInfo.plain(System.getenv("MEMCACHIER_USERNAME"),
                     System.getenv("MEMCACHIER_PASSWORD"));

    MemcachedClientBuilder builder = new XMemcachedClientBuilder(servers);

    // Configure SASL auth for each server
    for(InetSocketAddress server : servers) {
      builder.addAuthInfo(server, authInfo);
    }

    // Use binary protocol
    builder.setCommandFactory(new BinaryCommandFactory());
    // Connection timeout in milliseconds (default: )
    builder.setConnectTimeout(1000);
    // Reconnect to servers (default: true)
    builder.setEnableHealSession(true);
    // Delay until reconnect attempt in milliseconds (default: 2000)
    builder.setHealSessionInterval(2000);

    try {
      MemcachedClient mc = builder.build();
      try {
        mc.set("foo", 0, "bar");
        String val = mc.get("foo");
        System.out.println(val);
      } catch (TimeoutException te) {
        System.err.println("Timeout during set or get: " +
                           te.getMessage());
      } catch (InterruptedException ie) {
        System.err.println("Interrupt during set or get: " +
                           ie.getMessage());
      } catch (MemcachedException me) {
        System.err.println("Memcached error during get or set: " +
                           me.getMessage());
      }
    } catch (IOException ioe) {
      System.err.println("Couldn't create a connection to MemCachier: " +
                         ioe.getMessage());
    }
  }
}

The values for MEMCACHIER_SERVERS, MEMCACHIER_USERNAME, and MEMCACHIER_PASSWORD are listed on your cache overview page. Make sure to add them to your environment.

You may wish to look the xmemcached Wiki or JavaDocs.

SpyMemcached

We’ve built a small Java example, using SpyMemcached with Jetty: MemCachier Java Jetty sample app.

To use SpyMemcached with Maven you need to add the spymemcached library to your dependencies in your pom.xml file:

<dependency>
  <groupId>spy</groupId>
  <artifactId>spymemcached</artifactId>
  <version>2.12.3</version>
  <scope>provided</scope>
</dependency>

Once your build system is configured, you can start adding caching to your Java app:

import java.io.IOException;
import net.spy.memcached.AddrUtil;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.ConnectionFactoryBuilder;
import net.spy.memcached.auth.PlainCallbackHandler;
import net.spy.memcached.auth.AuthDescriptor;

public class Foo {
  public static void main(String[] args) {
    AuthDescriptor ad = new AuthDescriptor(
        new String[] { "PLAIN" },
        new PlainCallbackHandler(System.getenv("MEMCACHIER_USERNAME"),
                                 System.getenv("MEMCACHIER_PASSWORD")));
    try {
      MemcachedClient mc = new MemcachedClient(
          new ConnectionFactoryBuilder()
              .setProtocol(ConnectionFactoryBuilder.Protocol.BINARY)
              .setAuthDescriptor(ad).build(),
          AddrUtil.getAddresses(System.getenv("MEMCACHIER_SERVERS")));

      mc.set("foo", 0, "bar");
      System.out.println(mc.get("foo"));
    } catch (IOException ioe) {
      System.err.println("Couldn't create a connection to MemCachier: \nIOException "
              + ioe.getMessage());
    }
  }
}

The values for MEMCACHIER_SERVERS, MEMCACHIER_USERNAME, and MEMCACHIER_PASSWORD are listed on your cache overview page. Make sure to add them to your environment.

For convenience, you may want to set the above code up as a new MemCachierClient class:

package com.memcachier.examples.java;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;

import javax.security.auth.callback.CallbackHandler;

import net.spy.memcached.ConnectionFactory;
import net.spy.memcached.ConnectionFactoryBuilder;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.auth.AuthDescriptor;
import net.spy.memcached.auth.PlainCallbackHandler;

public class MemCachierClient extends MemcachedClient {

   public MemCachierClient(String username, String password, String servers) throws IOException {
       this(new SASLConnectionFactoryBuilder().build(username, password), getAddresses(servers));
   }

   public MemCachierClient(ConnectionFactory cf, List<InetSocketAddress> addrs) throws IOException {
       super(cf, addrs);
   }

   private static List<InetSocketAddress> getAddresses(String servers) {
       List<InetSocketAddress> addrList = new ArrayList<InetSocketAddress>();
       for (String server : servers.split(",")) {
           String addr = server.split(":")[0];
           int port = Integer.parseInt(server.split(":")[1]);
           addrList.add(new InetSocketAddress(addr, port));
       }
       return addrList;
   }
}

class SASLConnectionFactoryBuilder extends ConnectionFactoryBuilder {
   public ConnectionFactory build(String username, String password){
       CallbackHandler ch = new PlainCallbackHandler(username, password);
       AuthDescriptor ad = new AuthDescriptor(new String[]{"PLAIN"}, ch);
       this.setProtocol(Protocol.BINARY);
       this.setAuthDescriptor(ad);
       return this.build();
   }
}

It is possible that you will run into Java exceptions about the class loader. (See Spymemcached issue 155. The reported issue also contains a suggested work around.

You may wish to look the spymemcached JavaDocs or some more example code to help in using MemCachier effectively.