Tim Spurling

using jackson 2 with jersey

As a former Spring user, switching to JAX-RS in the form of Jersey and its more JavaEE-native (i.e. “Guicey“) dependency injection has caused me some confusion.

More specifically, at one point I was trying to accomplish the apparently simple goal of using (and manually configuring) Jackson (version 2) for my API’s serialization. This turned into a massive waste of time thanks to some silly misunderstandings, so I thought I’d explain the solution in the hope that it might help someone else avoid that pain (or perhaps I might be told I’m doing it wrong).

dependencies

Extreme fun with Maven, as always!

The jackson-jaxrs-json-provider is enough. Do not be fooled into trying to use jersey-media-json-jackson; currently that means Jackson version 1, and it’s not necessary, or necessarily the easiest way, even if that’s what you want.

i hate auto-configuration

One thing that’s “really great” is when something is auto-configuring. This is because if your serialization is wrong, you have absolutely no idea why.

“Am I configuring it wrong?”, you askā€¦ then “is it even listening to me at all??!”

Combined with a hint of Thursday rage, it’s enough to make the whole process feel like a battle to preserve the moral value of logic, against a computer that basically just hates you.

The solution is to just turn the whole damned auto-confusion system off. This is easily accomplished by setting a single initialization parameter in the code that starts your Servlet.

org.glassfish.jersey.CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE = "jersey.config.disableMetainfServicesLookup"

That‘s the constant Jersey gives you for the key. Map that to "true" and now, if your manual configuration isn’t working, you get no serialization, rather than the (incorrect) default configuration.

What this is actually doing is globally disabling Jersey’s “services lookup“, a classic Enterprisey hack which looks through all your included libraries for META-INF/services folders that declare implementations of standard services, and automatically uses them. So, disabling it will mean that everything must be manually declared on startup.

Never mind! I actually think that’s much better, because at least then it’s obvious what’s going on.

specificity

It turns out that the manual alternative is not even that bad. If you’re using the normal configuration method of specifying a ResourceConfig class (just a Jersey-specific JAX-RS Application) which includes all your Resources and Features, you can just make a JacksonFeature which registers your customized JacksonJaxbJsonProvider instance, and then register that in the ResourceConfig.

Too much? Here’s the Gist:

So I hope that’s vaguely helpful, and please comment if I am indeed doing it wrong, or if you’ve got any other tips. Cheers!

blog comments powered by Disqus