Oki, I think the outcome and problematic is now pretty much clear, right?
I think we at least need to add some wording to make people aware of the problematic,
isn't?
LieGrue,
strub
----- Original Message -----
From: Stuart Douglas <sdouglas(a)redhat.com>
To: Arne Limburg <arne.limburg(a)openknowledge.de>
Cc: "cdi-dev(a)lists.jboss.org" <cdi-dev(a)lists.jboss.org>
Sent: Wednesday, October 19, 2011 11:50 PM
Subject: Re: [cdi-dev] calling 'equals' on a proxy?
On 20/10/2011, at 1:13 AM, Arne Limburg wrote:
> Hi,
>
> What never will work is putting a contextual reference into a HashSet (or
HashMap as key) and assuming it is a contextual instance. And maybe this should
be made clear in the spec.
Considering that this is the main purpose of the equals() / hashCode() methods,
I can't see what we gain by specifing them. A mutable hashCode is not really
of any use to anyone, and I don't think that forcing people to implement
their equals methods in a special way to satisfy CDI is a good idea either.
Inexperienced java programmers already seem to have enough trouble implementing
equals() properly as it is.
I am not adverse to adding some kind of static method to unwrap proxies, this
can also be useful for reading private fields from contextual references.
Have their actually been any requests for this to be specified? I can't help
thinking that if you are using contextual instances as hash map keys you are
doing something wrong.
Stuart
>
> However the contract of java.lang.Object#hashCode() does allow that
hashCode() changes its return value: The same value only must be returned
"provided no information used in equals(Object) comparisons on the object
is modified". Since a change of the underlying contextual instance would
modify the information used in equals(Object), it would be perfectly valid, that
the returned hash code would change.
>
> So if we specify the behavior of equals and hashCode to delegate to the
contextual instance the only thing we need to be aware of is the symmetric
behavior of equals, so whatever we specify, the following must be true:
> For any x and y, if x.equals(y) is true y.equals(x) must be true as well.
> And this makes things wired, because of the following case:
> Let x be the current contextual instance of the contextual reference y,
then
> y.equals(x) would be true, assuming the call to equals is delegated
> y.equals(y) would be true, assuming the call to equals is delegated and the
parameter is unproxied
> x.equals(x) would be true, assuming the developer correctly implemented
equals. Nothing to do here for CDI since no proxy involved.
> x.equals(y) is the wired case since we are not able to unproxy y here. So
for this case it depends on the implementation of equals, if the result is true.
If equals only uses public methods of y then it should work otherwise it likely
will return false. But according to the definition of java.lang.Object#equals
(and the defined symmetry) if this returns false, y.equals(x) has to return
false, too.
> So the only way how this could be achieved, would be to modify the case
where y.equals(x) is handled: If we would return x.equals(y) for that case, we
would delegate the problem to the user implementing equals correct (with no
field-access). So either we have to specify it that way (and can specify
hashCode() to be delegated to the contextual instance) or we should leave it
unspecified.
>
> In addition we should provide a static method
CDI.getContextualInstance(Object), so that users can handle that case where they
want to put objects into HashSets or HashMaps. This method could then be used to
correctly implement equals on contextual instances like:
> public boolean equals(Object object) {
> object = CDI.getContextualInstance(object);
> //implement equals using field access.
> }
> Wdyt?
>
> Regards,
> Arne
>
> -----Ursprüngliche Nachricht-----
> Von: cdi-dev-bounces(a)lists.jboss.org
[mailto:cdi-dev-bounces@lists.jboss.org] Im Auftrag von Pete Muir
> Gesendet: Mittwoch, 19. Oktober 2011 14:03
> An: Rick Hightower
> Cc: Stuart Douglas; cdi-dev(a)lists.jboss.org
> Betreff: Re: [cdi-dev] calling 'equals' on a proxy?
>
> 100% agreed ;-)
>
> However, my issue is that not around the "will work in 99% of
cases", it's around that pesky remaining 1%. If it simply didn't
work in those 1% of cases, then I would be much more amenable. However, what we
actually have is it *actively and knowingly breaching* the rules laid down by
another specification, on which we build, in that 1% of cases, which I think it
is a totally different situation. And this is not just any spec, it's the
Java Language Spec, on which *everything* builds. Remaining consistent with the
language is of utmost importance IMO, and users will not forgive us for
breaking the rules they use every day.
>
> On 18 Oct 2011, at 22:08, Rick Hightower wrote:
>
>> I would argue (and probably lose) that something that worked in 99% of
cases as expected would be better than something that never does.
>>
>> I will reread Stuarts arguments, but it seems to me that we can specify
how equals works with client proxies.
>>
>> On Tue, Oct 18, 2011 at 1:56 PM, Pete Muir <pmuir(a)redhat.com>
wrote:
>>
>> On 18 Oct 2011, at 21:42, Rick Hightower wrote:
>>
>>> Currently the docs say this.... 5.4.2.
>>>
>>> .Behavior of all methods declared by java.lang.Object, except for
>>> toString(), is undefined for a client proxy .Portable applications
>>> should not invoke any method declared by java.lang.Object, except
>>> for toString(), on a client proxy
>>>
>>> I so don't agree with what is in the spec. now on this subject.
>>> (Realizing that it is a work in progress...)
>>
>> Not really, this is unchanged since 1.0. We don't currently have
plans to change this.
>>
>>>
>>> I think we should change this and call the underlying
implementation for these methods.
>>> Also equals and hashCode should work by unpacking and comparing the
contextual instance.
>>
>> Please take a look at Stuart's follow up to Mark's email, he
has investigated the options thoroughly, and found there is no solution that can
correctly obey the rules for equals. For this reason it's better to keep it
unspecified, as it warns people not to rely on this behavior.
>>
>>>
>>> Off topic....
>>>
>>> It would be nice if there was a utility API that implementations
had
>>> to implement that had these methods
>>>
>>>
>>> isProxy (lets you know if an object is a client proxy)
>>> getUnproxiedVersion (gives you the underlying unproxied version of
>>> the object)
>>>
>>>
>>> (It may exist already.)
>>
>> I don't believe there is, so file a CDI issue and we can discuss /
add it. It should be relatively trivial (require any client proxy to implement
an interface e.g. ClientProxy and provide a method on getUnderlying() or
similar).
>>
>>>
>>>
>>> On Tue, Oct 18, 2011 at 10:17 AM, Mark Struberg
<struberg(a)yahoo.de> wrote:
>>> Hi folks!
>>>
>>> There is a problem still in the chain which is a bit more trickier.
It's about equals() on contextual references.
>>>
>>> If the 'other' instance which gets compared with is a proxy
as well, then we would first need to 'unpack' it and pass the underlying
contextual instance into the comparison implementation. Otherwise accessing
private fields from the 'other' will actually only hit the proxy, and
not the 'real' target.
>>>
>>> But otherwise it should work fine.
>>>
>>>
>>> Wdyt?
>>>
>>> 1.) Should we specify this?
>>
>> See Stuart's response, I would be very leery of requiring behavior
which broke the fundamental contract of equals(). If we can't fully support
the correct behavior, it's better to leave it unportable.
>>
>>>
>>> 2.) What is the expected behaviour?
>>>
>>> 3.) Do we like to specify equals() for beans at all?
>>> 4.) Is there some established behaviour in other frameworks which
heavily uses proxies?
>>
>> Not AFAIK. We played around for ages with this in Seam and Weld, and
have something that gives you 99% correct behavior, but there are still edge
cases.
>>
>>> 5.) Should we at least specify that 'non portable behaviour
results'?
>>
>> We do, see Rick's reference above.
>>
>>>
>>>
>>> LieGrue,
>>> strub
>>>
>>>
>>>
>>> ----- Original Message -----
>>>> From: Pete Muir <pmuir(a)redhat.com>
>>>> To: Mark Struberg <struberg(a)yahoo.de>
>>>> Cc: cdi-dev(a)lists.jboss.org; Stuart Douglas
<sdouglas(a)redhat.com>
>>>> Sent: Monday, March 14, 2011 12:52 PM
>>>> Subject: Re: [cdi-dev] calling 'equals' on a proxy?
>>>>
>>>> Stuart, you had this one worked out right? I believe the spec
says
>>>> the behaviour is unspecified.
>>>>
>>>> On 7 Mar 2011, at 15:52, Mark Struberg wrote:
>>>>
>>>>> Hi Pete, others!
>>>>>
>>>>> Do you remember our discussion about what should happen if
>>>>> equals() gets
>>>> called on a proxy?
>>>>>
>>>>> Should it route to the equals method of the currently
proxied instance?
>>>>>
>>>>> LieGrue,
>>>>> strub
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> cdi-dev mailing list
>>>>> cdi-dev(a)lists.jboss.org
>>>>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>>>>
>>>
>>>
>>> _______________________________________________
>>> cdi-dev mailing list
>>> cdi-dev(a)lists.jboss.org
>>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>>>
>>>
>>>
>>> --
>>> Rick Hightower
>>> (415) 968-9037
>>> Profile
>>>
>>
>>
>>
>>
>> --
>> Rick Hightower
>> (415) 968-9037
>> Profile
>>
>
>
> _______________________________________________
> cdi-dev mailing list
> cdi-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> _______________________________________________
> cdi-dev mailing list
> cdi-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/cdi-dev
_______________________________________________
cdi-dev mailing list
cdi-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/cdi-dev