Re: proxy an interface and call a default method

2016-06-03 Thread Jochen Theodorou

That looks quite good to me

On 03.06.2016 11:51, Peter Levart wrote:



On 06/02/2016 06:34 PM, fo...@univ-mlv.fr wrote:


So perhaps, instead of providing a Proxy::findSuper method that
returns a pre-bound MH, there could simply be a method like the
following in the Proxy class:

public final Object invokeSuper(Class interfaze, String
methodName, MethodType methodType, Object ... args) { ... }

What do you think?


yes, good idea,
i think it should be static (and takes a Proxy as parameter) to avoid
unwanted overriding.


Something like the following?

http://cr.openjdk.java.net/~plevart/jdk9-dev/Proxy.invokeSuperDefaults/webrev.02/

Usage is even simpler with this API:

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();
 }

 public static void main(String[] args) {

 InvocationHandler h = (proxy, method, params) -> {
 System.out.println("InvocationHandler called for: " + method);
 try {
 return Proxy.invokeSuper(proxy, method, params);
 } catch (InvocationTargetException e) {
 throw e.getCause();
 }
 };

 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();
 }
}


Gives the following output:

InvocationHandler called for: public default void Test$I1.m()
default I1.m() called
InvocationHandler called for: public default void Test$I2.m()
default I2.m() called
InvocationHandler called for: public abstract void Test$I12.m()
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
 at $Proxy2.m(Unknown Source)
 at Test.main(Test.java:49)
Caused by: java.lang.IllegalAccessException: no such method:
Test$I12.m()void/invokeSpecial
 at
java.lang.invoke.MemberName.makeAccessException(java.base@9-internal/MemberName.java:928)
 at
java.lang.invoke.MemberName$Factory.resolveOrFail(java.base@9-internal/MemberName.java:1064)
 at
java.lang.invoke.MethodHandles$Lookup.resolveOrFail(java.base@9-internal/MethodHandles.java:1692)
 at
java.lang.invoke.MethodHandles$Lookup.findSpecial(java.base@9-internal/MethodHandles.java:1150)
 at
java.lang.reflect.Proxy.invokeSuper(java.base@9-internal/Proxy.java:1151)
 at Test.lambda$main$0(Test.java:33)
 ... 2 more
Caused by: java.lang.AbstractMethodError: Test$I12.m()V
 at
java.lang.invoke.MethodHandleNatives.resolve(java.base@9-internal/Native
Method)
 at
java.lang.invoke.MemberName$Factory.resolve(java.base@9-internal/MemberName.java:1036)
 at
java.lang.invoke.MemberName$Factory.resolveOrFail(java.base@9-internal/MemberName.java:1061)
 ... 6 more


...which is expected. You can't call the super abstract method. You have
to resolve the Method object of a particular interface (I1 or I2)
yourself in such case.

I think this is a simple API that everyone could understand.

Regards, Peter


___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: proxy an interface and call a default method

2016-06-03 Thread Peter Levart



On 06/02/2016 06:34 PM, fo...@univ-mlv.fr wrote:


So perhaps, instead of providing a Proxy::findSuper method that
returns a pre-bound MH, there could simply be a method like the
following in the Proxy class:

public final Object invokeSuper(Class interfaze, String
methodName, MethodType methodType, Object ... args) { ... }

What do you think?


yes, good idea,
i think it should be static (and takes a Proxy as parameter) to avoid 
unwanted overriding.


Something like the following?

http://cr.openjdk.java.net/~plevart/jdk9-dev/Proxy.invokeSuperDefaults/webrev.02/

Usage is even simpler with this API:

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();
}

public static void main(String[] args) {

InvocationHandler h = (proxy, method, params) -> {
System.out.println("InvocationHandler called for: " + method);
try {
return Proxy.invokeSuper(proxy, method, params);
} catch (InvocationTargetException e) {
throw e.getCause();
}
};

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();
}
}


Gives the following output:

InvocationHandler called for: public default void Test$I1.m()
default I1.m() called
InvocationHandler called for: public default void Test$I2.m()
default I2.m() called
InvocationHandler called for: public abstract void Test$I12.m()
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
at $Proxy2.m(Unknown Source)
at Test.main(Test.java:49)
Caused by: java.lang.IllegalAccessException: no such method: 
Test$I12.m()void/invokeSpecial
at 
java.lang.invoke.MemberName.makeAccessException(java.base@9-internal/MemberName.java:928)
at 
java.lang.invoke.MemberName$Factory.resolveOrFail(java.base@9-internal/MemberName.java:1064)
at 
java.lang.invoke.MethodHandles$Lookup.resolveOrFail(java.base@9-internal/MethodHandles.java:1692)
at 
java.lang.invoke.MethodHandles$Lookup.findSpecial(java.base@9-internal/MethodHandles.java:1150)
at 
java.lang.reflect.Proxy.invokeSuper(java.base@9-internal/Proxy.java:1151)

at Test.lambda$main$0(Test.java:33)
... 2 more
Caused by: java.lang.AbstractMethodError: Test$I12.m()V
at 
java.lang.invoke.MethodHandleNatives.resolve(java.base@9-internal/Native 
Method)
at 
java.lang.invoke.MemberName$Factory.resolve(java.base@9-internal/MemberName.java:1036)
at 
java.lang.invoke.MemberName$Factory.resolveOrFail(java.base@9-internal/MemberName.java:1061)

... 6 more


...which is expected. You can't call the super abstract method. You have 
to resolve the Method object of a particular interface (I1 or I2) 
yourself in such case.


I think this is a simple API that everyone could understand.

Regards, Peter

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: proxy an interface and call a default method

2016-06-02 Thread forax
- Mail original -

> De: "Peter Levart" 
> À: fo...@univ-mlv.fr
> Cc: "Da Vinci Machine Project" , "jochen
> Theodorou" 
> Envoyé: Jeudi 2 Juin 2016 15:23:44
> Objet: Re: proxy an interface and call a default method

> Hi Remi, Jochen,

> On 06/02/2016 11:15 AM, fo...@univ-mlv.fr wrote:

> > > > The solution could be for Proxy API to provide a MH that was already >
> > > > bound to the Proxy instance. Such pre-bound MH could not be abused
> > > > then.
> > 
> 

> > independently of any security issue, it may be a good idea but doing a
> > partial evaluation on a MH is not cheap.
> 

> I created a prototype for this:

> http://cr.openjdk.java.net/~plevart/jdk9-dev/Proxy.invokeSuperDefaults/webrev.01/

> Example usage is as follows:

> public class Test {

> interface I {
> default void m() {
> System.out.println("default I.m() called");
> }
> }

> public static void main(String[] args) {

> InvocationHandler h = (proxy, method, params) -> {
> System.out.println("InvocationHandler called for: " + method);
> MethodHandle superM = ((Proxy) proxy).findSuper(I.class, "m",
> MethodType.methodType(void.class));
> return superM.invokeWithArguments(params);
> };

> I i = (I) Proxy.newProxyInstance(
> I.class.getClassLoader(), new Class[]{I.class}, h);

> i.m();
> }
> }

> It works, but in order for this to have adequate performance, caching would
> have to be added. But caching a pre-bound MH would require caching on
> per-proxy-instance basis, which would not be very efficient. So perhaps,
> instead of providing a Proxy::findSuper method that returns a pre-bound MH,
> there could simply be a method like the following in the Proxy class:

> public final Object invokeSuper(Class interfaze, String methodName,
> MethodType methodType, Object ... args) { ... }

> What do you think?
yes, good idea, 
i think it should be static (and takes a Proxy as parameter) to avoid unwanted 
overriding. 

> Regards, Peter

Rémi 
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: proxy an interface and call a default method

2016-06-02 Thread Peter Levart

Hi Remi, Jochen,


On 06/02/2016 11:15 AM, fo...@univ-mlv.fr wrote:

>The solution could be for Proxy API to provide a MH that was already
>bound to the Proxy instance. Such pre-bound MH could not be abused then.

independently of any security issue, it may be a good idea but doing a partial 
evaluation on a MH is not cheap.



I created a prototype for this:

http://cr.openjdk.java.net/~plevart/jdk9-dev/Proxy.invokeSuperDefaults/webrev.01/

Example usage is as follows:

