-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
As described here:
https://github.com/FasterXML/jackson/blob/main/jackson3/MIGRATING_TO_JACKSON_3.md#5-default-config-setting-changes
MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS (disabled in 3.0): this non-intuitive feature may have masked actual problems with immutable classes, wherein Jackson forcibly overwrote values of final fields (which is possible via reflection!), but the developer assumed a constructor was being used.
"Is it a Bug or Feature?" -- disabled since newer JVMs are less likely to allow the feature to work.
I had to look this up, and JEP 500 seems to make for a clear way out for exactly deserialization - assuming that the POJOs implement Serializable.
Would it be relevant to introduce a mapper feature whereby setting of final fields are supported on Serializable classes, and that this was default enabled?
Serialization libraries should use sun.reflect.ReflectionFactory
The ability to mutate final fields via deep reflection was added in JDK 5 so that third-party serialization libraries could provide functionality on par with the JDK's own serialization facilities. The JDK can deserialize an object from an input stream even if the object's class declares final fields. It does this by bypassing the class's constructors, which ordinarily assign instance fields, and assigning values from the input stream to instance fields directly — even if they are final. Third-party serialization libraries use deep reflection to do the same.
When final field restrictions are strengthened in a future JDK release, serialization libraries will no longer be able to use deep reflection out-of-the-box. Rather than ask users to enable final field mutation on the command line, maintainers of serialization libraries should serialize and deserialize objects using the sun.reflect.ReflectionFactory API, which is supported for this purpose. This API allows a serialization library to obtain a method handle to special code that initializes an object by assigning to its instance fields directly, including final fields. This code, which is dynamically generated by the JDK, gives the serialization library the same powers as the JDK's own serialization facilities; it is not necessary to enable final field mutation by the module of the serialization library.
The sun.reflect.ReflectionFactory class only supports the deserialization of objects whose classes implement the java.io.Serializable interface. This limitation balances the interests of developers using serialization libraries with the wider interest of all developers in having correct and efficient execution. It ensures that the JVM, when performing optimizations such as constant folding, is not unduly constrained in the assumptions it can make: It must assume that final fields in Serializable objects are potentially mutable, but it can also assume that final fields in all other objects — which are the vast majority — are permanently immutable.