Unit Tests with Guice and Warp Persist

Note: this post is cross-posted on Cubeia.com.

Yesterday I needed to do some unit testing for a project using Guice and Warp Persist. And one thing that seems to be lacking, or wasn’t to be found be me yesterday, is the kind of unit testing you can do with Spring, where each method is wrapped by a transaction which is rolled back when the method ends.

To simplify, it enables you to do this:

@Test
public void createUser() {
    User u = userService.createUserWithId(1);
}

@Test
public void createUserWithSameId() {
    User u = userService.createUserWithId(1);
}

If you assume the “userService” is transactional, we’re on a database that spans multiple methods, and that the user ID must be unique, the above pseudo-code should fail as we’re trying to create two users with the same ID. If, however, there was a transaction wrapping both methods, and that transaction was rolled back, we’d be fine.

So, can you do it with Guice and Warp Persist? Sure you can!

(I’m using TestNG and JPA by the way, but you’ll get the point).

We’ll create a base class that sets up the Guice context as well as handles the transactions for us. Let’s start with creating the methods we need:

public abstract class JpaTestBase {

    @BeforeClass
    public void setUpJpa() throws Exception {
        // setup guice + jpa here here
    }

    @AfterClass
    public void tearDownJpa() throws Exception {
        // stop jpa here
    }

    /*
     * Return the module needed for the test.
     */
    protected abstract List<? extends Module> testModules();

    @BeforeMethod
    public void setupTransaction() throws Exception {
        // create "session in view"
    }

    @AfterMethod
    public void cleanTransaction() throws Exception {
        // rollback transaction and close session
    }
}

We’re using the TestNG “before” and “after” class to setup and tear down JPA. If the test was in a bigger suite you could probably do it around all test classes, but this will do for now. I’m also including a “testModules” method that subclasses should use to make sure their own test classes are setup correctly.

Before we go on, I’ll add some dependencies which will be explained later:

@Inject
protected PersistenceService service;

@Inject
protected WorkManager workManager;

@Inject
protected Provider<EntityManagerFactory> emfProvider;

We’ll setup the Guice context and the JPA persistence service in the “setUpJpa” method:

@BeforeClass
public void setUpJpa() throws Exception {
    // create list with subclass modules
    List<Module> list = new LinkedList<Module>(testModules());
    // add persistence module
    list.add(PersistenceService.usingJpa()
        .across(UnitOfWork.REQUEST)
        .forAll(Matchers.annotatedWith(Transactional.class), Matchers.any())
        .buildModule());
    // modules to array and create 
    GuiceModule[] arr = list.toArray(new Module[list.size()]);
    injector = Guice.createInjector(arr);
    // make sure we get our dependencies
    injector.injectMembers(this);
    // NB: we need to start the service (injected)
    service.start();
}

The persistence service will work across UnitOfWork.REQUEST as that’s what we’re emulating here. I’m also matching the transaction for any classes, this enables me to mark an entire class as transactional, as opposed to single methods, which I find handy.

All we need to do to shut down is to close the service, like so:

@AfterClass
public void tearDownJpa() throws Exception {
    service.shutdown();
}

Now, let’s wrap the methods. Remember our dependency injections earlier? Well, here’s where they come in handy. The WorkManager is used by Warp Persist to manage a session, we can tell it to start and end “work” and this will correspond to an EntityManager bound to the current thread. Let’s start with that:

@BeforeMethod
public void setupTransaction() throws Exception {
    workManager.beginWork();
}

@AfterMethod
public void cleanTransaction() throws Exception {
    workManager.endWork();
}

So before each method we’ll open a new EntityManager which will be closed when the method ends. So far so good. Now, in order to enable a rollback when the method ends we first need to wrap the entire execution in a transaction, which means we need to get hold of the EntityManager. Luckily, Warp Persist has a class called ManagedContext which holds currently bound objects (a bit like a custom scope), in which we’ll find our EntityManager keyed to it’s persistence context, ie. the EntityManagerFactory that created it. Take a look again at the injected dependencies we injected above: As the test only handles one persistence context we can safely let Guice inject a Provider for an EntityManagerFactory for us and assume it is going to be the right one.

Still with me? OK, let’s do it then:

@BeforeMethod
public void setupTransaction() throws Exception {
    // begin work
    workManager.beginWork();
    // get the entity manager, using it's factory
    EntityManagerFactory emf = emfProvider.get();
    EntityManager man = ManagedContext.getBind(EntityManager.class, emf);
    // begin transactionman.getTransaction().begin();
}

