JEP 8323072 and Serialization

Shahan Yang shahan at google.com
Thu Mar 28 13:07:10 UTC 2024


On Thu, Mar 28, 2024, 3:53 AM Remi Forax <forax at univ-mlv.fr> wrote:

>
>
> ------------------------------
>
> *From: *"Shahan Yang" <shahan at google.com>
> *To: *"amber-dev" <amber-dev at openjdk.org>
> *Sent: *Thursday, March 28, 2024 12:20:44 AM
> *Subject: *JEP 8323072 and Serialization
>
>
> Hello,
>
>
> My apologies if this is the wrong place for this kind of question. I
> maintain an Unsafe-heavy serialization library and I am weighing options in
> light of Unsafe memory access deprecation.
>
> It appears that the recommended replacement is to use VarHandles. This
> seems reasonable at first glance, but it looks like VarHandles do not
> support writes to final fields.
>
> The problem is that there's a large codebase with a lot of application
> logic objects to be serialized. The presence of final fields on those
> objects aids in their readability. Currently, those fields can just be set
> using Unsafe.put* methods during deserialization, but that isn't possible
> with VarHandles. I don't think it's reasonable to ask developers to make
> all of the application object fields non-final for deserialization. It
> would also be an infeasibly large amount of toil to add custom code to
> serialize and deserialize all those objects, relative to what is possible
> with reflection.
>
> I can think of a number of alternatives, but so far I haven't come up with
> anything that avoids harming the readability of the code, increasing toil,
> making serialization more error prone or slower (just using regular Field
> reflection instead of Unsafe to set final fields?). I'm less worried about
> records because the tight contract between their constructors and their
> fields makes a code generation-based solution quite clean.
>
> Do you have any suggestions? Am I overlooking something that other
> serialization libraries are doing here?
>
>
> You ask for suggestions, my suggestion is that your serialization
> framework should ask users to provide the equivalent of a record canonical
> constructor, i.e. a constructor with the same visibility as the class that
> is able to initialize the class with either an annotation for each
> parameter that contains the corresponding name of the field or you can ask
> users to compile with "-parameters" then at runtime like with records, you
> just call that constructor. In my opinion, that's the simpler future-proof
> solution.
> I think Brian as alreay proposes something quite similar for the Java
> serialization.
>

Very well, thank you. Ironically, the serialization code started with that
approach and quite a few classes are still serialized that way when
reflection doesn't work. It's a bit more error prone and more toil which is
why the reflection-based approach came into being. I guess we'll move back
to constructor-based.


> Why future-proof ?
> As part of Valhalla, we are introducing a new kind of fields, "really
> really final" fields that must be initialized *before* calling the super
> constructor and that can not be updated after the call to the super
> constructor. So even if we do not disable Unsafe.putField for those fields,
> the JIT is allowed to not use the result of an Unsafe.putField and use a
> previously seen value of the field.
>

Thank you for explaining this. Can't wait to see Valhalla.


>
>
> Otherwise, you can set the value of a final field by getting the field,
> calling setAccessible on it, then uses Lookup.unreflectSetter(field) on
> that field. You will get a method handle able to set a final field.
> But as i said above, it will be a short victory.
>
>
>
> Thanks,
> Shahan
>
>
> regards,
> Rémi
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20240328/572b3dad/attachment-0001.htm>


More information about the amber-dev mailing list