You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Mark Thomas <ma...@apache.org> on 2018/02/15 21:35:08 UTC

Session attribute listeners inconsistency

Hi,

I've been looking at:
https://bz.apache.org/bugzilla/show_bug.cgi?id=43866

In short, this bug is looking for a way to tell Tomcat an object set as
a session attribute has been mutated and therefore needs to be
replicated. The 'standard' way to do this is by calling setAttribute()
but this triggers listeners.

While thinking about ways to implement an option for this, I stumbled
across the following. When setAttribute() is called with an object that
is already in the session then StandardSession.setAttribute() calls
listeners inconsistently.

Any HttpSessionBindingListener will not be called because the old and
new values are the same (see line 1426 in trunk).

Any HttpSessionAttributeListener will be called since the old and new
values are not compared (see line 1466 in trunk).

I can find no reason in the spec for this difference.

I think these should be consistent. In the case where setAttribute() is
called with the same value as is already bound either both types of
listener should be called or neither.

The question is what to do about it. I think we need an option on the
Manager to control this. For now, call it
notifyListenersOnUnchangedValue (suggestions for better names welcome).
Clearly there need to be two options, "true" and "false". Does there
need to be a third "legacy" (again suggestions for better names please)
that essentially retains the current inconsistent behaviour.

Or do we have two options. One for HttpSessionBindingListener and one
for HttpSessionAttributeListener?

Thoughts? Comments?

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: Session attribute listeners inconsistency

Posted by Mark Thomas <ma...@apache.org>.
On 16/02/18 03:49, Konstantin Kolinko wrote:
> 2018-02-16 0:35 GMT+03:00 Mark Thomas <ma...@apache.org>:
>> Hi,
>>
>> I've been looking at:
>> https://bz.apache.org/bugzilla/show_bug.cgi?id=43866
>>
>> In short, this bug is looking for a way to tell Tomcat an object set as
>> a session attribute has been mutated and therefore needs to be
>> replicated. The 'standard' way to do this is by calling setAttribute()
>> but this triggers listeners.
>>
>> While thinking about ways to implement an option for this, I stumbled
>> across the following. When setAttribute() is called with an object that
>> is already in the session then StandardSession.setAttribute() calls
>> listeners inconsistently.
>>
>> Any HttpSessionBindingListener will not be called because the old and
>> new values are the same (see line 1426 in trunk).
>>
>> Any HttpSessionAttributeListener will be called since the old and new
>> values are not compared (see line 1466 in trunk).
>>
>> I can find no reason in the spec for this difference.
>>
>> I think these should be consistent. In the case where setAttribute() is
>> called with the same value as is already bound either both types of
>> listener should be called or neither.
>>
> 
> I disagree.
> 
> Javadoc (Servlet 4.0):
> https://javaee.github.io/javaee-spec/javadocs/javax/servlet/http/HttpSessionAttributeListener.html
> https://javaee.github.io/javaee-spec/javadocs/javax/servlet/http/HttpSessionBindingListener.html
> 
> 1) HttpSessionAttributeListener is "@since Servlet 2.3",
> HttpSessionBindingListener does not have "@since" clause.
> Thus it looks that the attribute listener is a newer and improved API.
> 
> 2) The "binding" listener is not a listener (it is not in the list of
> listeners, it cannot be declared in web.xml). It is an interface
> implemented by the value itself.
> 
> 3) I think that once value.valueUnbound() is called, the expectation
> is that the value is never going to be used again and can be
> destroyed. I think it is not safe to call valueBound() on it.
> 
> Thus the reason for (value != oldValue) check (line 1426 in trunk).
> 
> 
> 4) A HttpSessionAttributeListener has three methods as opposed to two
> in binding listener.
> 
> Its attributeReplaced() method can be coded to handle the (value ==
> oldValue) case.

Thanks for disagreeing. Having someone put the opposing case helps
clarify my own thoughts. Keep in mind that I am trying to address BZ
43866 at the same time.

What bugs me about this is the inconsistency.

The language for HttpSessionBindingListener, valueUnbound() and the
phrase "unbound" is pretty much identical with the language for
HttpSessionAttributeListener, attributeReplaced() and "replaced".

Both valueUnbound() and attributeReplaced() have enough information to
handle the value = oldValue case.

What I really don't see is the justification (apart from history) for
handling them differently.

I think this is another instance of something to get clarified by the
Servlet EG (or whatever it ends up being called) once the process moves
to Eclipse.

Meanwhile, I'd like to suggest the following. Two new Manager options to
individually control the calling of these listeners when the value and
the old value are the same.

Something like:

notifyBindingListenerOnUnchangedValue (defaults to false)
notifyAttributeListenerOnUnchangedValue (defaults to true)

This would leave the current behaviour unchanged, make it easy to change
the default of the 'Servlet EG' clarifies the expected behaviour and
provide a work-around for the problem described in BZ 43866.

Thoughts?

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: Session attribute listeners inconsistency

Posted by Konstantin Kolinko <kn...@gmail.com>.
2018-02-16 0:35 GMT+03:00 Mark Thomas <ma...@apache.org>:
> Hi,
>
> I've been looking at:
> https://bz.apache.org/bugzilla/show_bug.cgi?id=43866
>
> In short, this bug is looking for a way to tell Tomcat an object set as
> a session attribute has been mutated and therefore needs to be
> replicated. The 'standard' way to do this is by calling setAttribute()
> but this triggers listeners.
>
> While thinking about ways to implement an option for this, I stumbled
> across the following. When setAttribute() is called with an object that
> is already in the session then StandardSession.setAttribute() calls
> listeners inconsistently.
>
> Any HttpSessionBindingListener will not be called because the old and
> new values are the same (see line 1426 in trunk).
>
> Any HttpSessionAttributeListener will be called since the old and new
> values are not compared (see line 1466 in trunk).
>
> I can find no reason in the spec for this difference.
>
> I think these should be consistent. In the case where setAttribute() is
> called with the same value as is already bound either both types of
> listener should be called or neither.
>

I disagree.

Javadoc (Servlet 4.0):
https://javaee.github.io/javaee-spec/javadocs/javax/servlet/http/HttpSessionAttributeListener.html
https://javaee.github.io/javaee-spec/javadocs/javax/servlet/http/HttpSessionBindingListener.html

1) HttpSessionAttributeListener is "@since Servlet 2.3",
HttpSessionBindingListener does not have "@since" clause.
Thus it looks that the attribute listener is a newer and improved API.

2) The "binding" listener is not a listener (it is not in the list of
listeners, it cannot be declared in web.xml). It is an interface
implemented by the value itself.

3) I think that once value.valueUnbound() is called, the expectation
is that the value is never going to be used again and can be
destroyed. I think it is not safe to call valueBound() on it.

Thus the reason for (value != oldValue) check (line 1426 in trunk).


4) A HttpSessionAttributeListener has three methods as opposed to two
in binding listener.

Its attributeReplaced() method can be coded to handle the (value ==
oldValue) case.


Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org