@AfterMethod
public void cleanTransaction() throws Exception {
    // get the entity manager, using its factory
    EntityManagerFactory emf = emfProvider.get();
    EntityManager man = ManagedContext.getBind(EntityManager.class, emf);
    // rollback transaction
    man.getTransaction().rollback();
    // end work
    workManager.endWork();
}

And that’s it! Each test method is now within a transaction that will be rolled back when the method ends. Now all you need to do is to write the actual tests…

A Google Analytics Plugin for Nexus

Note: this post is cross-posted on Cubeia.com.

Since Firebase Community Edition uses Maven heavily, I realized I’d like to track our Nexus repository in Google Analytics. The Nexus Book says that there exists such a plugin already, but apparently now one knows where it is. So here’s my attempt to write a simple one.

If you’re an impatient kind, here’s the source code.

I created the project  in Eclipse, instructions here.

Now, let’s start off with a “repository customizer” which is Nexus extension point we’ll use to insert a custom request processor into every repository…

public class GaTrackerRepositoryCustomizer implements RepositoryCustomizer {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Inject
    @Named("gaTracker")
    private RequestProcessor gaTracker;    

    @Override
    public void configureRepository(Repository rep) throws ConfigurationException {
        log.debug("Attaching tracker to: " + rep.getName());
        rep.getRequestProcessors().put("gaTracker", gaTracker);
    }

    @Override
    public boolean isHandledRepository(Repository rep) {
        boolean b = true;
        log.info("Handles repository '" + rep.getName() + "': " + b);
        return b;    
    }
}

Not too complicated. We’re using injection to get hold of the actual tracker components and we’re inserting it into all repostories.

Wait, all repositories? Yes, and it’s problem I haven’t really figured out yet. Ideally I’d like to track “hosted” repositories only. However, we’ve configured all our builds to use a few common development “groups” for convenience. However, Nexus seems to treat groups as first class members, so even though an artifact may be deployed in a hosted repository while accessed through a group, the request processor will not get notified for the hosted repository, only the group. I tend to see “groups” as equivalent to “views” in which case I’d expect the hosted repository to be called as well, but, no…

Now, let’s create a request processor which will react when someone “reads” a path in a repository.  We’ll take it in pieces…

@Named("gaTracker")
public class GaTrackerRequestProcessor implements RequestProcessor {

    public static final String GA_TRACKER_ID = System.getProperty("cubeia.nexus.gaTrackerId");
    public static final String GA_REFERER_URL =System.getProperty("cubeia.nexus.gaRefererUrl");

    private final Logger log = LoggerFactory.getLogger(getClass());

    private final JGoogleAnalyticsTracker tracker;    

    public GaTrackerRequestProcessor() {
        if(GA_TRACKER_ID == null) {
            String msg = "Missing system property 'cubeia.nexus.gaTrackerId'";
            throw new IllegalStateException(msg);
        }
        log.info("Creating new tracker, with id: " + GA_TRACKER_ID);
        tracker = new JGoogleAnalyticsTracker("nexus", "read", GA_TRACKER_ID);
        checkRefererUrl();
        adaptLogging();
    }

[...]

We configure the plugin via system properties (not too beautiful, I know), the “tracker id” is the google tracking code id and is mandatory, and the “refer url” will be set on the call to GA if available.  We’re using the JGoogleAnalytics library to call GA for us. Also, I’m being naughty and throwing an illegal state exception if the tracker id is missing, since GA updates every 24 hours we’d like to be notified on errors early.

There’s  two methods above, one sets the logging in the tracker code to use to slf4j logger instead and the other checks for and sets the referer URL:

private void adaptLogging() {
    /*
     * Adapt the logging to use slf4j instead.
     */
    tracker.setLoggingAdapter(new LoggingAdapter() {

        public void logMessage(String msg) {
            log.debug(msg);
        }

        public void logError(String msg) {
            log.error(msg);
        }
    });
}

private void checkRefererUrl() {
    if(GA_REFERER_URL != null) {
        /*
         * If we have a referer URL we need to set this. However, the
         * tracker does not have a getter for the URL binding strategy, so
         * we'll simply create a new one, ugly, but works.
         */
        log.info("Modifying GA tracking to use referer URL: " + GA_REFERER_URL);
        GoogleAnalytics_v1_URLBuildingStrategy urlb;
        urlb = new GoogleAnalytics_v1_URLBuildingStrategy("nexus", "read", GA_TRACKER_ID);
        urlb.setRefererURL("http://m2.cubeia.com");
        // set new referer
        tracker.setUrlBuildingStrategy(urlb);
    }
}

Not too complicated eh? The only thing to note is that the only way to set the refer URL is by creating a new URL building strategy. Well, I can live with that.

Before we go on we’ll create a small subclass on FocusPoint which we’ll use for tracking. Since JGoogleAnalitycs is made primarily for applications the focus point will URL encode itself, however, that won’t work for us, so we need to override it’s getContentURI method:

/** 
 * Simple inner class that adapts the content URI to
 * not be URL-escaped.
 */
private static class Point extends FocusPoint {

