Tag Archives: Java

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.