Best Practice for Jackson collection deserialisation - java

Let's say I have a simple class Person
public class Person{
final List<String> names= Lists.newArrayList();
public List<String> getNames(){
return names;
}
}
If I try to deserialise that with Jackson (2.2)
Person l = mapper.readValue(js,Person.class);
I get Disabling Afterburner deserialization ....due to access error (type java.lang.IllegalAccessError ....
This is because of final names list. To solve this I set MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS to false.
Is this the right solution or better just to make the list non-final?
Is there a Jackson method to use collection.add methods for initialising collections?
Or maybe there is a better way. What can be suggested here?
EDIT: I now found this setting:
USE_GETTERS_AS_SETTERS (default: true) Controls whether "getters" that
return Collection or Map types can be used for "setting" values (same
as how JAXB API works with XML), so that separate "setter" method is
not needed. Even if enabled, explicit "setter" method will have
precedence over implicit getter-as-setter, if one exists.
Seems like exactly what I was looking and it is on by default. So why was it ignored then?

Working with immutable Objects in your application is a best practice, but on the boundaries to the (non-Java) outside world, you usually have to refrain from using them.
In most Serialization technologies, everything works fine when your Objects are "well-behaved" (mutable, with getters and setters according to the JavaBeans-standard). There's usually some way around that but in my experience it's easiest to just make the damn thing mutable, as long as you're not going to reference it from other Java Code. (if worst comes to worst, create a dedicated serialization DTO)

I suspect that this is due to a problem with combination of things. Specifically, can you try your approach without enabling Afterburner first? If this works, then this is an issue with Afterburner module's handling of processing -- it is possible since code path involved here differs from default one.
Make sure to use latest version; 2.3.0 was just released.

Related

Setter returning this vs builder

I was wondering, when constructing an object, is there any difference between a setter returning this:
public User withId(String name) {
this.name = name;
return this;
}
and a builder (for example one which is generated by Builder Generator plugin for IDEA)?
My first impression is that a setter returning this is much better:
it uses less code - no extra class for builder, no build() call at the end of object construction.
it reads better:
new User().withName("Some Name").withAge(30);
vs
User.UserBuilder.anUserBuilder().withName("Some Name").withAge(30).build();
Then why to use builder at all? Is there anything I am missing?
The crucial thing to understand is the concept of an immutable type.
Let's say I have this code:
public class UnitedStates {
private static final List<String> STATE_NAMES =
Arrays.asList("Washington", "Ohio", "Oregon", "... etc");
public static List<String> getStateNames() {
return STATE_NAMES:
}
}
Looks good, right?
Nope! This code is broken! See, I could do this, whilst twirling my moustache and wielding a monocle:
UnitedStates.getStateNames().set(0, "Turtlia"); // Haha, suck it washington!!
and that will work. Now for ALL callers, apparently there's some state called Turtlia. Washington? Wha? Nowhere to be found.
The problem is that Arrays.asList returns a mutable object: There are methods you can invoke on this object that change it.
Such objects cannot be shared with code you don't trust, and given that you don't remember every line you ever wrote, you can't trust yourself in a month or two, so, you basically can't trust anybody. If you want to write this code properly, all you had to do is use List.of instead of Arrays.asList, because List.of produces an immutable object. It has zero methods that change it. It seems like it has methods (it has a set method!), but try invoking it. It won't work, you'll get an exception, and crucially, the list does not change. It is in fact impossible to do so. Fortunately, String is also immutable.
Immutables are much easier to reason about, and can be shared freely with whatever you like without copying.
So, want your own immutable? Great - but apparently the only way to make one, is to have a constructor where all values are set and that's it - immutable types cannot have set methods, because that would mutate them.
If you have a lot of fields, especially if those fields have the same or similar types, this gets annoying fast. Quick!
new Bridge("Golden Gate", 1280, 1937, 2737);
when was it built? How long is it? What's the length of the largest span?
Uhhhhhhh..... how about this instead:
newBridge()
.name("Golden Gate")
.longestSpan(1280)
.built(1937)
.length(2737)
.build();
sweet. Names! builders also let you build over time (by passing the builder around to different bits of code, each responsible for setting up their bits). But a bridgebuilder isn't a bridge, and each invoke of build() will make a new one, so you keep the general rules about immutability (a BridgeBuilder is not immutable, but any Bridge objects made by the build() method are.
If we try to do this with setters, it doesn't work. Bridges can't have setters. you can have 'withers', where you have set-like methods that create entirely new objects, but, calling these 'set' is misleading, and you create both a ton of garbage (rarely relevant, the GC is very good at collecting short lived objects), and intermediate senseless bridges:
Bridge goldenGate = Bridge.create().withName("Golden Gate").withLength(2737);
somewhere in the middle of that operation you have a bridge named 'Golden Gate', with no length at all.
In fact, the builder can decide to not let you build() bridge with no length, by checking for that and throwing if you try. This process of invoking one method at a time can't do that. At best it can mark a bridge instance as 'invalid', and any attempt to interact with it, short of calling .withX() methods on it, results in an exception, but that's more effort, and leads to a less discoverable API (the with methods are mixed up with the rest, and all the other methods appear to throw some state exception that is normally never relevant.. that feels icky).
THAT is why you need builders.
NB: Project Lombok's #Builder annotation gives you builders for no effort at all. All you'd have to write is:
import lombok.Value;
import lombok.Builder;
#Value #Builder
public class Bridge {
String name;
int built;
int length;
int span;
}
and lombok automatically takes care of the rest. You can just Bridge.builder().name("Golden Gate").span(1280).built(1937).length(2737).build();.
Builders are design patterns and are used to bring a clear structure to the code. They are also often used to create immutable class variables. You can also define preconditions when calling the build() method.
I think your question is better formulated like:
Shall we create a separate Builder class when implementing the Builder Pattern or shall we just keep returning the same instance?
According to the Head First Design Patterns:
Use the Builder Pattern to encapsulate the construction of a product
and allow it to be constructed in steps.
Hence, the Encapsulation is important point.
Let's now see the difference in the approaches you have provided in your original question. The main difference is the Design, of how you implement the Builder Pattern, i.e. how you keep building the object:
In the ObjecBuilder separate class approach, you keep returning the Builder object, and you only(!) return the finalized/built Object, after you have finalized building, and that's what better encapsulates creation process, as it's more consistent and structurally well designed approach, because you have a clearly separated two distinct phases:
1.1) Building the object;
1.2) Finalizing the building, and returning the built instance (this may give you the facility to have immutable built objects, if you eliminate setters).
In the example of just returning this from the same type, you still can modify it, which probably will lead to inconsistent and insecure design of the class.
It depends on the nature of your class. If your fields are not final (i.e. if the class can be mutable), then doing this:
new User().setEmail("alalal#gmail.com").setPassword("abcde");
or doing this:
User.newBuilder().withEmail("alalal#gmail.com").withPassowrd("abcde").build();
... changes nothing.
However, if your fields are supposed to be final (which generally speaking is to be preferred, in order to avoid unwanted modifications of the fields, when of course it is not necessary for them to be mutable), then the builder pattern guarantees you that your object will not be constructed until when all fields are set.
Of course, you may reach the same result exposing a single constructor with all the parameters:
public User(String email, String password);
... but when you have a large number of parameters it becomes more convenient and more readable to be able to see each of the sets you do before building the object.
One advantage of a Builder is you can use it to create an object without knowing its precise class - similar to how you could use a Factory. Imagine a case where you want to create a database connection, but the connection class differs between MySQL, PostgreSQL, DB2 or whatever - the builder could then choose and instantiate the correct implementation class, and you do not need to actually worry about it.
A setter function, of course, can not do this, because it requires an object to already be instantiated.
The key point is whether the intermediate object is a valid instance.
If new User() is a valid User, and new User().withName("Some Name") is a valid User, and new User().withName("Some Name").withAge(30) is a valid user, then by all means use your pattern.
However, is a User really valid if you've not provided a name and an age? Perhaps, perhaps not: it could be if there is a sensible default value for these, but names and ages can't really have default values.
The thing about a User.Builder is the intermediate result isn't a User: you set multiple fields, and only then build a User.