    public Point(String name) {
        super(name);
    } 

    @Override
    public String getContentURI() {
        return getName();
    }
}

And finally we’ll tie it all toghether. We’ll react on “read” actions, create a URI (of form ‘//path’) and track asynchronously (which will spawn a new thread for calling GA:

public boolean process(Repository rep, ResourceStoreRequest req, Action action) {
    if(action == Action.read) {
        /*
         * 1) create path by appending repo path to repo id
         * 2) create a subclass of focus point that handles proper URI's
         * 3) track asynchronously, this will perform the tracking on a new thread
         */
        String path = rep.getId() + req.getRequestPath();
        log.debug("Tracking path: " + path);
        FocusPoint p = new Point(path);
        tracker.trackAsynchronously(p);
    } else {
        log.debug("Ingoring action '" + action + "' for: " + req.getRequestPath());
    }    
    return true;
}

And that’s it. It’s not perfect: though ideally I’d like to track hosted repositories only, I’d like to avoid tracking crawlers and I would prefer not to configure via system properties (hint for you Nexus bundle users out there, you can set system properties in the “conf/wrapper.conf” files), but I’ll leave those for a rainy day.

Here’s the source code as a Maven project.Enjoy!

Update: If you download and try to compile, you will probably be missing the JGoogleAnalytics lib. You’re welcome to use our, GA-tracked, repository if you like :-)

<repository>
  <id>cubeia-nexus</id>
  <url>http://m2.cubeia.com/nexus/content/groups/public/</url>
  <releases><enabled>true</enabled></releases>
  <snapshots><enabled>true</enabled></snapshots>
</repository>

A Java Concurrency Bug, and How We Solved It

Note: this post is cross-posted on Cubeia.com.

Everyone agrees that good debugging is critical. But it is not entirely trivial when it comes to multi-threaded applications. So here’s the story how I tracked down a nasty bug in the Java5 ReentrantReadWriteLock.

Update 15/4: To be a bit clearer, the Java bug in question is on 1) Java 5; and 2) only when using fair locks, non fairness seems to work, however, that was never an option for us, if nothing else due to this other Java bug… Thanks to Artur Biesiadowski for the heads up.

Our product Firebase is designed to offload threading issues and scalability from game developers to a generic platform. However, one of our customers experienced mysterious “freezes” when running a fairly small system load in their staging environment.

First step on the way: getting stack dumps when the system is frozen. In other words, request that the client do a “kill -3” on the server process when it’s hanged, as this dumps all threads and their current stack traces to the standard output. This we did, but only got confused by it, all threads seemed dormant and there was no visible dead-lock in the stack traces.

However, several threads were all mysteriously waiting on a read lock deep down in the server, and seemingly not getting any further, despite that fact that no-one was holding the write lock. This wasn’t conclusive though as there was one thread waiting to take the write lock and this would block the readers. But given that the server was actually frozen it looked suspicious. So my first analysis concluded:

As far as I can see, the only abnormal thing that could have caused this stack is if a thread have taken the lock (read or write) and then crashed without releasing it, however there doesn’t seem to be any place in the code not safeguarded by try/finally (where the lock is released in the finally clause).

Implied in that conclusion is of course that this might either be a normal behavior and we’re looking in the wrong direction, or that we have a more serious Java error on our hands.

There’s a lot of information to be had from a ReentrantReadWriteLock, including the threads waiting for either read or write privileges, and the thread holding a write lock (if any), but not (strangely enough) the threads actually holding a read lock. And as a reader thread can effectively block the entire lock by not unlocking while a writer is waiting, this is information you really need to know.

So the next step was to get hold of the reader threads. I did this by sub-classing the ReentrantReadWriteLock to return my own version of the read lock, which, simplified, did this:

Set readers = Collections.synchronizedSet(new HashSet());

public Set getReaders() {
    return readers;
}

public void lock() {
    super.lock();
    readers.add(Thread.currentThread());
}

public void unlock() {
    super.unlock();
    readers.remove(Thread.currentThread());
}

Given this code, we now have a set containing a snapshot of the threads holding the read lock. I then added a JMX command for printing the following information to standard out for the given read/write lock:

  1. The threads waiting for a read lock, including their stack traces.

  2. The threads waiting for the write lock, including their stack traces.

  3. Any threads holding a read lock, including their stack traces.

  4. The thread holding the write lock, including its stack trace, if any.

I shipped this patched code to the client and asked them to freeze the server with the patch, print the new debug information, and then send me the output. Which they did, and the relevant output looked like this (very much shortened):

Holding reader:
Thread[DQueue Handoff Executor Pool Thread { GAME }-1,5,main]
    sun.misc.Unsafe.park(Native Method)
    java.util.concurrent.locks.LockSupport.park(LockSupport.java:118)
    […]

Waiting writer:
Thread[Incoming,dqueue,127.0.0.1:7801,5,Thread Pools]
    sun.misc.Unsafe.park(Native Method)
    […]

Waiting reader:
Thread[DQueue Handoff Executor Pool Thread { GAME }-1,5,main]
    sun.misc.Unsafe.park(Native Method)
    […]

See anything strange here? It appears that the same thread is both holding and waiting for a read lock at the same time. But this is supposed to be a reentrant lock. In which case…

So, the freeze was caused by this: There’s a bug in Java5 (but not in Java6) where a fair ReentrantReadWriteLock stops a reader from re-entering the lock if there’s a writer waiting. It is of course easy to write a test case for, which you can find here.

This is now submitted as a bug to Sun, but I have yet to get a confirmation and bug number.

As for Firebase, it is now patched and released to use manually tracked re-entrance for read/write locks through the entire server when running under Java5, looking, again very much simplified, like this:

private ThreadLocal count = new ThreadLocal();

public void lock() {
    if (get() == 0) {
        // don't lock if we alread have a count, in other words, only
        // really lock the first time we enter the lock
        super.lock();
    }
    // increment counter
    increment();
}

public void unlock() {
    if (get() == 0) {
        // we don't have the lock, this is an illegal state
        throw new IllegalMonitorStateException();
    } else if (get() == 1) {
        // we have the lock, and this is the “first” one, so unlock
        super.unlock();
        remove();
    } else {
        // this is not the “first” lock, so just count down
        decrement();
    }
}

// --- HELPER METHODS --- //

private void remove() {
    count.remove();
}

private int get() {
    AtomicInteger i = count.get();
    if (i == null) return 0;
    else {
         return i.intValue();
    }
}

private void increment() {
    AtomicInteger i = count.get();
    if (i == null) {
        i = new AtomicInteger(0);
        count.set(i);
    }
    i.incrementAndGet();
}

private void decrement() {
    AtomicInteger i = count.get();
    if (i == null) {
        // we should never get here...
        throw new IllegalStateException();
    }
    i.decrementAndGet();
}

The above code isn’t trivial, but shouldn’t be too hard to decode: We’re simple managing a “count” each time a thread takes the read lock, but we’re only actually locking the first time, the other times we simply increment the counter. On unlock, we decrement the counter, and if it is the “last” lock, if the counter equals 1, we do the real unlock and remove the counter.

There are two things to learn, 1) in any sufficiently complex server, the above debug information is nice to have from the start on any important lock; and 2) it really is time to migrate to Java6.

New Article: Real Time BI

Note: this post is cross-posted on Cubeia.com.

Since I’ve spent some time discussing complex event processing in various contexts the last weeks, I thought I’d write up a small article about it. And lo, here it is.I do point out in the beginning that the article is primarily targeted towards gambling networks, however it can be applied to other domains as well. Financial fraud management? Sure. Industry process supervision? No problems. And so on…

Class Loading and AOP

Note: this post is cross-posted on Cubeia.com.

I have a new article up, Debugging Class Loading with AOP, in which I briefly discuss how Aspect Oriented Programming (AOP) using AspectJ can be used to debug class loading, in particular in instances where a system have multiple class loaders.It does not cover how to use the load time weaver that comes with AspectJ. For you reference, this is roughly how to use it (for Java 5 or higher):

  1. Download AspectJ from the Eclipse site.
  2. Create a configuration file called “aop.xml” in a META-INF folder on the class path. For an example file, see below.
  3. Start your VM with: -javaagent:pathto/aspectjweaver.jar

Which is about it, the “aop.xml” file may look something like this for running the code in the article in a Tomcat 6 installation:

<code lost in blog system move>

