If I'm correct, we're not suppose to investigate and discuss the
implementation details of RI.
Sounds it is violate our independent implemenation's goal.

Best Regards
Sean, Xiao Xia Qiu




2009/7/8 oleg babul <oleg...@gmail.com>:
> To find entry in the HashMap RI performs:
> 1) Check that entry.hash==key.hashCode() (entry - hash map entry)
> 2) Check that entry.key == key or (key!=null && key.eqauls(entry.key))
>
> hm.get(proxyInstance); returns !=null object because entry.key == key
> in the 2) and equals doesn't perform.
>
> Oleg
>
> On Wed, Jul 8, 2009 at 8:34 AM, Regis<xu.re...@gmail.com> wrote:
>> Jim Yu wrote:
>>>
>>> 2009/6/18 Regis <xu.re...@gmail.com>
>>>
>>>> Jim Yu wrote:
>>>>
>>>>> 2009/6/18 Regis <xu.re...@gmail.com>
>>>>>
>>>>>  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.
>>>>>
>>>> The patch looks good for me, applied at r786015, please verify.
>>>
>>>
>>> Verified at r786379.  Thanks, Regis.
>>>
>>>>
>>>>
>>>>>
>>>>>>  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,
>>>> Regis.
>>>>
>>>
>>>
>>>
>>
>> I found this patch involve serious performance regression. Because
>> Proxy.isProxyClass() synchronized on a instance "proxyCache", which is a
>> static field of Proxy, so all HashMap.get() will contend for this lock. So
>> is there other way to test whether a class is Proxy class or
>> Proxy.isProxyClass() could avoid to use lock of static field?
>>
>>
>> --
>> Best Regards,
>> Regis.
>>
>

Reply via email to