The Jackson library's ObjectMapper class seems to be thread safe.
Does this mean that I should declare my ObjectMapper as a static field like this
class Me {
private static final ObjectMapper mapper = new ObjectMapper();
}
instead of as an instance-level field like this?
class Me {
private final ObjectMapper mapper = new ObjectMapper();
}
Yes, that is safe and recommended.
The only caveat from the page you referred is that you can't be modifying configuration of the mapper once it is shared; but you are not changing configuration so that is fine. If you did need to change configuration, you would do that from the static block and it would be fine as well.
EDIT: (2013/10)
With 2.0 and above, above can be augmented by noting that there is an even better way: use ObjectWriter and ObjectReader objects, which can be constructed by ObjectMapper.
They are fully immutable, thread-safe, meaning that it is not even theoretically possible to cause thread-safety issues (which can occur with ObjectMapper if code tries to re-configure instance).
Although ObjectMapper is thread safe, I would strongly discourage from declaring it as a static variable, especially in multithreaded application.
Not even because it is a bad practice, but because you are running a heavy risk of deadlocking. I am telling it from my own experience. I created an application with 4 identical threads that were getting and processing JSON data from web services.
My application was frequently stalling on the following command, according to the thread dump:
Map aPage = mapper.readValue(reader, Map.class);
Beside that, performance was not good.
When I replaced static variable with the instance based variable, stalling disappeared and performance quadrupled. I.e. 2.4 millions JSON documents were processed in 40min.56sec., instead of 2.5 hours previously.
A trick I learned from this PR if you don't want to define it as a static final variable but want to save a bit of overhead and guarantee thread safe.
private static final ThreadLocal<ObjectMapper> om = new ThreadLocal<ObjectMapper>() {
#Override
protected ObjectMapper initialValue() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return objectMapper;
}
};
public static ObjectMapper getObjectMapper() {
return om.get();
}
credit to the author.
Although it is safe to declare a static ObjectMapper in terms of thread safety, you should be aware that constructing static Object variables in Java is considered bad practice. For more details, see Why are static variables considered evil? (and if you'd like, my answer)
In short, statics should be avoided because the make it difficult to write concise unit tests. For example, with a static final ObjectMapper, you can't swap out the JSON serialization for dummy code or a no-op.
In addition, a static final prevents you from ever reconfiguring ObjectMapper at runtime. You might not envision a reason for that now, but if you lock yourself into a static final pattern, nothing short of tearing down the classloader will let you re-initialize it.
In the case of ObjectMapper its fine, but in general it is bad practice and there is no advantage over using a singleton pattern or inversion-of-control to manage your long-lived objects.
com.fasterxml.jackson.databind.type.TypeFactory._hashMapSuperInterfaceChain(HierarchicType)
com.fasterxml.jackson.databind.type.TypeFactory._findSuperInterfaceChain(Type, Class)
com.fasterxml.jackson.databind.type.TypeFactory._findSuperTypeChain(Class, Class)
com.fasterxml.jackson.databind.type.TypeFactory.findTypeParameters(Class, Class, TypeBindings)
com.fasterxml.jackson.databind.type.TypeFactory.findTypeParameters(JavaType, Class)
com.fasterxml.jackson.databind.type.TypeFactory._fromParamType(ParameterizedType, TypeBindings)
com.fasterxml.jackson.databind.type.TypeFactory._constructType(Type, TypeBindings)
com.fasterxml.jackson.databind.type.TypeFactory.constructType(TypeReference)
com.fasterxml.jackson.databind.ObjectMapper.convertValue(Object, TypeReference)
The method _hashMapSuperInterfaceChain in class com.fasterxml.jackson.databind.type.TypeFactory is synchronized.
Am seeing contention on the same at high loads.
May be another reason to avoid a static ObjectMapper
This question may be old, but here's what I do.
Hold the ObjectMapper instance in a thread-safe singleton:
public final class JacksonObjectMapperHolder {
private static volatile JacksonObjectMapperHolder INSTANCE;
private static final Object MUTEX = new Object();
public static JacksonObjectMapperHolder getInstance() {
JacksonObjectMapperHolder instance = INSTANCE;
if(instance == null) {
synchronized(MUTEX) {
instance = INSTANCE;
if(instance == null) {
INSTANCE = instance = new JacksonObjectMapperHolder();
}
}
}
return instance;
}
private final ObjectMapper objectMapper = new ObjectMapper();
private JacksonObjectMapperHolder() {
super();
}
public final ObjectMapper getObjectMapper() {
return objectMapper;
}
}
Related
The Jackson library's ObjectMapper class seems to be thread safe.
Does this mean that I should declare my ObjectMapper as a static field like this
class Me {
private static final ObjectMapper mapper = new ObjectMapper();
}
instead of as an instance-level field like this?
class Me {
private final ObjectMapper mapper = new ObjectMapper();
}
Yes, that is safe and recommended.
The only caveat from the page you referred is that you can't be modifying configuration of the mapper once it is shared; but you are not changing configuration so that is fine. If you did need to change configuration, you would do that from the static block and it would be fine as well.
EDIT: (2013/10)
With 2.0 and above, above can be augmented by noting that there is an even better way: use ObjectWriter and ObjectReader objects, which can be constructed by ObjectMapper.
They are fully immutable, thread-safe, meaning that it is not even theoretically possible to cause thread-safety issues (which can occur with ObjectMapper if code tries to re-configure instance).
Although ObjectMapper is thread safe, I would strongly discourage from declaring it as a static variable, especially in multithreaded application.
Not even because it is a bad practice, but because you are running a heavy risk of deadlocking. I am telling it from my own experience. I created an application with 4 identical threads that were getting and processing JSON data from web services.
My application was frequently stalling on the following command, according to the thread dump:
Map aPage = mapper.readValue(reader, Map.class);
Beside that, performance was not good.
When I replaced static variable with the instance based variable, stalling disappeared and performance quadrupled. I.e. 2.4 millions JSON documents were processed in 40min.56sec., instead of 2.5 hours previously.
A trick I learned from this PR if you don't want to define it as a static final variable but want to save a bit of overhead and guarantee thread safe.
private static final ThreadLocal<ObjectMapper> om = new ThreadLocal<ObjectMapper>() {
#Override
protected ObjectMapper initialValue() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return objectMapper;
}
};
public static ObjectMapper getObjectMapper() {
return om.get();
}
credit to the author.
Although it is safe to declare a static ObjectMapper in terms of thread safety, you should be aware that constructing static Object variables in Java is considered bad practice. For more details, see Why are static variables considered evil? (and if you'd like, my answer)
In short, statics should be avoided because the make it difficult to write concise unit tests. For example, with a static final ObjectMapper, you can't swap out the JSON serialization for dummy code or a no-op.
In addition, a static final prevents you from ever reconfiguring ObjectMapper at runtime. You might not envision a reason for that now, but if you lock yourself into a static final pattern, nothing short of tearing down the classloader will let you re-initialize it.
In the case of ObjectMapper its fine, but in general it is bad practice and there is no advantage over using a singleton pattern or inversion-of-control to manage your long-lived objects.
com.fasterxml.jackson.databind.type.TypeFactory._hashMapSuperInterfaceChain(HierarchicType)
com.fasterxml.jackson.databind.type.TypeFactory._findSuperInterfaceChain(Type, Class)
com.fasterxml.jackson.databind.type.TypeFactory._findSuperTypeChain(Class, Class)
com.fasterxml.jackson.databind.type.TypeFactory.findTypeParameters(Class, Class, TypeBindings)
com.fasterxml.jackson.databind.type.TypeFactory.findTypeParameters(JavaType, Class)
com.fasterxml.jackson.databind.type.TypeFactory._fromParamType(ParameterizedType, TypeBindings)
com.fasterxml.jackson.databind.type.TypeFactory._constructType(Type, TypeBindings)
com.fasterxml.jackson.databind.type.TypeFactory.constructType(TypeReference)
com.fasterxml.jackson.databind.ObjectMapper.convertValue(Object, TypeReference)
The method _hashMapSuperInterfaceChain in class com.fasterxml.jackson.databind.type.TypeFactory is synchronized.
Am seeing contention on the same at high loads.
May be another reason to avoid a static ObjectMapper
This question may be old, but here's what I do.
Hold the ObjectMapper instance in a thread-safe singleton:
public final class JacksonObjectMapperHolder {
private static volatile JacksonObjectMapperHolder INSTANCE;
private static final Object MUTEX = new Object();
public static JacksonObjectMapperHolder getInstance() {
JacksonObjectMapperHolder instance = INSTANCE;
if(instance == null) {
synchronized(MUTEX) {
instance = INSTANCE;
if(instance == null) {
INSTANCE = instance = new JacksonObjectMapperHolder();
}
}
}
return instance;
}
private final ObjectMapper objectMapper = new ObjectMapper();
private JacksonObjectMapperHolder() {
super();
}
public final ObjectMapper getObjectMapper() {
return objectMapper;
}
}
I have a major design concern about my specific use-case in object construction.
I am constructing an object MyMessage based on the value of the com.fasterxml.jackson.databind.JsonNode object. For that purpose, of course, the ObjectMapper is used, so the actual construction snippet would look something like following:
JsonNode json = JsonLoader.fromResource("msg.json");
MyMessage m = jsonMapper.treeToValue(json, MyMessage.class);
Here the jsonMapper variable is of the type ObjectMapper.
Now, I would like MyMessage to only be able to construct from a static factory method, and keep the actual constructor private (as it has way too many fields). So the preferred construction would like this:
MyMessage m = MyMessage.createFromJson(json);
Here a json variable is of type JsonNode.
And that is where the problem begins. Obviously, ObjectMapper instance is needed to construct the object from JSON, and I would try to avoid it being passed-in by the client code.
Now, making ObjectMapper as a private (static) field of MyMessage comes to mind, and have something like this:
private static final ObjectMapper jsonMapper = new ObjectMapper();
private MyMessage(/* many fields */){/* ctor code */}
public MyMessage createFromJson(JsonNode json) {
return jsonMapper.treeToValue(json, MyMessage.class)
}
But here the problem is that I want the ObjectMapper object to be singleton for my entire application, and used not only for constructing MyMessage object, but also different kind of Message objects such as YourMessage, SomeOtherMessage, etc.
The problem with having many (static) instances of ObjectMapper is that I will have very large number of different Message classes, and many instances per class. So this would be very memory inefficient.
The Question
What is the closest I can get to have both a singleton ObjectMapper and a static factory method? Or maybe you could suggest some other design idea (I don't know if a builder pattern could help somehow) that would suit my use-case?
I'd suggest you move away from the static factory method restriction, and have a Factory that creates your messages, and make that class have a reference to your singleton ObjectMapper:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
final class MessagesFactory {
private final ObjectMapper objectMapper;
// This constructor is a great candidate for DI
MessagesFactory(final ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
<T extends Message> T createFromJson(
final JsonNode json, final Class<T> messageClass
) throws JsonProcessingException {
return objectMapper.treeToValue(json, clazz);
}
}
Then, wherever you need it, you can do:
MyMessage m1 = messagesFactory.createFromJson(json, MyMessage.class);
MyMessage2 m2 = messagesFactory.createFromJson(otherJson, MyMessage2.class);
Jackson have ObjectReader and documentation says that you need to use it for thread safety. But I can't understand how to do it correctly
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import java.io.IOException;
import java.util.Map;
public class JsonParser {
private ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private ObjectReader OBJECT_READER = new ObjectMapper().readerFor(Map.class);
public Map<String, String> parseJson1(String json) throws IOException {
ObjectReader objectReader = OBJECT_MAPPER.readerFor(Map.class);
return objectReader.readValue(json);
}
public Map<String, String> parseJson2(String json) throws IOException {
return OBJECT_READER.readValue(json);
}
}
I wrote two samples
parseJson1() - creates ObjectReader from ObjectMapper on each parsing
parseJson2() - reuses single instance on ObjectReader
Which of them is right?
Documentation said it's "fully thread-safe" it means you can use parseJson2 safely without worring about invoking this method in concurrent threads.
https://fasterxml.github.io/jackson-databind/javadoc/2.5/com/fasterxml/jackson/databind/ObjectReader.html
Uses "fluent" (or, kind of, builder) pattern so that instances are immutable (and thus fully thread-safe with no external synchronization); new instances are constructed for different configurations. Instances are initially constructed by ObjectMapper and can be reused, shared, cached; both because of thread-safety and because instances are relatively light-weight.
I have a Java servlet, where I want to use the Jackson JSON parser.
Rather than instantiate it multiple times (I use it in different functions in the servlet), is it safe to declare it as a 'static final' and reuse the 'ObjectMapper' across different methods in the same servlet?
Here's an example of how I currently have it:
public class ServiceExample extends HttpServlet {
private final static ObjectMapper jsonHelper = new ObjectMapper();
public void doSomething() {
jsonHelper.writeValueAsString(new SomeObject());
}
public void doSomethingElse() {
jsonHelper.writeValueAsString(new SomeOtherObject());
}
}
I thought I read somewhere that this was okay, but I wanted to double check.
Edit
According to this, it is thread-safe so long as it's configured before it's used.
Thanks.
So then you configure it in a static initializer method inside your class. Then it should not be an issue.
Servlets are normally singletons anyhow, so it wouldn't make any difference if you had it configured as:
public class ServiceExample extends HttpServlet {
private final ObjectMapper jsonHelper = new ObjectMapper();
}
The cavet to this is if you have multiple <servlet> entries for the same servlet class in web.xml will result in one instance of the servlet for each <servlet> element.
The important thing to figure out is whether or not the ObjectMapper from jackson is threadsafe.
If a singleton is implemented as follows,
class Singleton {
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
How is this implementation different from the lazy initialization approach?
In this case,the instance will be created when the class is loaded and the class itself is loaded only on the first active use (for example, Singleton.getInstance() not when you declare for instance Singleton singleton = null;)
Even with lazy initialization approach, the instance is created on the call to getInstance()
Am i missing something here?
With lazy initialization you crate instance only when its needed and not when the class is loaded. So you escape the unnecessary object creation. That being said there are other things to consider too.
In lazy initialization you give a public API to get the instance. In multi-threaded environment it poses challenges to avoid unnecessary object creation. you put synchronization blocks which poses unnecessary locking to be done to check for object already created. So it becomes a performance issue in this case.
So if you are sure that creating you object is not going to take any significant memory and its almost always going to be used in your application then its good to create in static initialization. Also please do not forget to make your instance final in this case as it make sures that the object creation is reflected properly and in totality to main memory which is important in multi-threaded environment.
Please refer this tutorial from IBM on Singleton+ Lazy Loading+ Multithreaded Environment case
===============Edit on 09/09/2018====================
You should also look at object creation on demand pattern here.
You may call any other static methods or static member variable too to load the singleton instance.
class Logger {
private static Logger instance = new Logger();
public static String LOG_LINE_SEPERATOR =
System.getProperty("line.separator");
public static Logger getInstance() {
return instance;
}
public static String logPattern() {
return null;
}
}
...
Logger.LOG_LINE_SEPERATOR; // load Logger instance or
Logger.logPattern(); // load Logger instance
For the reasons you mention, this is just a more complicated way of doing much the same as
enum Singleton {
INSTANCE;
}
Using lazy initialisation is only useful if you are concerned that the class could be initilised but you don't want to load the singleton at that point. For most situations this is over kill.
Note: Just referencing the class does not initialise the class.
e.g. Say you have a badly written class which cannot be initilised until some condition is set. In this case n must be non-zero.
public class Main {
public static void main(String ... args) {
Class c= LazyLoaded.class;
System.out.println(c);
}
static class LazyLoaded {
static int n = 0;
static {
System.out.println("Inverse "+1000/n);
}
}
}
prints
class Main$LazyLoaded
First of all, the singleton pattern is overused. What you really want to do if you want "one of something" is to declare it a singleton in your DI framework of choice. This is effectively a configuration driven eager singleton, and frees up options for injecting mocks to do proper testing.
Why not lazy load? Unless your class has a massive initialization routine in construction (which I would argue is also an anti-pattern), there is no benefit and lots of drawbacks to lazy loading. You're just adding complexity and possibly breaking your program if it's not done correctly. The correct way (if you must) is to use the Initialization-on-demand holder idiom.
For lazy loading singleton instance, I am using as below.
class Singleton {
private static Singleton instance;
private Singleton(){
}
public static Singleton getInstance() {
if(null==instance){
synchronized(Singleton.class){
if(null==instance){
instance = new Singleton();
}
}
}
return instance;
}
}