Monthly Archives: February 2011

Mise en Place

Mise en place is a culinary term referring to getting everything ready to cook before you start cooking. If you are going to barbecue, you make sure you have all the fuel you need (charcoal and wood chips), all the tools you need (tongs, thermometer, brushes, knives, gloves) and all the ingredients you need (the meat, seasonings, mop sauces, butters in bowls). The point of all this is that when you actually fire up the grill and get started, you want to concentrate on the task at hand, not running around trying to find your extra charcoal or looking for the pepper.

So what does this have to do with programming? It’s the way I think about all of the tools that you want to have to do your job. You have source control, IDE, automated tests and a CI server that runs those tests every time you check something in. Those are some of the tools, but it goes further.

Say you are building some web services. You need to write integration tests to test those services. If you have a maven build that loads some test data and starts up an application server, then you just need to write the tests (using something handy like HtmlUnit) and you’re good to go. If you don’t, then you probably wind up inserting some test data manually and just testing it with curl or something. That’s a lot of work. It’s enough work that you certainly aren’t going to regression test. Even worse, it may be enough work that you don’t even do it the first time and just throw it over the wall to the QA department.

It is not a perfect analogy. The mise en place is set up to get you through a recipe, but then everything is either consumed or put back away. When you’re done coding, though, everything is still there. Nothing is consumed per se. So, for example, if you go through a lot of effort to set up your integration testing automation, you don’t need to do it again the next time. I think of this as every time I finish a coding task, I’m also setting the table for the next coding task. If I have to spend some extra effort for something that wasn’t there (e.g. automated tests) I make sure to spend that effort in a way that it will serve as the mise en place for next task. If, during the next task, I find that I my automated testing executing scheme came up short, I enhance it so that it has a better chance of being sufficient for the next task. Eventually, you wind up with an environment where you can really spend almost all of your time concentrating on the task at hand and very little time distracted by having to “put everything in place”.

Advertisements

Share my pain!

Here’s a painful puzzle I ran into using Jersey 1.4 with Spring.

I have two kinds of entities in my system. (Well, more than that, but for this example, we’ll just look at two.) First is RoleImpl:

@Entity(name = "Role")
@Table(name = "Role")
@XmlRootElement(name = "role")
@XmlType(name = "role")
public class RoleImpl implements HasLongId, HasName, HasZone, Role {
...
}

Second is PartyEntity:

@Entity(name = "Party")
@XmlType(name = "party")
@XmlRootElement(name = "party")
public abstract class PartyEntity implements Party {
...
}

I have a resource for each and a @GET method that returns a List<RoleImpl> and a List<PartyEntity> respectively. When they produce JSON, the parties are rendered as an array like this:
[{"id":45,"name":"","firstName":"","lastName":""},{"id":48,"name":"Winston Abbott","firstName":"Winston","lastName":"Abbott"}]

This is the “correct” behavior as far as I’m concerned. However, the roles are rendered as an object with an array in the “role” field like this:
{"role":[{"id":"1","name":"superuser","permissions":"*"},{"id":"2","name":"admin","permissions":["*:*:ownZone"]}]}

After much fiddling around, I found the solution. See if you can tell me the functional difference between these two classes:

package com.factorlab.ws.security;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBException;

import com.factorlab.security.RoleImpl;
import com.factorlab.security.UserEntity;
import com.factorlab.ws.AbstractJAXBContextResolver;

public class SecurityJAXBContextResolver extends AbstractJAXBContextResolver {

	public SecurityJAXBContextResolver() throws JAXBException {
		super();
	}

	@Override
	protected Set<Class> getTypes() {
		Set<Class> classSet = new HashSet<Class>();
		classSet.add(UserEntity.class);
		classSet.add(RoleImpl.class);
		return classSet;
	}

}

and

package com.factorlab.ws.security;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBException;

import com.factorlab.security.PartyEntity;
import com.factorlab.security.PersonEntity;
import com.factorlab.ws.AbstractJAXBContextResolver;

@Provider
public class SecurityJAXBContextResolver extends AbstractJAXBContextResolver {

	public SecurityJAXBContextResolver() throws JAXBException {
		super();
	}

	@Override
	protected Set<Class> getTypes() {
		Set<Class> classSet = new HashSet<Class>();
		classSet.add(PartyEntity.class);
		classSet.add(PersonEntity.class);
		return classSet;
	}

}

The answer came to me after variously staring at the code and stepping through a bunch of Jersey code in my debugger for only about 5 hours. Of course, the actual solution, once known, was trivial to implement (and I do mean trivial).

Mouse over me for the answer

Now the question is: Why did it even work as well as it did. I leave that as an exercise for the reader (because I don’t have an answer). I’d love to hear theories in the comments.

How’s that Post-A-Week Thing Workin’ Out For Ya?

Well, we are in week 7 of the post-a-week challenge and so far I’ve posted 4 times (including this one). So, so far, not so good. Super jammed up at work, so I have lots of ideas for interesting (or at least difficult) problems I’ve solved, but no time to write them down. There will be one tomorrow, I promise. And hopefully some more makeup posts till I’m caught up to an average of a post per week, if not a post every single week.