Equality problem with an Object and its dynamic proxy.

I met with this problem while working on something else. In a hashmap I was using an object and its proxy as the key. What I saw was that, even if I put both the object and proxy, the hashmap will take only one object. I was confused for some time and then I realized that internally, when HashMap invokes ‘equals’ method, the InvocationHandler of the proxy delegates that method as well to the actual object, so that will always return true. Hence, I will never be able to have both as keys. To make it clear

MyObject obj ; //say it is some valid object implementing MyIntf interface.ProxyOfMyObject proxy ; //say this is the valid proxy of obj

obj.equals(proxy) returns false. That is understood.

proxy.equals(obj) will return true. This happens because the invocation handler will call the obj.equals(obj) internally.

To fix this, I created one more interface ‘ForEqualsMyIntf’ that extends ‘MyIntf’. This interface doesn’t have any methods. I will create the proxy using this ‘ForEqualsMyIntf’ interface, rather then the usual ‘MyIntf’. And in the ‘inovke’ method of Invocation Handler, I will check if the object passed in ‘equals’ method is instanseof ‘ForEqualsMyIntf’. So, when proxy.equals(obj) is invoked, since the obj is not implemeting ‘ForEqualsMyIntf’, it will return false. I am giving the sample code for this invocation handler below.

class MyInvocationHandler implements InvocationHandler {
  private MyObject obj;
public MyInvocationHandler(MyObject obj) {
  this.obj = obj;
  }

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  if(method.getName().equals("equals")) {
  Object other = args[0];
  if(other instanceof ForEqualsMyIntf) {
  if(other == proxy) {
  return new Boolean(true);
  } else {
  return new Boolean(false);
  }
  } else {
  return new Boolean(false);
  }
  }
  Object result = method.invoke(obj, args);
  if(method.getName().equals("toString")) {
  return "Proxy - " + result;
  }
  return result;
  }
  }

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: