2009/6/18 Regis <[email protected]> > Jim Yu wrote: > >> Hi all, >> >> There is an interesting edge case in HashMap. If we use a proxy object as >> the key to put something into HashMap, we will fail to retrieve the value >> by >> using that key. But RI works well for this case. Here is a test case below >> to present the problem. I found the root cause of the failure for our >> HashMap is that proxyInstance.equals(proxyInstance) returns false which >> sounds strange but appears work correctly as both Harmony and RI behave >> so. >> > > It's very interesting behaviors, seems like RI did it intended, are there > any cases we need proxyInstance.equals(proxyInstance) return false?
I think it is reasonable to return false here since spec mentioned for proxy instance that "An invocation of the hashCode, equals, or toString methods declared in java.lang.Object on a proxy instance will be encoded and dispatched to the invocation handler's invoke method" So the meaning of equals method seems has been changed by the invoke here: ) > > > I suspect RI has made some special approaches to match the key when the >> key >> is a proxy object. So I would be inclined to follow RI's behavior in this >> case. Any thoughts here? >> > > I think if proxyInstance.equals(proxyInstance) return false is reasonable, > we should do some tricks to make HashMap work with Proxy. And does Proxy > object work well with other collections which used equals to retrieve object > from collection? > Agree. I have made a patch to do the trick so as to follow RI's behavior. > > >> I have raised a JIRA at >> https://issues.apache.org/jira/browse/HARMONY-6237for this issue. >> >> >> public interface MockInterface { >> public String mockMethod(); >> } >> >> public class MockClass implements MockInterface { >> public String mockMethod() { >> return "This is a mock class."; >> } >> } >> >> import java.lang.reflect.InvocationHandler; >> import java.lang.reflect.Method; >> import java.lang.reflect.Proxy; >> import java.util.HashMap; >> import java.util.Map; >> >> public class TestProxy implements InvocationHandler { >> >> Object obj; >> >> public TestProxy(Object o) { >> obj = o; >> } >> >> public Object invoke(Object proxy, Method m, Object[] args) >> throws Throwable { >> >> Object result = null; >> >> try { >> >> result = m.invoke(obj, args); >> >> } catch (Exception e) { >> e.printStackTrace(); >> } finally { >> } >> return result; >> } >> >> public static void main(String[] argv) throws Exception { >> >> MockInterface proxyInstance = (MockInterface) >> Proxy.newProxyInstance( >> MockInterface.class.getClassLoader(), >> new Class[] { MockInterface.class }, new TestProxy( >> new MockClass())); >> >> Map hm = new HashMap(); >> >> hm.put(proxyInstance, "Value"); >> >> Object o = hm.get(proxyInstance); >> >> System.out.println("Value got for proxy object key:" + o); >> >> System.out.println(proxyInstance.equals(proxyInstance)); >> >> } >> } >> >> Output >> Harmony: >> Value got for proxy object key:null >> false >> >> RI: >> Value got for proxy object key:Value >> false >> >> > > -- > Best Regards, > Regis. > -- Best Regards, Jim, Jun Jie Yu
