Clustering Guice Java Web Applications

Considering the origin of Guice (it’s use in Google Adwords, one of the largest apps on the Internet), it’s fair to say it should support clustering / session replication.

There’s not much in the way of documentation around that aspect of it.

As it turns out, there’s a good reason for that – clustering and session replication with Guice are mind-numbingly simple. In fact, if you’re doing session replication / fail-over, you probably already have it working.

This is because, @SessionScoped objects in Guice are stored in HttpSession, and with consistent internal keys.

That might be obvious to some people, but it wasn’t to me. I thought that Guice used… well… MAGIC or something to keep track of objects in session scope.

Actually, delving into the Guice internals, here’s the “magical” code -

  public static final Scope SESSION = new Scope() {
    public  Provider scope(Key key, final Provider creator) {
      final String name = key.toString();
      return new Provider() {
        public T get() {
          HttpSession session = GuiceFilter.getRequest().getSession();
          synchronized (session) {
            Object obj = session.getAttribute(name);
            if (NullObject.INSTANCE == obj) {
              return null;
            }
            @SuppressWarnings("unchecked")
            T t = (T) obj;
            if (t == null) {
              t = creator.get();
              session.setAttribute(name, (t != null) ? t : NullObject.INSTANCE);
            }
            return t;
          }
        }
        public String toString() {
          return String.format("%s[%s]", creator, SESSION);
        }
      };
    }

So the GuiceFilter servlet filter is actually what provides the magic for this functionality. The actual objects are stored in the HttpSession as attributes.

So in order to support session replication you just need to make sure that your session scoped objects are Serializable, and everything is good. Normal HttpSession replication across your cluster will mean everything works as expected.

Of course, what if you have non-serializable dependencies?

Well they can be @Inject’ed into a static member variable to get around that, though I’d suggest a better solution would be to refactor the code such that the data (Serializable) component is kept in session scope, but the functional (non-serializable) part is split out into a @Singleton service class.

Related posts:

  1. Guice / Java IoC best practices – using annotations for configuration
  2. 5 Minute Guide to Clustering – Java Web Apps in Tomcat
  3. The 5 Minute Guice Primer
  4. AOP, Annotation-based caching solution for Guice projects…
  5. Adding a Dynamic Watermark to an Image – Java Web Application

This entry was posted in Java, Software Engineering and tagged cluster, guice, Java, tips. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>