RFR: JDK-8242888: Convert dynamic proxy to hidden classes
Johannes Kuhn
info at j-kuhn.de
Mon Apr 18 10:53:45 UTC 2022
On 18-Apr-22 9:36, Alan Bateman wrote:
> On 17/04/2022 17:24, liach wrote:
>> Convert dynamic proxies to hidden classes. Modifies the serialization
>> of proxies (requires change in "Java Object Serialization
>> Specification"). Makes the proxies hidden in stack traces. Removes
>> duplicate logic in proxy building.
>>
>> The main compatibility changes and their rationales are:
>> 1. Modification to the serialization specification: In the "An
>> instance of the class is allocated... The contents restored
>> appropriately" section, I propose explicitly state that handling of
>> proxies are unspecified as to allow implementation freedom, though
>> I've seen deliberate attempts for proxies to implement interfaces with
>> `readResolve` in order to control their serialization behavior.
>> - This is for the existing generated constructor accessor is
>> bytecode-based, which cannot refer to hidden classes.
>> - An alternative is to preserve the behavior, where the
>> serialization constructor calls `invokespecial` on the closest
>> serializable superclass' no-arg constructor, like in #1830 by @DasBrain.
>> - My rationale against preservation is such super calls are unsafe
>> and should be discouraged in the long term. Calling the existing
>> constructor with a dummy argument, as in my implementation, would be
>> more safe.
>> 2. The disappearance of proxies in stack traces.
>> - Same behavior exists in lambda expressions: For instance, in
>> `((Runnable) () -> { throw new Error(); }).run();`, the `run` method,
>> implemented by the lambda, will not appear in the stack trace, and
>> isn't too problematic.
>
> It's great that you have time to experiment in this area but just to set
> expectations that it will likely require significant discussion and
> maybe prototyping of alternatives. It suspect the Reviewer effort will
> end up being many times the effort required to do the actual work
> because of the compatibility and security issues that will need to be
> worked through.
>
> I think you need to add non-discoverability to the list of compatibility
> issues. Do we know for sure that there aren't frameworks and libraries
> that use Class.forName on proxy classes? We've had issues in the past
> with changes in this area.
>
> It's too early to say but it might be that the compatibility risks may
> nudge this one into creating a new API.
>
> -Alan.
>
>
>
Proxies will have to be rethought at some future point - wrt Valhalla.
The current specification says:
> A proxy class implements exactly the interfaces specified at its
creation, in the same order. Invoking getInterfaces on its Class object
will return an array containing the same list of interfaces (in the
order specified at its creation), [...]
In the current design Valhalla will add two interfaces - IdentityObject
and ValueObject (afaik). One of them have to be implemented as well.
Also, because the superclass is java.lang.reflect.Proxy, and that class
has a protected final field, it can currently not implement ValueObject.
An other thing are annotations - currently they are implemented using
Proxies. This implementation detail surfaces when serializing an
annotation. Other implementation strategies are possible - for example
spinning a record at runtime.
But this leads to the question - how can one migrate away from
serialized proxies in a compatible way?
In the end - a lot of stuff in the JDK depends on Proxies, and their
limitations now begins to surface.
A new API may not be a bad idea. :)
- Johannes
More information about the core-libs-dev
mailing list