Hi everyone,

I am glad this was discussed on the list again.
I just wanted to throw out there, as a library developer and
end user, I now have had to reproduce this hack in no fewer
than four different projects for various reasons.

It is even worse because it means that my library cannot run
under a SecurityManager.  While this isn't a problem for me
personally it does limit the utility of any libraries I might produce.

It really is a glaring missing API and if it does not make Java 9
I can't imagine I will be the only person that is extremely disappointed.

Thanks,
Steven

> On Jun 6, 2016, at 1:58 PM, Mandy Chung <mandy.ch...@oracle.com> wrote:
> 
> Hi Peter,
> 
> Thanks for the proposal. This feature has been lacking.  When this subject 
> was brought, I also have similiar thought to provide a way in Proxy class for 
> InvocationHandler to invoke a default method (but of course no time to put 
> into it).
> 
> I appreciate your contribution and good work.  I support to add this feature 
> in a future release.
> 
> I personally don’t feel comfortable to absorb this small API targetting for 
> JDK 9 (since I don’t have the cycle to shepherd this in the next few months). 
> I may be overly conversative but I won’t take security assessment lightly.  
> Maybe someone else is able to help you move this forward before I am 
> available.
> 
> Mandy
> 
>> On Jun 3, 2016, at 7:58 AM, Peter Levart <peter.lev...@gmail.com> wrote:
>> 
>> Hi,
>> 
>> Since Java SE 8 introduced default methods in interfaces there was a 
>> question what to do with java.lang.reflect.Proxy API. Nothing was done to 
>> the API at that time, so the default behavior is to proxy default methods 
>> too. InvocationHandler gets invoked for default methods, but it has not 
>> provision to forward such calls to the default implementations in the 
>> interfaces.
>> 
>> I propose a simple API addition that allows calling super default methods in 
>> proxy instances:
>> 
>> http://cr.openjdk.java.net/~plevart/jdk9-dev/Proxy.invokeSuperDefaults/webrev.02/
>> 
>> With this addition one can simply decide in the InvocationHandler what to do 
>> with invocations to default methods and can forward such invocation to the 
>> default implementation:
>> 
>> public class Test {
>> 
>>   interface I1 {
>>       default void m() {
>>           System.out.println("  default I1.m() called");
>>       }
>>   }
>> 
>>   interface I2 {
>>       default void m() {
>>           System.out.println("  default I2.m() called");
>>       }
>>   }
>> 
>>   interface I12 extends I1, I2 {
>>       @Override
>>       void m();
>> 
>>       default int sum(int a, int b) {
>>           return a + b;
>>       }
>> 
>>       default Object[] concat(Object first, Object... rest) {
>>           Object[] result = new Object[1 + rest.length];
>>           result[0] = first;
>>           System.arraycopy(rest, 0, result, 1, rest.length);
>>           return result;
>>       }
>>   }
>> 
>>   public static void main(String[] args) {
>> 
>>       InvocationHandler h = (proxy, method, params) -> {
>>           System.out.println("\nInvocationHandler called for: " + method +
>>                              " with parameters: " + Arrays.toString(params));
>>           if (method.isDefault()) {
>>               try {
>>                   return Proxy.invokeSuper(proxy, method, params);
>>               } catch (InvocationTargetException e) {
>>                   throw e.getCause();
>>               }
>>           } else {
>>               switch (method.getName()) {
>>                   case "m":
>>                       System.out.println("  abstract I12.m(): called");
>>                       return null;
>>                   default:
>>                       throw new UnsupportedOperationException(
>>                           "Unsupported method: " + method);
>>               }
>>           }
>>       };
>> 
>>       I1 i1 = (I1) Proxy.newProxyInstance(
>>           I1.class.getClassLoader(), new Class<?>[]{I1.class}, h);
>>       i1.m();
>> 
>>       I2 i2 = (I2) Proxy.newProxyInstance(
>>           I2.class.getClassLoader(), new Class<?>[]{I2.class}, h);
>>       i2.m();
>> 
>>       I12 i12 = (I12) Proxy.newProxyInstance(
>>           I12.class.getClassLoader(), new Class<?>[]{I12.class}, h);
>>       i12.m();
>> 
>>       System.out.println("  1 + 2 = " + i12.sum(1, 2));
>>       System.out.println("  [1] concat [2, 3, 4] = " +
>>                          Arrays.toString(i12.concat(1, 2, 3, 4)));
>>   }
>> }
>> 
>> 
>> I know FC date is over, but this is really a small change and I have heard 
>> several people that such feature is missing from the Proxy API.
>> 
>> I'm prepared to create jtreg tests covering the specification if this 
>> proposal is accepted.
>> 
>> Regards, Peter
>> 
>> 
>> 
> 

Reply via email to