<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">On Mon, May 13, 2024 at 3:49 PM Ron Pressler <<a href="mailto:ron.pressler@oracle.com">ron.pressler@oracle.com</a>> wrote:</span><br></div></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The draft JEP, Integrity by Default (<a href="https://openjdk.org/jeps/8305968" rel="noreferrer" target="_blank">https://openjdk.org/jeps/8305968</a>), 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:<br>
<br>
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.<br>
<br>
2. When serializing JDK classes, the serialization library can take advantage of sun.reflect.ReflectionFactory, which has been left unencapsulated precisely for that purpose.<br>
<br>
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.<br>
<br>
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.<br></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">I'm well aware of these arguments, as I was present when they were devised (and have the scars - and jpms-spec-experts membership - to prove it). As I said, I fully support the goal of integrity by default.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">However neither of these points really addresses the problem at hand. In particular, ReflectionFactory does not relate specifically to serializing JDK classes; it presently provides access to serialization constructors and (lately) the non-public serialization spec methods for *all* classes. It does not address the problem of field access in any way.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">While I understand that nobody likes the current JDK serialization strategy (we don't like it either), we don't really have a workable alternative *yet*. I've seen the seeds of some good ideas from Brian and others over the years but there is nothing that we can point to and say "this is where we are going to go with this". In the meantime there are several thousand JDK classes, and many more thousands of user classes which are `Serializable`. It is not feasible to ask the user to `--add-opens` every single package containing such a class. It is also not feasible for every general purpose library that contains a `Serializable` class to open their packages containing serializable classes to the modules of every existing serialization spec compliant framework. It will simply not work in practice, and this is another hurdle preventing the modularization of the ecosystem as a whole.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">ReflectionFactory allows access to serialization facilities without any access checking (other than the defunct SecurityManager checks). Perhaps this class could gain some more methods, like this:</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">* `newGetterForSerialization(Field field)` - includes ability to access `objectStreamFields` and `serialVersionUID`, or these could be separate methods</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">* `newSetterForSerialziation(Field field)`</div></div><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Does this seem workable?</div><br></div><div><br></div></div><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature"><div dir="ltr">- DML • he/him<br></div></div></div>