Replies: 2 comments
-
|
@stolsvik Very interesting! Thank you for digging this up and sharing. Yes, I think that a new
If so, this could go in both 2.x (2.21) and 3.x (3.1) and not change default settings. |
Beta Was this translation helpful? Give feedback.
0 replies
-
|
Note: if anyone wants to proceed with this, should file a feature request on https://github.com/FasterXML/jackson-databind/issues , referencing this issue. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
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?
https://openjdk.org/jeps/500
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.
Beta Was this translation helpful? Give feedback.
All reactions