Checking String parameters corresponding to field names

I'm heavily using Java.lang.Class.getField() method which requires a String variable as an argument. The problem I'm facing is when I change field names, that getField() refers to, Eclipse doesn't warn me that argument points nowhere (since it's String) and I end up having methods working improperly unnoticed.
So far I can see two ways out. It's either using try-catch blocks around every getField() call and running application to see what will be the next line to throw an exception. Fix it and watch out for the next exception. Or it's using Find/Replace feature every time I change a field name to manually look for the String value and replace it. Is there a more friendly (i.e. automatic) way to update String parameters in such cases?
Maybe there's a method (which I fail to find) that accepts a full field path as a non-String argument and returns a Field object? Something like turnToFieldObject(car.speed) returning Field object corresponding to speed field so that Eclipse would automatically check if there's such a field car.speed.
PS
First of all, thank you for your replies.
I can see that a lot of you, guys, suggest that I'm using reflection too much. That's why I feel I need to add extra explanation and would be glad to hear suggestions as well.
I'm doing a research about modeling social evolution and I need the entities to evolve new features that they don't have at the start. And it seemed to me that adding new fields to represent some evolutional changes is better understanding wise than adding new elements to arrays or collections. And the task suggests I shouldn't be able to know what feature will be evolved. That's why I rely so heavily on reflection.
AFAIK, there is no such method. You pass a reference (if it's an object) or value (if it's primitive); all data about the variables that they were originally assigned to is not available at runtime.
This is the huge downside of using reflection, and if you're "heavily" using this feature in such way, you're probably doing something wrong. Why not access the field directly, using getters and setters?
Don't get me wrong, reflection has its uses (for example, when you want to scan for fields with certain annotations and inject their values), but if you're referencing fields or methods by their name using a simple string, you could just as well access fields or methods directly. It implies that you know the field beforehand. If it's private, there is probably a reason why it's encapsulated. You're losing the content assist and refactoring possibilities by overusing reflection.
If you're modeling social evolution, I'd go with a more flexible solution. Adding new fields at runtime is (near?) impossible, so you are basically forced to implement a new class for each entity and create a new object each time the entity "evolves". That's why I suggest you to go with one of these solutions:
Use Map<String, Object> to store entities' properties. This is a very flexible solution which will allow you easily add and remove "fields" at the cost of losing their type data. Checking if the entity has a certain property will be a cheap contains call.
If you really want to stick to a million custom classes, use interfaces with getters and setters in addition to fields. For example, convert private String name to interface Named { String getName(); void setName(String name); }. This is much easier to refactor and does not rely on reflection. A class can implement as many interfaces as you want, so this is pretty much like the field solution, except it allows you to create custom getters/setters with extra logic if desperately needed. And determining if entity has a certain property is a entity instanceof MyInterface call, which is still cheaper than reflection.
I would suggest writing a method that use to get your fields supply it a string and then if the exception is thrown notify whatever needs to be notified that it was not valid and if the exception isn't caught return the field.
Although I do agree with the above that reflection should not be used heavily.

