[External] : Re: New candidate JEP: 471: Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal
Ron Pressler
ron.pressler at oracle.com
Tue May 14 11:11:09 UTC 2024
> On 13 May 2024, at 21:18, Ron Pressler <ron.pressler at oracle.com> wrote:
>
> The draft JEP, Integrity by Default (https://openjdk.org/jeps/8305968), which covers the general strategy guiding us in this JEP and others, also covers the recommended practice for libraries under integrity by default. It includes what we’ve recommended to serialization libraries since JDK 9. I’ll summarise the recommendations here:
>
> 1. Client code should grant the serialization library access to its private data either programmatically (by passing a MethodHandles.Lookup, e.g. in a class initializer) or declaratively by opening the module to the serialization library in module-info.java.
>
> 2. When serializing JDK classes, the serialization library can take advantage of sun.reflect.ReflectionFactory, which has been left unencapsulated precisely for that purpose.
>
> However, in the long term serialization libraries are advised to migrate away from any direct access of fields, as the practice is inherently dangerous: it bypasses data validation done in the constructor. Deserialization in particular should use constructors, which is easy for collections and records, and ask users to register class-specific serializers that call constructors for other kinds of classes.
>
> Explicitly granting deep reflective access — either declaratively or programmatically — is useful to express the risk inherent to allowing library code, which is unaware of the specific invariants of a class, directly set a class’s fields while bypassing its constructors. A more coarse-grained permission poses a usability challenge, as it makes it hard to inspect which classes are exposed to which risks.
>
> — Ron
P.S.
It’s worth mentioning here that the use of the --add-opens flag (and/or the --add-exports) on the command line is never recommended. They change encapsulation without the cooperation of the affected classes [1], and denote a temporary workaround for some issue that will later need to be addressed (they’re like a TODO comment). The right number of --add-opens flags in an up-to-date and portable Java application is zero.
[1]: It may not be the case for serialization, but opening deep reflective access to a set of classes means that an *internal* change to those classes may break the application. If the classes don’t acknowledge it, it means they’re not aware of this risk. They’re also unaware that some invariants they wish to rely on may be broken.
— Ron
More information about the jdk-dev
mailing list