public class Test {

interface I {
default void m() {
System.out.println("default I.m() called");
}
}

public static void main(String[] args) {

InvocationHandler h = (proxy, method, params) -> {
System.out.println("InvocationHandler called for: " + method);
MethodHandle superM = ((Proxy) proxy).findSuper(I.class, 
"m", MethodType.methodType(void.class));

return superM.invokeWithArguments(params);
};

I i = (I) Proxy.newProxyInstance(
I.class.getClassLoader(), new Class[]{I.class}, h);

i.m();
}
}


It works, but in order for this to have adequate performance, caching 
would have to be added. But caching a pre-bound MH would require caching 
on per-proxy-instance basis, which would not be very efficient. So 
perhaps, instead of providing a Proxy::findSuper method that returns a 
pre-bound MH, there could simply be a method like the following in the 
Proxy class:


public final Object invokeSuper(Class interfaze, String methodName, 
MethodType methodType, Object ... args) { ... }


What do you think?

Regards, Peter

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: proxy an interface and call a default method

2016-06-02 Thread forax


- Mail original -
> De: "Peter Levart" 
> À: "Remi Forax" , "Da Vinci Machine Project" 
> 
> Cc: "jochen Theodorou" 
> Envoyé: Jeudi 2 Juin 2016 10:26:48
> Objet: Re: proxy an interface and call a default method
> 
> 
> 
> On 05/27/2016 01:40 PM, Remi Forax wrote:
> > I don't see the issue if the lookup object represent the proxy class itself
> > restricted to only access to public methods.
> >
> > Rémi
> 
> I think there could be security issues. For example, let there be an
> interface like:
> 
> public interface Resource {
>  InputStream openStream() throws IOException;
> 
>  default byte[] getContent() throws IOException {
>  try (InputStream is = openStream()) {
>  return is.readAllBytes();
>  }
>  }
> }
> 
> Then there might be an implementation that overrides both methods, like:
> 
> public class SecuredResource implements Resource {
> 
>  @CallerSensitive
>  @Override
>  public InputStream openStream() throws IOException {
>  checkPermission(Reflection.getCallerClass());
>  return openStreamImpl();
>  }
> 
>  @CallerSensitive
>  @Override
>  public byte[] getContent() throws IOException {
>  checkPermission(Reflection.getCallerClass());
>  try (InputStream is = openStreamImpl()) {
>  return is.readAllBytes();
>  }
>  }
> 
>  private InputStream openStreamImpl() throws IOException { ...
>  ...
> }
> 
> 
> If Proxy API allowed access to a MH(invokespecial Resource::getContent),
> then one could abuse such MH to circumvent access check in an instance
> of SecuredResource by making it appear it was invoked from the Resource
> class.
> 
> I think that bytecode verifier does not allow such things and
> SecuredResource can be considered perfectly safe in this respect.

I dont think this code is safe, without any proxy, you can create a 
MethodHandle with findvirtual() on Resource::getContent and bypass the check on 
@CallerSensitive.
I'm not a security guy, but IMO, you can not annotate an overridden method with 
@CallerSensitive without creating a security hole.

> 
> The solution could be for Proxy API to provide a MH that was already
> bound to the Proxy instance. Such pre-bound MH could not be abused then.

independently of any security issue, it may be a good idea but doing a partial 
evaluation on a MH is not cheap.

> 
> Regards, Peter

Rémi

> 
> >
> > - Mail original -
> >> De: "Peter Levart" 
> >> À: "Da Vinci Machine Project" , "jochen
> >> Theodorou" 
> >> Envoyé: Vendredi 27 Mai 2016 12:50:34
> >> Objet: Re: proxy an interface and call a default method
> >>
> >> Hi,
> >>
> >> I think the main problem here is that by providing the InvocationHandler
> >> with a Lookup that could provide "invokespecial" MHs for the proxy
> >> interface(s) could be abused. Anyone can create a Proxy for any public
> >> interface and supply its own InvocationHandler which could be used to
> >> "steal" such Lookup object.
> >>
> >> There would have to be a way to restrict calling interface "super"
> >> methods from InvocationHandler *INSTANCES* that are bound to particular
> >> Proxy instances.
> >>
> >> Hm...
> >>
> >> Regards, Peter
> >>
> >> On 05/26/2016 08:20 AM, Jochen Theodorou wrote:
> >>> Hi all,
> >>>
> >>> I am looking for a solution to the following problem... I have an
> >>> interface and an object that is supposed to serve as implementation,
> >>> but does not implement the interface. n methods of the interface will
> >>> be redirected to the object, but in case of default methods I would
> >>> like to have the implementation provided by the interface. I am
> >>> looking especially for a solution without me generating classes at
> >>> runtime by hand.
> >>>
> >>> Now there are several problems... I seem not to be able to invoke a
> >>> default method by reflection. By MethodHandles I did something like this:
> >>>
>  MethodHandles.Lookup.class.getDeclaredConstructor(Class.class,
>  int.class).
> newInstance(interfaceClass, MethodHandles.Lookup.PRIVATE).
> unreflectSpecial(method, interfaceClass).
> bindTo(receiver);
> >>> where receiver is a dynamic proxy, method the Method of the default
> >>> method, interfaceClass the Class of the interface with the default
> >>> method.
> >>>
> >>> But I am calling a private constructor here, which is bad, plus the
> >>> above procedure does no longer work on JDK9.
> >>>
> >>> So what am I supposed to do? change from a proxy to runtime generated
> >>> classes and hope the best for classloaders and modules not getting in
> >>> my way?
> >>>
> >>> bye Jochen
> >>> ___
> >>> mlvm-dev mailing list
> >>> mlvm-dev@openjdk.java.net
> >>> 

Re: proxy an interface and call a default method

2016-06-02 Thread Peter Levart



On 05/27/2016 01:40 PM, Remi Forax wrote:

I don't see the issue if the lookup object represent the proxy class itself 
restricted to only access to public methods.

Rémi


I think there could be security issues. For example, let there be an 
interface like:


public interface Resource {
InputStream openStream() throws IOException;

default byte[] getContent() throws IOException {
try (InputStream is = openStream()) {
return is.readAllBytes();
}
}
}

Then there might be an implementation that overrides both methods, like:

public class SecuredResource implements Resource {

@CallerSensitive
@Override
public InputStream openStream() throws IOException {
checkPermission(Reflection.getCallerClass());
return openStreamImpl();
}

@CallerSensitive
@Override
public byte[] getContent() throws IOException {
checkPermission(Reflection.getCallerClass());
try (InputStream is = openStreamImpl()) {
return is.readAllBytes();
}
}

private InputStream openStreamImpl() throws IOException { ...
...
}


If Proxy API allowed access to a MH(invokespecial Resource::getContent), 
then one could abuse such MH to circumvent access check in an instance 
of SecuredResource by making it appear it was invoked from the Resource 
class.


I think that bytecode verifier does not allow such things and 
SecuredResource can be considered perfectly safe in this respect.


The solution could be for Proxy API to provide a MH that was already 
bound to the Proxy instance. Such pre-bound MH could not be abused then.


Regards, Peter



- Mail original -

De: "Peter Levart" 
À: "Da Vinci Machine Project" , "jochen Theodorou" 

Envoyé: Vendredi 27 Mai 2016 12:50:34
Objet: Re: proxy an interface and call a default method

Hi,

I think the main problem here is that by providing the InvocationHandler
with a Lookup that could provide "invokespecial" MHs for the proxy
interface(s) could be abused. Anyone can create a Proxy for any public
interface and supply its own InvocationHandler which could be used to
"steal" such Lookup object.

There would have to be a way to restrict calling interface "super"
methods from InvocationHandler *INSTANCES* that are bound to particular
Proxy instances.

Hm...

Regards, Peter

On 05/26/2016 08:20 AM, Jochen Theodorou wrote:

Hi all,

I am looking for a solution to the following problem... I have an
interface and an object that is supposed to serve as implementation,
but does not implement the interface. n methods of the interface will
be redirected to the object, but in case of default methods I would
like to have the implementation provided by the interface. I am
looking especially for a solution without me generating classes at
runtime by hand.

Now there are several problems... I seem not to be able to invoke a
default method by reflection. By MethodHandles I did something like this:


MethodHandles.Lookup.class.getDeclaredConstructor(Class.class,
int.class).
   newInstance(interfaceClass, MethodHandles.Lookup.PRIVATE).
   unreflectSpecial(method, interfaceClass).
   bindTo(receiver);

where receiver is a dynamic proxy, method the Method of the default
method, interfaceClass the Class of the interface with the default
method.

But I am calling a private constructor here, which is bad, plus the
above procedure does no longer work on JDK9.

So what am I supposed to do? change from a proxy to runtime generated
classes and hope the best for classloaders and modules not getting in
my way?

bye Jochen
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev



___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: proxy an interface and call a default method

2016-05-27 Thread Remi Forax
I don't see the issue if the lookup object represent the proxy class itself 
restricted to only access to public methods.

Rémi 

- Mail original -
> De: "Peter Levart" 
> À: "Da Vinci Machine Project" , "jochen Theodorou" 
> 
> Envoyé: Vendredi 27 Mai 2016 12:50:34
> Objet: Re: proxy an interface and call a default method
> 
> Hi,
> 
> I think the main problem here is that by providing the InvocationHandler
> with a Lookup that could provide "invokespecial" MHs for the proxy
> interface(s) could be abused. Anyone can create a Proxy for any public
> interface and supply its own InvocationHandler which could be used to
> "steal" such Lookup object.
> 
> There would have to be a way to restrict calling interface "super"
> methods from InvocationHandler *INSTANCES* that are bound to particular
> Proxy instances.
> 
> Hm...
> 
> Regards, Peter
> 
> On 05/26/2016 08:20 AM, Jochen Theodorou wrote:
> > Hi all,
> >
> > I am looking for a solution to the following problem... I have an
> > interface and an object that is supposed to serve as implementation,
> > but does not implement the interface. n methods of the interface will
> > be redirected to the object, but in case of default methods I would
> > like to have the implementation provided by the interface. I am
> > looking especially for a solution without me generating classes at
> > runtime by hand.
> >
> > Now there are several problems... I seem not to be able to invoke a
> > default method by reflection. By MethodHandles I did something like this:
> >
> >> MethodHandles.Lookup.class.getDeclaredConstructor(Class.class,
> >> int.class).
> >>   newInstance(interfaceClass, MethodHandles.Lookup.PRIVATE).
> >>   unreflectSpecial(method, interfaceClass).
> >>   bindTo(receiver);
> >
> > where receiver is a dynamic proxy, method the Method of the default
> > method, interfaceClass the Class of the interface with the default
> > method.
> >
> > But I am calling a private constructor here, which is bad, plus the
> > above procedure does no longer work on JDK9.
> >
> > So what am I supposed to do? change from a proxy to runtime generated
> > classes and hope the best for classloaders and modules not getting in
> > my way?
> >
> > bye Jochen
> > ___
> > mlvm-dev mailing list
> > mlvm-dev@openjdk.java.net
> > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
> 
> ___
> mlvm-dev mailing list
> mlvm-dev@openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
> 
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: proxy an interface and call a default method

2016-05-27 Thread Peter Levart

Hi,

I think the main problem here is that by providing the InvocationHandler 
with a Lookup that could provide "invokespecial" MHs for the proxy 
interface(s) could be abused. Anyone can create a Proxy for any public 
interface and supply its own InvocationHandler which could be used to 
"steal" such Lookup object.


There would have to be a way to restrict calling interface "super" 
methods from InvocationHandler *INSTANCES* that are bound to particular 
Proxy instances.


Hm...

Regards, Peter

On 05/26/2016 08:20 AM, Jochen Theodorou wrote:

Hi all,

I am looking for a solution to the following problem... I have an 
interface and an object that is supposed to serve as implementation, 
but does not implement the interface. n methods of the interface will 
be redirected to the object, but in case of default methods I would 
like to have the implementation provided by the interface. I am 
looking especially for a solution without me generating classes at 
runtime by hand.


Now there are several problems... I seem not to be able to invoke a 
default method by reflection. By MethodHandles I did something like this:


MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, 
int.class).

  newInstance(interfaceClass, MethodHandles.Lookup.PRIVATE).
  unreflectSpecial(method, interfaceClass).
  bindTo(receiver);


where receiver is a dynamic proxy, method the Method of the default 
method, interfaceClass the Class of the interface with the default 
method.


But I am calling a private constructor here, which is bad, plus the 
above procedure does no longer work on JDK9.


So what am I supposed to do? change from a proxy to runtime generated 
classes and hope the best for classloaders and modules not getting in 
my way?


bye Jochen
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev