On Thu, 13 Jun 2024 14:31:06 GMT, David M. Lloyd <d...@openjdk.org> wrote:

> Issue [JDK-8164908](https://bugs.openjdk.org/browse/JDK-8164908) added 
> support for functionality required to continue to support IIOP and custom 
> serializers in light of additional module-based restrictions on reflection. 
> It was expected that these libraries would use `sun.misc.Unsafe` in order to 
> access fields of serializable classes. However, with JEP 471, the methods 
> necessary to do this are being removed.
> 
> To allow these libraries to continue to function, it is proposed to add two 
> methods to `sun.reflect.ReflectionFactory` which will allow serialization 
> libraries to acquire a method handle to generated `readObject`/`writeObject` 
> methods which set or get the fields of the serializable class using the 
> serialization `GetField`/`PutField` mechanism. These generated methods should 
> be used by serialization libraries to serialize and deserialize classes which 
> do not have a `readObject`/`writeObject` method or which use 
> `ObjectInputStream.defaultReadObject`/`ObjectOutputStream.defaultWriteObject` 
> to supplement default serialization.
> 
> It is also proposed to add methods which allow for the reading of 
> serialization-specific private static final fields from classes which have 
> them.
> 
> With the addition of these methods, serialization libraries no longer need to 
> rely on `Unsafe` for serialization/deserialization activities.
> cc: @AlanBateman

Oops, I forgot that `cc` is a Skara command. Sorry, bot.

I've updated the PR with a new access control solution, but it's not ideal 
since it involves internal reflection. To solve this issue, unless I'm 
misunderstanding something, I think we would need to have access to 
`Lookup#IMPL_LOOKUP` from the method generators. The only way I can think to do 
this (without exposing the lookup from `JavaLangInvokeAccess`, which I assume 
would not be desirable) would be to move the generators into the 
`java.lang.invoke` package, adding methods to `JavaLangInvokeAccess` for that 
purpose. Would this be the recommended approach, or is there some other better 
approach that I do not see?

I added a commit which moves the bytecode gen to the JLI package and accesses 
it via SharedSecrets, which is reasonably similar to what other methods in 
ReflectionFactory are already doing.

Edit: Per Alan's feedback this was moved back again. See [the resolved 
discussion](https://github.com/openjdk/jdk/pull/19702#discussion_r1658837413) 
for details.

> I skimmed through the latest update 
> ([d137f43](https://github.com/openjdk/jdk/commit/d137f43b00e935e9fbcaeaa80fdff93a0a2df44b))
>  and I think you've got this to a good place and a sensible/workable 
> proposal. I've asked from help from others on the security review of this.

Great. There are a couple more tests I want to add but once that's done I'll 
mark it "Ready for review".

> Right now, I'm still wonder if 
> defaultReadObjectForSerialization/defaultWriteObjectForSerialization should 
> return the same as readObjectForSerialization/writeObjectForSerialization 
> when the readObject/writeObject methods are defined. This is more of a 
> concern for a class with a readObject of course as that readObject will 
> likely check invariants that would be bypassed if the serialization library 
> always uses the defaultXXX methods.

By spec, the `readObject` method must call either `OIS#defaultReadObject` or 
`OIS#readFields`, but they _are_ allowed to choose which one they call. If they 
call `defaultReadObject`, then the serialization library would still need 
`defaultReadObjectForSerialization` in order to implement it. If 
`defaultReadObjectForSerialization` falls back to calling the user 
`readObject`, we then would (at best) have a stack overflow situation, because 
the user's `readObject` would call `defaultReadObject`, which in turn would 
call back into the user's `readObject`, etc.

So, in some cases, the (de)serializer can use only `readObjectForSerialization` 
(specifically, when there is a user `readObject` method which uses 
`readFields`); in other cases it can use only 
`defaultReadObjectForSerialization` (when the user didn't provide a 
`readObject`); and, in the final case, it would need to use both (when the user 
`readObject` calls `OIS#defaultReadObject`).

The same thing applies on the write side.

> I'd probably drop the "Of" suffix from serialPersistentFieldsOf and 
> serialVersionUIDOf but naming isn't important right now.

I'll do so.

> /csr
> 
> Since this is an API addition, this will require a CSR; Valhalla folks can 
> check if this API is future-proof in the CSR.

According to https://wiki.openjdk.org/display/csr/CSR+FAQs, only changes to 
public and exported APIs in the `jdk.*`, `java.*`, and `javax.*` packages need 
a CSR. This PR changes public and exported APIs in the `sun.misc` package, and 
changes public but non-exported APIs in the `jdk.internal.reflect` package, so 
I don't think it qualifies, does it?

The CSR is [JDK-8335438](https://bugs.openjdk.org/browse/JDK-8335438).

-------------

PR Comment: https://git.openjdk.org/jdk/pull/19702#issuecomment-2165859586
PR Comment: https://git.openjdk.org/jdk/pull/19702#issuecomment-2195182295
PR Comment: https://git.openjdk.org/jdk/pull/19702#issuecomment-2195575503
PR Comment: https://git.openjdk.org/jdk/pull/19702#issuecomment-2200005883
PR Comment: https://git.openjdk.org/jdk/pull/19702#issuecomment-2200116881
PR Comment: https://git.openjdk.org/jdk/pull/19702#issuecomment-2200604899

Reply via email to