From d1aee90bc6a21994f9b8e1f8ec5d00f2ccc777d9 Mon Sep 17 00:00:00 2001 From: Greg Hogan Date: Thu, 7 Jul 2016 09:35:29 -0400 Subject: [PATCH] [FLINK-4172] [gelly] Don't proxy a ProxiedObject Retrieve the proxied object and wrap in a new proxy. This closes #2213 --- .../flink/graph/utils/proxy/Delegate.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/flink-libraries/flink-gelly/src/main/java/org/apache/flink/graph/utils/proxy/Delegate.java b/flink-libraries/flink-gelly/src/main/java/org/apache/flink/graph/utils/proxy/Delegate.java index 164125c369147..a2d724dbe0be4 100644 --- a/flink-libraries/flink-gelly/src/main/java/org/apache/flink/graph/utils/proxy/Delegate.java +++ b/flink-libraries/flink-gelly/src/main/java/org/apache/flink/graph/utils/proxy/Delegate.java @@ -30,7 +30,7 @@ * Wraps an object with a proxy delegate whose method handler invokes all * method calls on the wrapped object. This object can be later replaced. * - * @param + * @param the type of the proxied object */ public class Delegate { private X obj; @@ -52,7 +52,7 @@ public Delegate(X obj) { * @param obj delegated object */ public void setObject(X obj) { - this.obj = obj; + this.obj = (obj instanceof ReferentProxy) ? ((ReferentProxy) obj).getProxiedObject() : obj; } /** @@ -70,6 +70,7 @@ public X getProxy() { ProxyFactory factory = new ProxyFactory(); factory.setSuperclass(obj.getClass()); + factory.setInterfaces(new Class[]{ReferentProxy.class}); // create the class and instantiate an instance without calling a constructor Class proxyClass = factory.createClass(new MethodFilter() { @@ -84,12 +85,28 @@ public boolean isHandled(Method method) { ((ProxyObject) proxy).setHandler(new MethodHandler() { @Override public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable { - // method visibility may be restricted - thisMethod.setAccessible(true); - return thisMethod.invoke(obj, args); + if (thisMethod.getName().equals("getProxiedObject")) { + // this method is provided by the ReferentProxy interface + return obj; + } else { + // method visibility may be restricted + thisMethod.setAccessible(true); + return thisMethod.invoke(obj, args); + } } }); return proxy; } + + /** + * This interface provides access via the proxy handler to the original + * object being proxied. This is necessary since we cannot and should not + * create a proxy of a proxy but must instead proxy the original object. + * + * @param the type of the proxied object + */ + protected interface ReferentProxy { + Y getProxiedObject(); + } }