[cdi-dev] calling 'equals' on a proxy?
Mark Struberg
struberg at yahoo.de
Thu Oct 20 00:46:28 EDT 2011
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 at redhat.com>
> To: Arne Limburg <arne.limburg at openknowledge.de>
> Cc: "cdi-dev at lists.jboss.org" <cdi-dev at 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 at lists.jboss.org
> [mailto:cdi-dev-bounces at lists.jboss.org] Im Auftrag von Pete Muir
>> Gesendet: Mittwoch, 19. Oktober 2011 14:03
>> An: Rick Hightower
>> Cc: Stuart Douglas; cdi-dev at 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 at 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 at 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 at redhat.com>
>>>>> To: Mark Struberg <struberg at yahoo.de>
>>>>> Cc: cdi-dev at lists.jboss.org; Stuart Douglas
> <sdouglas at 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 at lists.jboss.org
>>>>>> https://lists.jboss.org/mailman/listinfo/cdi-dev
>>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> cdi-dev mailing list
>>>> cdi-dev at 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 at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/cdi-dev
>>
>> _______________________________________________
>> cdi-dev mailing list
>> cdi-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
>
> _______________________________________________
> cdi-dev mailing list
> cdi-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
More information about the cdi-dev
mailing list