15
15
**************************************************************************** */
16
16
package org .jpype .proxy ;
17
17
18
+ import java .lang .invoke .MethodHandles ;
18
19
import java .lang .reflect .InvocationHandler ;
19
20
import java .lang .reflect .Method ;
20
21
import java .lang .reflect .Proxy ;
@@ -35,6 +36,7 @@ public class JPypeProxy implements InvocationHandler
35
36
public long cleanup ;
36
37
Class <?>[] interfaces ;
37
38
ClassLoader cl = ClassLoader .getSystemClassLoader ();
39
+ public static Object missing = new Object ();
38
40
39
41
public static JPypeProxy newProxy (JPypeContext context ,
40
42
long instance ,
@@ -69,35 +71,46 @@ public Object newInstance()
69
71
public Object invoke (Object proxy , Method method , Object [] args )
70
72
throws Throwable
71
73
{
72
- try
73
- {
74
- // context.incrementProxy();
75
- if (context .isShutdown ())
76
- throw new RuntimeException ("Proxy called during shutdown" );
77
74
78
- // We can save a lot of effort on the C++ side by doing all the
79
- // type lookup work here.
80
- TypeManager typeManager = context .getTypeManager ();
81
- long returnType ;
82
- long [] parameterTypes ;
83
- synchronized (typeManager )
75
+ if (context .isShutdown ())
76
+ throw new RuntimeException ("Proxy called during shutdown" );
77
+
78
+ // We can save a lot of effort on the C++ side by doing all the
79
+ // type lookup work here.
80
+ TypeManager typeManager = context .getTypeManager ();
81
+ long returnType ;
82
+ long [] parameterTypes ;
83
+ synchronized (typeManager )
84
+ {
85
+ returnType = typeManager .findClass (method .getReturnType ());
86
+ Class <?>[] types = method .getParameterTypes ();
87
+ parameterTypes = new long [types .length ];
88
+ for (int i = 0 ; i < types .length ; ++i )
84
89
{
85
- returnType = typeManager .findClass (method .getReturnType ());
86
- Class <?>[] types = method .getParameterTypes ();
87
- parameterTypes = new long [types .length ];
88
- for (int i = 0 ; i < types .length ; ++i )
89
- {
90
- parameterTypes [i ] = typeManager .findClass (types [i ]);
91
- }
90
+ parameterTypes [i ] = typeManager .findClass (types [i ]);
92
91
}
92
+ }
93
93
94
- return hostInvoke (context .getContext (), method .getName (), instance , returnType , parameterTypes , args );
95
- } finally
94
+ // Check first to see if Python has implementated it
95
+ Object result = hostInvoke (context .getContext (), method .getName (), instance , returnType , parameterTypes , args , missing );
96
+
97
+ // If we get a good result than return it
98
+ if (result != missing )
99
+ return result ;
100
+
101
+ // If it is a default method in the interface then we have to invoke it using special reflection.
102
+ if (method .isDefault ())
96
103
{
97
- // context.decrementProxy();
104
+ return MethodHandles .lookup ()
105
+ .unreflectSpecial (method , method .getDeclaringClass ())
106
+ .bindTo (proxy )
107
+ .invokeWithArguments (args );
98
108
}
109
+
110
+ // Else throw... (this should never happen as proxies are checked when created.)
111
+ throw new NoSuchMethodError (method .getName ());
99
112
}
100
113
101
114
private static native Object hostInvoke (long context , String name , long pyObject ,
102
- long returnType , long [] argsTypes , Object [] args );
115
+ long returnType , long [] argsTypes , Object [] args , Object bad );
103
116
}
0 commit comments