ops4j / peaberry

42 stars 9 forks source link

Equals on service proxy #67

Open mcculls opened 9 years ago

mcculls commented 9 years ago

Originally reported on Google Code with ID 64

When I get a service proxy, equals returns false for every argument.

Foo foo = //injected with guice using service()
foo.equals(foo); //Returns false! I think this method call should return true

Reported by js.cedarsoft on 2011-09-26 12:59:19

mcculls commented 9 years ago
Getting equals right with proxies is a hard problem given that most equals implementations
don't support subclasses. Bloch discusses this in Effective Java, see also http://cwmaier.blogspot.com/2007/07/liskov-substitution-principle-equals.html

At the moment the service proxy just delegates to the actual service implementation
for equals/hashcode, so if your implementation of equals works with subclasses then
you should get the expected result. However if your equals method checks against an
exact class (ie. using getClass() == obj.getClass() rather than instanceof) then you
will get negative results as above.

Alternative approaches/suggestions are welcomed, feel free to attach a patch for the
ImportGlue proxy class.

Reported by mcculls on 2011-09-30 21:12:40

mcculls commented 9 years ago
I don't understand the problem in detail. And I am very sure that it is complicated.

But for me this seems to be obvious:

for
   Foo foo =...

without any equals implementation
   foo.equals(foo)

returns true.
This is the default implementation of equals() and should also work for with proxies...

Every Java developer without deep knowledge of the proxy topic will expect this behavior.
So maybe a workaround could be useful in that case.

Reported by js.cedarsoft on 2011-10-27 10:02:06

mcculls commented 9 years ago
Sure, the issue is that we delegate straight to the underlying object - so if that has
a correct substitutable implementation of equals then that will behave correctly when
proxied. The issue is when the object being proxied uses the default implementation
of equals or a non-substitutable version, that's when you get the spurious result of
!foo.equals(foo).

We should probably do a quick == test before delegating to the proxied object, which
would fix this case.

Reported by mcculls on 2011-10-28 01:08:46

mcculls commented 9 years ago

Reported by mcculls on 2011-10-28 01:15:38

mcculls commented 9 years ago

Reported by mcculls on 2011-10-28 01:15:49

mcculls commented 9 years ago

Reported by mcculls on 2012-08-04 21:48:52