RFR: 8159746: (proxy) Support for default methods [v3]

Peter Levart plevart at openjdk.java.net
Wed Sep 30 21:34:33 UTC 2020


On Wed, 30 Sep 2020 19:14:28 GMT, Mandy Chung <mchung at openjdk.org> wrote:

>> This proposes a new static `Proxy::invokeDefaultMethod` method to invoke
>> the given default method on the given proxy instance.
>> 
>> The implementation looks up a method handle for `invokespecial` instruction
>> as if called from with the proxy class as the caller, equivalent to calling
>> `X.super::m` where `X` is a proxy interface of the proxy class and
>> `X.super::m` will resolve to the specified default method.
>> 
>> The implementation will call a private static `proxyClassLookup(Lookup caller)`
>> method of the proxy class to obtain its private Lookup.  This private method
>> in the proxy class only allows a caller Lookup on java.lang.reflect.Proxy class
>> with full privilege access to use, or else `IllegalAccessException` will be
>> thrown.
>> 
>> This patch also proposes to define a proxy class in an unnamed module to
>> a dynamic module to strengthen encapsulation such that they are only
>> unconditionally exported from a named module but not open for deep reflective
>> access.  This only applies to the case if all the proxy interfaces are public
>> and in a package that is exported or open.
>> 
>> One dynamic module is created for each class loader that defines proxies.
>> The change changes the dynamic module to contain another package (same
>> name as the module) that is unconditionally exported and is opened to
>> `java.base` only.
>> 
>> There is no change to the package and module of the proxy class for
>> the following cases:
>> 
>> - if at least one proxy interface is non-public, then the proxy class is defined
>>   in the package and module of the non-public interfaces
>> - if at least one proxy is in a package that is non-exported and non-open,
>>   if all proxy interfaces are public, then the proxy class is defined in
>>   a non-exported, non-open package of a dynamic module.
>> 
>> The spec change is that a proxy class used to be defined in an unnamed
>> module, i.e. in a exported and open package, is defined in an unconditionally
>> exported but non-open package.  Programs that assume it to be open unconditionally
>> will be affected and cannot do deep reflection on such proxy classes.
>> 
>> Peter Levart contributed an initial prototype [1] (thanks Peter).  I think
>> the exceptions could be simplified as more checking should be done prior to
>> the invocation of the method handle like checking the types of the arguments
>> with the method type.  This approach avoids defining a public API
>> `protected Proxy::$$proxyClassLookup$$` method.  Instead it defines a
>> private static method that is restricted for Proxy class to use (by
>> taking a caller parameter to ensure it's a private lookup on Proxy class).
>> 
>> javadoc/specdiff:
>> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8159746/api/
>> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8159746/specdiff/
>> 
>> [1]  http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-June/041629.html
>
> Mandy Chung has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev
> excludes the unrelated changes brought in by the merge/rebase. The pull request contains 17 additional commits since
> the last revision:
>  - Merge branch 'master' of https://github.com/openjdk/jdk into proxy-default-method
>  - minor tweak to the spec wording and impl
>  - Merge pull request #1 from plevart/proxy-default-method-performance
>    
>    Performance improvements for Proxy::invokeDefaultMethod
>  - Add test case for InvocationTargetException
>  - Revert the thrown exceptions spec to be consistent with Method::invoke
>  - Speed up Proxy.invokeDefaultMethod while also changing its spec regarding exception types thrown
>  - Merge branch 'master' of https://github.com/openjdk/jdk into proxy-default-method
>  - fix regression tests due to proxy name change
>  - minor bug fix
>  - Merge branch 'master' of https://github.com/openjdk/jdk into proxy-default-method
>  - ... and 7 more: https://git.openjdk.java.net/jdk/compare/3112f91d...db6cfc13

src/java.base/share/classes/java/lang/reflect/Proxy.java line 1256:

> 1254:      *             {@code args} elements cannot be assigned to the corresponding
> 1255:      *             method parameter type.</li>
> 1256:      *         </ul>

After trying it in practice, I see your words are correct. 1st unboxing happens and then assignment.

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

PR: https://git.openjdk.java.net/jdk/pull/313


More information about the core-libs-dev mailing list