Notice above that we include the base package of your application for weaving and the Catalina class loader packages. We’re doing this to limit the scope of the weaver, otherwise your debugging may take a bit too much time and resources.

Singletons… Again!

Perhaps I’m being a bit grumpy today, but this article rubs me the wrong way. It describes the Singleton pattern in Java but contains some problems. And one of the is a pet peeve of mine. The article claims:

  • There can only be one singleton instance per JVM == Plain wrong in every respect.
  • Singletons are good for object pooling (such as connection pooling) == Dangerous.
  • You can get away with synchronization problems with a nested inner class == Naive.

The singleton pattern does not guarantee anything regards to the number of instances of an object, and certainly not per JVM. You see, even if we disregard cloning, serialization, reflection or thread safety the following is still true: A class instance of an object is guaranteed to be unique per class loader, not JVM. In other words, if you have multiple class loaders (as do almost all application servers) you can have multiple instances of a singleton per JVM; one for each class loader.

Singletons can help guard limited resources such as object pooling. That is correct, but the implication that it is good design to use it to do so is wrong. Statically held object pools in larger and long running applications and servers are not a good idea as their lifetime cannot be directly controlled by the code. Also, if there are multiple class loaders… See the paragraph above.

And the synchronization discussion is naive as one of the comments suggests. See this, this, this or google it yourself.

So, yes, the Singleton pattern is useful, but not as massively so as many articles and tutorials suggests. In a world of serialization and class loader hierarchies it can be a real pain in the ass as well. Use with care.

Re: The Open Source Frameworks I Use

The Codist asks what open source frameworks we use. Now, he says frameworks, but it looks more like libraries and utilities. Which is fine by me as I generally tend to avoid the larger frameworks, and just as The Codist himself wrote my own web framework for my regular site.

So, without further ado, here’s some regulars:

  • Jetty – good stuff
  • c3p0 – JDBC pooling
  • log4j – logging, I don’t really like it, but…
  • jgroups – data distribution/messaging
  • JBoss Serialization – for high throughput servers
  • JBoss Cache – data replication
  • Mina – network IO framework
  • XFire – for all your SOAP needs
  • HSQLDB – just works, but I’ll probably check out H2 soon
  • Jaxen – very good xpath engine
  • Hibernate – ORM, because it is more or less standard
  • GNU Trove – primitive fast collections
  • Wicket – if I really must code an web UI

But I must admit, for my home coding I use a lot of my private libraires, I’ve got my own XML API and XPath engine. My own commons collection, UUID API, simple object -> XML lib, logging, email API, etc.

Updated book library: Design and fantasy

My book library have been updated. First, the latest installment of Steven Erikson’s epic fantasy series, The Bonehunters. I am, as I suspect many others, slightly in awe of Erikson. Extremely complex. Extremely well written. Extremely good stuff.

The second update is the classic The Design of Everyday Things, by Donald A. Norman. This is really good stuff, and anyone aspiring to design software, be it GUI or API’s, really, really should read it. I picked it up after reading an interview with Ken Arnold over at Artima.com:

Taste is a very personal thing. There is no textbook. When people ask me about books on object design, the books I hand them have nothing to do with object design per se. I commonly recommend The Design of Everyday Things, by Donald Norman. This book promotes focusing on usability in the design of doors, teapots, and faucets – everyday things. If you do that for objects, you’ll have the idea. 

Oh yes, Ken Arnold as in:

State is hell. 

Or:

Every program has at least one bug and can be shortened by at least one instruction — from which, by induction, it is evident that every program can be reduced to one instruction that does not work. 

MLP VII: Consumer JRE!

This years JavaOne announced several important Java technologies. The one that got most initial attention was of course JavaFX. Well, exciting as this may sound I wasn’t alone in wondering how on earth Sun could hope to launch such a technology on their existing platform. Take these bullet points:

  • Huge download (JRE)
  • Slow startup (no pre-loading here, no)
  • Crappy browser integration (seen any applets lately?)
  • Bad JRE detection (part of the above problem)
  • Somewhat slow graphics performance
  • Sub-standard installer

As a profoundly specialized server developer (I still have nightmares about the one time I had to dive deep into the source of JTable and JTree, the horror! the horror!) I’ve never been very concerned personally. It has annoyed me on an academic level, as I’ve never understood why Sun just didn’t smarten up and fix it.

So why launch JavaFX now? Well, it turns out someone was a bit smarter than I first thought. You see, there was an announcement made on JavaOne which got drowned out a bit, the Consumer JRE. It would appear Sun has finally granted all our wet dreams. Here. And here.

Wheee! Damn good stuff!