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