Ways to signal that API returns an unmodifiable/immutable collection

Other than documenting it (obviously it should also be documented), using a special return type (I'm wary of limiting myself to an ImmutableX) or having the user find out at runtime, is there any other way of telling the users of an API that the collection they receive from said API is unmodifiable/immutable?
Are there any naming conventions or marker annotations that universally signal the same thing?
Edit: Unmodifiable and immutable do not mean the same thing, but for the purposes of this question, they are similar enough. The question basically boils down to letting the user know that the returned object does not fully honour its contract (ie. some common operations will throw a runtime exception).
Not a general naming convention but you might be interested in using this #Immutable annotation: http://aspects.jcabi.com/annotation-immutable.html
Besides the documentation purpose this mechanism will also validate if your object is really immutable (during it's instantiation) and throw a runtime exception if it is not.
Good and verbose solution would be to make your own UnmodifiableCollection wrapper class, and return it:
public UnmodifiableCollection giveMeSomeUnmodifableCollection() {
return new UnmodifiableCollection(new LinkedList());
}
The name of the return type would be enough to make verbose statement about the unmodifiablility of the collection.
Document it indeed
Provide API for checking if the given object is imutable collection
Return collection in wrapper that will hold information is the collection inside of it is mutable or not - my favorite solution
If possible, dont use mullable and immutable collections, but pick one of them. Results can always be immutable as they are results - why changing it. If there would be such need, it is a matter of single line to copy collection to new, mutable one and modify it (eg for chain processing)
Writing an #Immutable annotation on the return type of a method is the best approach. It has multiple benefits:
the annotation documents the meaning for users
a tool can verify that client code respects the annotation (that is, that client code does not have bugs)
a tool can verify that the library code respects the annotation (that is, that library code does not have bugs)
What's more, the verification can occur at compile time, before you ever run your code.
If you want verification at compile time, you can use the IGJ Immutability Checker. It distinguishes between
#Immutable references whose abstract value never changes, and
#ReadOnly references upon which side effects cannot be performed.

getDeclaredField(String) vs. getMethod(String) for private fields in a bean

I have a bean whose properties I want to access via reflection. I receive the property names in String form. The beans have getter methods for their private fields.
I am currently getting the field using getDeclaredField(fieldName), making it accessible by using setAccessible(true) and then retrieving its value using get.
Another way to go about it would be to capitalize the field name and add get to the front of it, and then get the method by that name from the class and finally invoke the method to get the value of the private field.
Which way is better?
EDIT
Perhaps I should explain what I mean by "better"... By "better", I mean in the sense of best-practices. Or, if there are any subtle caveats or differences.
You may want to take a look at the Introspector class, its a nice wrapper if you want to only deal with properties which have been exposed, you can get a BeanInfo object and then call getPropertyDescriptors(), for example:
final BeanInfo info = Introspector.getBeanInfo(clazz);
for (PropertyDescriptor prop : info.getPropertyDescriptors()) {
final Method read = prop.getReadMethod();
if (read != null) {
// do something
}
}
It depends of your use, but in general I would prefer to use the getter as this is the "normal" way and will in more cases do the thing the developer of the class expects gets done.
In principle, if the developer of the class has made the field private he is free to do as he pleases, like for instance removing it later if it can be calculated in another way. Then the fieldaccess will break, hopefully immediately, if you are unlucky 3 months later when nobody remembers anymore.
Note that there a libraries like apache commons BeanUtils (I believe there is one in Spring too) which does that for you and offer a more sane interface, like a hash map for example.
Possibly using the getter method, as it may have additional behaviour besides just returning the property's value. However this depends on the class.
Better in what way?
You could write a 20 line unit test to see which is faster. You could write both and look at them to see which is easier to read. If one way is both easier to read and faster, go for it. If not, you will have to pick your poison...

XStream or Simple

I need to decide on which one to use. My case is pretty simple. I need to convert a simple POJO/Bean to XML, and then back. Nothing special.
One thing I am looking for is it should include the parent properties as well. Best would be if it can work on super type, which can be just a marker interface.
If anyone can compare these two with cons and pros, and which thing is missing in which one. I know that XStream supports JSON too, thats a plus. But Simple looked simpler in a glance, if we set JSON aside. Whats the future of Simple in terms of development and community? XStream is quite popular I believe, even the word, "XStream", hit many threads on SO.
Thanks.
Just from reading the documentation (I'm facing down the same problem you are, but haven't tried either way yet; take this with a grain of salt):
XSTREAM
Very, very easy to Google. Examples, forum posts, and blog posts about it are trivial to find.
Works out of the box. (May need more tweaking, of course, but it'll give you something immediately.)
Converting a variable to an attribute requires creating a separate converter class, and registering that with XStream. (It's not hard for simple values, but it is a little extra work.)
Doesn't handle versioning at all, unless you add in XMT (another library); if the XML generated by your class changes, it won't deserialize at all. (Once you add XMT, you can alter your classes however you like, and have XStream handle it fine, as long as you create an increasing line of incremental versioning functions.)
All adjustments require you to write code, either to implement your own (de)serialization functions, or calling XStream functions to alter the (de)serialization techniques used.
Trivial syntax note: you need to cast the output of the deserializer to your class.
SIMPLE
Home page is the only reliable source of information; it lists about a half-dozen external articles, and there's a mailing list, but you can't find it out in the wild Internet.
Requires annotating your code before it works.
It's easy to make a more compact XML file using attributes instead of XML nodes for every property.
Handles versioning by being non-strict in parsing whenever the class is right, but the version is different. (i.e., if you added two fields and removed one since the last version, it'll ignore the removed field and not throw an exception, but won't set the added fields.) Like XStream, it doesn't seem to have a way to migrate data from one version to the next, but unlike XStream, there's no external library to step in and handle it. Presumably, the way to handle this is with some external function (and maybe a "version" variable in your class?), so you do
Stuff myRestoredStuff = serializer.read(Stuff.class, file);
myRestoredStuff.sanityCheck();
Commonly-used (de)serializing adjustments are made by adding/editing annotations, but there's support for writing your own (de)serialization functions to override the standard methods if you need to do something woolly.
Trivial syntax note: you need to pass the restored object's class into the deserializer (but you don't need to cast the result).
Why not use JAXB instead?
100% schema coverage
Huge user base
Multiple implementations (in case you hit a bug in one)
Included in Java SE 6, compatible with JDK 1.5
Binding layer for JAX-WS (Web Services)
Binding layer for JAX-RS (Rest)
Compatible with JSON (when used with libraries such as Jettison)
Useful resources:
Comparison, JAXB & XStream
Comparison, JAXB & Simple
I'd recommend that you take a look at Simple
I would also suggest Simple, take a look at the tutorial, there and decide for yourself. The mailing list is very responsive and you will always get a prompt answer to any queries.
So far I have never use Simple framework yet.
Based on my experience with Xstream. It worked well on XML. However, for JSON, the result is not as precise as expected when I attempt to serialize a bean that contain a List of Hashtable.
Thought I share this here.
To get XStream to ignore missing fields (when you have removed a property):
XStream xstream = new XStream() {
#Override
protected MapperWrapper wrapMapper(MapperWrapper next) {
return new MapperWrapper(next) {
#Override
public boolean shouldSerializeMember(Class definedIn,
String fieldName) {
if (definedIn == Object.class) {
return false;
}
return super.shouldSerializeMember(definedIn, fieldName);
}
};
}
};
This can also be extended to handle versions and property renames.
Credit to Peter Voss: https://pvoss.wordpress.com/2009/01/08/xstream
One "simple" (pun intended) disadvantage of Simple and Jaxb is that they require annotating your objects before they can be serialized to XML. What happens the day you quickly want to serialize someone else's code with objects that are not annotated? If you can see that happening one day, XStream is a better fit. (Sometimes it really just boils down to simple requirements like this to drive your decisions).
Was taking a quick look at simple while reading stackoverflow; as an amendment to Paul Marshalls helpful post, I thought i'd mention that Simple does seem to support versioning through annotations-
http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#version
Simple is much slower then XStream(in serialization objects to xml)
http://pronicles.blogspot.com/2011/03/xstream-vs-simple.html

Categories