3.63. kink/javahost/JAVA_PROXY

JAVA_PROXY mod provides a way to make a Java dynamic proxies (java.lang.reflect.Proxy).

See the documentation of Proxy class:

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/Proxy.html

3.63.1. JAVA_PROXY.new(Class_loader Intfs $handler)

`new` makes a Java dynamic proxy, whose action is defined by $handler fun.

Preconditions:

• `Class_loader` must be a java val (loader, any type), where `loader` is an instance of java.lang.ClassLoader.

• `Intfs` must be a vec of java vals, object references of which are instances of java.lang.Class.

• The class loader and the class objects must satisfy conditions described in https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/Proxy.html

$handler is invoked when a method of the proxy is invoked. The parameters of $handler are `Method` and `Args`, where:

• `Method` is a java val (method, java.lang.reflect.Method), where `method` is the invoked method.

• `Args` is a vec of java vals, object references of which are arguments passed to the method, or boxing instances of them, and static types of which are the declared types of the parameters of the method.

When $handler terminates throwing a Java exception as described in Java.throw and Java.call_method, invocation of the Java method throws the Java exception.

When $handler terminates returning a thrower val, invocation of the Java method throws the Java exception.

`new` returns a java val (proxy, proxyClass), where `proxy` is the created dynamic proxy, and `proxyClass` is the runtime class of the proxy instance.

If instantiation of a proxy fails with a Java exception, `new` raises a Kink exception, instead of throwing a Java exception.

Example:

:JAVA.require_from('kink/javahost/')
:JAVA_PROXY.require_from('kink/javahost/')
:Runnable_class <- JAVA.class('java.lang.Runnable')
:Cl <- JAVA.wrap(new_val).dynamic_type.call_method('getClassLoader' [])
:Run <- JAVA_PROXY.new(Cl [Runnable_class]){(:Method :Args)
  Method.call_method('getName' []).to_kink_str == 'run' || raise(
    'unknown method {}'.format(Method.repr))
  stdout.print_line('hey')
}.as(Runnable_class)
:Thread <- JAVA.class('java.lang.Thread').new([Run])
Thread.call_method('start' [])
Thread.call_method('join' [])
# Output:
#   hey