How do I correctly reuse Jackson ObjectMapper?

JavaJackson

Java Problem Overview


I am happy with how the ObjectMapper works and general use within my application. What I would like to understand is the best way to implement the ObjectMapper to ensure it is re-used and I'm not creating unnecessary instances within my application?

My thoughts are that I can declare the ObjectMapper in a Utils class as follows:

public class Utils {

    public final static ObjectMapper mapper = new ObjectMapper();

}

I could then reference this from the various places I need to using code such as:

JsonSimple jsonSimple = Utils.mapper.readValue(jsonString, JsonSimple.class);

I came across this other question (https://stackoverflow.com/questions/3907929/should-i-make-jacksons-objectmapper-as-static-final) that prompted my approach. I think maybe the key difference is that I want to share my ObjectMapper instance across many different classes, not just within a single class.

Does this approach sound appropriate or am I missing something?

Thanks

Java Solutions


Solution 1 - Java

It's fine to use a single instance per application provided you don't call any configuration methods after it's been made visible i.e. you should do all your initialization inside a static block.

Solution 2 - Java

As posted in other answers, the ObjectMapper is indeed Thread safe. But reusing the same object can decrease the performance of your application, since all - 1 threads can be locked at a given time waiting for the owner of the lock to complete the serialization/deserialization of JSON.

This is especially critical on web servers such as Jetty or Tomcat: the overall performance of the entire server can be compromised, for instance, if you use the singleton ObjectMapper as entry/exit point of REST services - depending, of course, on your access load.

So, my suggestion is to use a pool of ObjectMappers, to allow multiple Threads to use it, and in a way you don't have to recreate the mappers every time you need them. The number to ObjectMappers in the pool should be the same number of worker Threads of your application.

More about: http://jackson-users.ning.com/forum/topics/pooling-objectmapper-for-performance

-- EDIT --

Ok, some users are really passionate about the Jackson lib to the point that they downvote this answer without even looking at the linked website. Anyway, this answer is based on my experience with the lib without any modifications (just using ObjectMapper, no extra classes, no custom serializer, no custom JSONFactory, nothing) at the time of the answer (2013). I don't use it anymore on my projects so I don't know about newer versions - but I guess it should be solved by now.

As developer, if you're going to use Jackson or any other JSON reader/writer on your project, directly or indirectly, consider running a profiling tool on your server to see how the threads behave on high load. It's a simple step that doesn't harm.

Solution 3 - Java

Use the latest version of Jackson and use ObjectReader and ObjectWriter instead of ObjectMapper

Solution 4 - Java

The plain static singleton you proposed in your question is correct. An alternative approach would be to use the singleton pattern (the use of singleton pattern been discussed at length in answer comments to a similar question). Here's a simple example:

public enum Mapper {
  INSTANCE;
  private final ObjectMapper mapper = new ObjectMapper();

  private Mapper(){
    // Perform any configuration on the ObjectMapper here.
  }

  public ObjectMapper getObjectMapper() {
    return mapper;
  }
}

Then you can use (and reuse) the ObjectMapper singleton as follows:

ObjectMapper mapper = Mapper.INSTANCE.getObjectMapper();
JsonSimple jsonSimple = mapper.readValue(jsonString, JsonSimple.class);

This is safe as ObjectMapper is thread-safe after configuration.

Caveat: As @StaxMan points out in the answer comments, this does NOT guarantee against further (re)configuration on the returned singleton.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnickebbittView Question on Stackoverflow
Solution 1 - JavaRokLView Answer on Stackoverflow
Solution 2 - JavaGilberto TorrezanView Answer on Stackoverflow
Solution 3 - JavatalebisiaView Answer on Stackoverflow
Solution 4 - JavalorcanView Answer on Stackoverflow