You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Huxing Zhang <hu...@apache.org> on 2018/07/25 15:28:40 UTC

Duplicate registration of ServletContextListerner

Hi,

Recently I am working on implementing a feature that can automatically
register a ServletContextListerner instance, say A, to servletContext
programmatically during startup.

I use ServletContainerInitializer and call the
servletContext.addListener() method. This is fine for most of the
cases. But if user has specified A in web.xml, it turns that A will be
registered twice, which will lead to undesired behavior.

My expected behavior will be registering A only once regardless of
user specified A in web.xml or not.

I can achieve this by specifying A in web-fragment.xml, since it will
get merged into web.xml whenever A is defined in web.xml or not, which
means duplicates can be removed.

I am wondering why we can not achieve this using programatic API.

I've checked servlet 4.0/3.1 spec, in 4.4.3.1 "void addListener(String
className)", it says:

If the class with the given name implements a listener interface whose
invocation order corresponds to the declaration order, that is, if it
implements javax.servlet.ServletRequestListener,
javax.servlet.ServletContextListener or
javax.servlet.http.HttpSessionListener, then the new listener will be
added to the end of the ordered list of listeners of that interface.

It looks tomcat's behavior is spec-compliant.

My idea is if I can get all the existing listeners from
servletContext, then I can decide whether to add A or not.

But I can't find that kind of API from servletContext.

I also noticed that there are getServletRegistrations() and
getFilterRegistrations() in servletContext, why can't we have API like
getListeners()?


-- 
Best Regards!
Huxing

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


Re: Duplicate registration of ServletContextListerner

Posted by Mark Thomas <ma...@apache.org>.
On July 27, 2018 1:53:40 AM UTC, Huxing Zhang <hu...@apache.org> wrote:

<snip/>

>What if the listener isn't in control, e.g. the listener class is in a
>3rd party library.
>In some cases, a listener may not allow multiple instances, if the
>second listener start, it will fail.

Raise a bug against the 3rd party library?

>Is it possible to add a new method in ServletContext called
>getListeners(), and let the user to decide whether to add it or not?

Yes, but we can't do that. We can't change the Servlet API. I suggest opening an issue against the Servlet API to make a change in the next version.

Mark

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


Re: Duplicate registration of ServletContextListerner

Posted by Huxing Zhang <hu...@apache.org>.
On Fri, Jul 27, 2018 at 3:02 AM, Mark Thomas <ma...@apache.org> wrote:
> On July 26, 2018 6:08:09 PM UTC, Christopher Schultz <ch...@christopherschultz.net> wrote:
>>-----BEGIN PGP SIGNED MESSAGE-----
>>Hash: SHA256
>>
>>Mark,
>>
>>On 7/26/18 5:21 AM, Mark Thomas wrote:
>>> On 26/07/2018 04:29, Huxing Zhang wrote:
>>>> Hi,
>>>>
>>>> On Thu, Jul 26, 2018 at 2:57 AM, Christopher Schultz
>>>> <ch...@christopherschultz.net> wrote:
>>>
>>> <sniup/>
>>>
>>>>> Can you think of a use-case where addListener() shouldn't
>>>>> automatically perform de-duplication?
>>>>
>>>> No, I can't think of that case.
>>>
>>> Yes, although only for the programmatic case.
>>>
>>> Multiple instances of the same listener configured differently.
>>> E.g. I can see a use for a simple
>>> javax.servlet.http.HttpSessionAttributeListener that might be
>>> added multiple times in a single app to define different actions
>>> for different attributes. Yes it could be implemented as a single
>>> listener but I can certainly see some scenarios where adding the
>>> same listener multiple times would give cleaner / simpler code.
>>>
>>>> If there is really a case, I think we can use
>>>> javax.servlet.ServletContext#setInitParameter to control that
>>>> behavior. For example, use a initialization parameter named
>>>> DEDUPLICATE_LISTENERS, if set to true, any further registration
>>>> will be de-duplicated. This parameter is better to be a per call
>>>> parameter rather than a global parameter, because it might be
>>>> updated from multiple place.
>>>
>>> Configuration at that point may cause problems. I'm not sure that
>>> the ServletContext would be available early enough. It would be
>>> better as an attribute on the Context. That would also be
>>> consistent with other such configuration parameters.
>>>
>>>>> I'm thinking that Tomcat should simply take a call to
>>>>> addListener() and ignore any registrations after the first one.
>>>>> >
>>>> Yes, I think it is important to have consistent behavior between
>>>> web-fragement/@WebListener and programmatic API.
>>>
>>> -1. That behaviour is not consistent with the Servlet spec. The
>>> spec expects multiple instances. It isn't explicit but it is very
>>> strongly implied both by the wording used and the complete absence
>>> of any indication of how de-duplication should be performed.


>>>
>>> Further, de-duplication is not that simple. Some users will want
>>> the fist listener added. Some the most recent. There are probably
>>> other complications I haven't thought of.
>>>
>>>>> Would that make sense? Would it violate any spec-defined
>>>>> behavior?
>>>>
>>>> I can't find any spec describing how to handle the duplications
>>>> on that part, so I guess it is safe to do so. :)
>>>
>>> There are lots of behaviours the spec doesn't define. That doesn't
>>> mean implementing them is spec compliant. Exactly the opposite in
>>> fact.
>>>
>>>> Maybe we can improve spec as well.
>>>
>>> Hopefully, with the move to Eclipse, the various clarifications
>>> that have been open for a number of years will now start to be
>>> addressed. I'd recommend adding this to them
>>>
>>> https://github.com/eclipse-ee4j/servlet-api/issues
>>
>>FWIW, I was not suggesting that all types of listeners be
>>deduplicated. I was instead focusing on ServletContextListeners, since
>>that was Huxing's use-case. I should have been more clear in my
>>proposal
>>.
>>
>>On the other hand, listeners cannot be registered with any information
>>other than their class. Therefore I'm not sure that adding the same
>>class multiple times to the event-notification list would accomplish
>>anything useful.
>>
>>Hmm... I just realized that the programmatic interface allows
>>listeners to be added by /instance/ and not just by class (name), so
>>theoretically one could instantiate two instances of a single class,
>>each with different behaviors (configured via constructors or other
>>mutators) and they would therefore be "distinct".
>>
>>Rather than deduplicating by class, perhaps we could deduplicate by
>>using .equals(). In that case, if you had something like this:
>>
>>class MyListener extends HttpSessionAttributeListener {
>>  MyListener(String attributeName) { ... }
>>}
>>
>>Then registering one instance of this class with attribute name "foo"
>>versus "bar" could work as long as MyListener can prove that the two
>>instances are distinct (e.g. by comparing their "attribute names").
>>
>>- -chris
>>-----BEGIN PGP SIGNATURE-----
>>Comment: GPGTools - http://gpgtools.org
>>Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
>>
>>iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAltaDggACgkQHPApP6U8
>>pFhg2w//ZuhPBU6LzWYJksEKh/HcPLaXZODjqCUA8xl8EBEXyIbqu6Bafl2QlKxT
>>J2yprTHefOKAI7TOY8yPWtdiwCFCgI1yMOD6HDp4J5MhWziKV+0bbOjrrG1Vuia1
>>i1Sspvue3XyWVcpMF40/LGRC6BDlNcN+XqCfwfODXD5JLKxpaFZIKSLNDb2cttEH
>>7rJhQHwqxqGj5OUxlA5y/TRBzTKihH789PG0XKukXeYLzW64KhzB9kVIYJTgVmT4
>>rWOMUmMRBB2VVi4ovmmRy/O4Y8t0VXZvdQVb9EwVKlSKvnoO6tVLgsVGAKG966EB
>>SdTEBeUIkwPdYYbv2lL7OgpHAOUAmwBtwZhs8UFUCIU1nCi2FUS8kqbMNIlDk431
>>J8Ad9PQ3jh/A01m3XScKL+/4qVx550lxQEk1Zd7wsajgtbJPZo0ZOA+Iy1x5huDx
>>IbudWubPMJudxJLvjb8kb2aDYamvMtmQF7Xb3R1aWOGezCHuB39f05Nurz8c4ZKt
>>YrrZHjeqcYnPgpdvWBaobXZt0q3y8cbQnoovdpLiHg5l7Lb4NY9LS87KAamj+T4q
>>ZwJVHjE7ULlLRlgdAnDu0Z0CZBdMW/Xe0ZmnE+hW6jSmsB/vDdePZTLk/g/1iddr
>>vR2MKJ56L9xMgbYWPl144XkZN7p8GDuzHWrqZQt/FLwyCXos5L4=
>>=Ygg3
>>-----END PGP SIGNATURE-----
>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
>>For additional commands, e-mail: dev-help@tomcat.apache.org
>
> Probably easier to have the listener handle multiple registrations itself for that use case.
>
> I.e. given that listeners are started serially in a single thread, check/set a servlet context attribute when the listener starts.
>
> That should work for any container without having to depend on container specific  behaviour.

What if the listener isn't in control, e.g. the listener class is in a
3rd party library.
In some cases, a listener may not allow multiple instances, if the
second listener start, it will fail.

Is it possible to add a new method in ServletContext called
getListeners(), and let the user to decide whether to add it or not?
>
> Mark
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>



-- 
Best Regards!
Huxing

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


Re: Duplicate registration of ServletContextListerner

Posted by Mark Thomas <ma...@apache.org>.
On July 26, 2018 6:08:09 PM UTC, Christopher Schultz <ch...@christopherschultz.net> wrote:
>-----BEGIN PGP SIGNED MESSAGE-----
>Hash: SHA256
>
>Mark,
>
>On 7/26/18 5:21 AM, Mark Thomas wrote:
>> On 26/07/2018 04:29, Huxing Zhang wrote:
>>> Hi,
>>> 
>>> On Thu, Jul 26, 2018 at 2:57 AM, Christopher Schultz 
>>> <ch...@christopherschultz.net> wrote:
>> 
>> <sniup/>
>> 
>>>> Can you think of a use-case where addListener() shouldn't 
>>>> automatically perform de-duplication?
>>> 
>>> No, I can't think of that case.
>> 
>> Yes, although only for the programmatic case.
>> 
>> Multiple instances of the same listener configured differently.
>> E.g. I can see a use for a simple 
>> javax.servlet.http.HttpSessionAttributeListener that might be
>> added multiple times in a single app to define different actions
>> for different attributes. Yes it could be implemented as a single
>> listener but I can certainly see some scenarios where adding the
>> same listener multiple times would give cleaner / simpler code.
>> 
>>> If there is really a case, I think we can use 
>>> javax.servlet.ServletContext#setInitParameter to control that 
>>> behavior. For example, use a initialization parameter named 
>>> DEDUPLICATE_LISTENERS, if set to true, any further registration
>>> will be de-duplicated. This parameter is better to be a per call
>>> parameter rather than a global parameter, because it might be
>>> updated from multiple place.
>> 
>> Configuration at that point may cause problems. I'm not sure that
>> the ServletContext would be available early enough. It would be
>> better as an attribute on the Context. That would also be
>> consistent with other such configuration parameters.
>> 
>>>> I'm thinking that Tomcat should simply take a call to
>>>> addListener() and ignore any registrations after the first one.
>>>> >
>>> Yes, I think it is important to have consistent behavior between 
>>> web-fragement/@WebListener and programmatic API.
>> 
>> -1. That behaviour is not consistent with the Servlet spec. The
>> spec expects multiple instances. It isn't explicit but it is very
>> strongly implied both by the wording used and the complete absence
>> of any indication of how de-duplication should be performed.
>> 
>> Further, de-duplication is not that simple. Some users will want
>> the fist listener added. Some the most recent. There are probably
>> other complications I haven't thought of.
>> 
>>>> Would that make sense? Would it violate any spec-defined
>>>> behavior?
>>> 
>>> I can't find any spec describing how to handle the duplications
>>> on that part, so I guess it is safe to do so. :)
>> 
>> There are lots of behaviours the spec doesn't define. That doesn't
>> mean implementing them is spec compliant. Exactly the opposite in
>> fact.
>> 
>>> Maybe we can improve spec as well.
>> 
>> Hopefully, with the move to Eclipse, the various clarifications
>> that have been open for a number of years will now start to be
>> addressed. I'd recommend adding this to them
>> 
>> https://github.com/eclipse-ee4j/servlet-api/issues
>
>FWIW, I was not suggesting that all types of listeners be
>deduplicated. I was instead focusing on ServletContextListeners, since
>that was Huxing's use-case. I should have been more clear in my
>proposal
>.
>
>On the other hand, listeners cannot be registered with any information
>other than their class. Therefore I'm not sure that adding the same
>class multiple times to the event-notification list would accomplish
>anything useful.
>
>Hmm... I just realized that the programmatic interface allows
>listeners to be added by /instance/ and not just by class (name), so
>theoretically one could instantiate two instances of a single class,
>each with different behaviors (configured via constructors or other
>mutators) and they would therefore be "distinct".
>
>Rather than deduplicating by class, perhaps we could deduplicate by
>using .equals(). In that case, if you had something like this:
>
>class MyListener extends HttpSessionAttributeListener {
>  MyListener(String attributeName) { ... }
>}
>
>Then registering one instance of this class with attribute name "foo"
>versus "bar" could work as long as MyListener can prove that the two
>instances are distinct (e.g. by comparing their "attribute names").
>
>- -chris
>-----BEGIN PGP SIGNATURE-----
>Comment: GPGTools - http://gpgtools.org
>Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
>
>iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAltaDggACgkQHPApP6U8
>pFhg2w//ZuhPBU6LzWYJksEKh/HcPLaXZODjqCUA8xl8EBEXyIbqu6Bafl2QlKxT
>J2yprTHefOKAI7TOY8yPWtdiwCFCgI1yMOD6HDp4J5MhWziKV+0bbOjrrG1Vuia1
>i1Sspvue3XyWVcpMF40/LGRC6BDlNcN+XqCfwfODXD5JLKxpaFZIKSLNDb2cttEH
>7rJhQHwqxqGj5OUxlA5y/TRBzTKihH789PG0XKukXeYLzW64KhzB9kVIYJTgVmT4
>rWOMUmMRBB2VVi4ovmmRy/O4Y8t0VXZvdQVb9EwVKlSKvnoO6tVLgsVGAKG966EB
>SdTEBeUIkwPdYYbv2lL7OgpHAOUAmwBtwZhs8UFUCIU1nCi2FUS8kqbMNIlDk431
>J8Ad9PQ3jh/A01m3XScKL+/4qVx550lxQEk1Zd7wsajgtbJPZo0ZOA+Iy1x5huDx
>IbudWubPMJudxJLvjb8kb2aDYamvMtmQF7Xb3R1aWOGezCHuB39f05Nurz8c4ZKt
>YrrZHjeqcYnPgpdvWBaobXZt0q3y8cbQnoovdpLiHg5l7Lb4NY9LS87KAamj+T4q
>ZwJVHjE7ULlLRlgdAnDu0Z0CZBdMW/Xe0ZmnE+hW6jSmsB/vDdePZTLk/g/1iddr
>vR2MKJ56L9xMgbYWPl144XkZN7p8GDuzHWrqZQt/FLwyCXos5L4=
>=Ygg3
>-----END PGP SIGNATURE-----
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
>For additional commands, e-mail: dev-help@tomcat.apache.org

Probably easier to have the listener handle multiple registrations itself for that use case.

I.e. given that listeners are started serially in a single thread, check/set a servlet context attribute when the listener starts.

That should work for any container without having to depend on container specific  behaviour.

Mark

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


Re: Duplicate registration of ServletContextListerner

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Mark,

On 7/26/18 5:21 AM, Mark Thomas wrote:
> On 26/07/2018 04:29, Huxing Zhang wrote:
>> Hi,
>> 
>> On Thu, Jul 26, 2018 at 2:57 AM, Christopher Schultz 
>> <ch...@christopherschultz.net> wrote:
> 
> <sniup/>
> 
>>> Can you think of a use-case where addListener() shouldn't 
>>> automatically perform de-duplication?
>> 
>> No, I can't think of that case.
> 
> Yes, although only for the programmatic case.
> 
> Multiple instances of the same listener configured differently.
> E.g. I can see a use for a simple 
> javax.servlet.http.HttpSessionAttributeListener that might be
> added multiple times in a single app to define different actions
> for different attributes. Yes it could be implemented as a single
> listener but I can certainly see some scenarios where adding the
> same listener multiple times would give cleaner / simpler code.
> 
>> If there is really a case, I think we can use 
>> javax.servlet.ServletContext#setInitParameter to control that 
>> behavior. For example, use a initialization parameter named 
>> DEDUPLICATE_LISTENERS, if set to true, any further registration
>> will be de-duplicated. This parameter is better to be a per call
>> parameter rather than a global parameter, because it might be
>> updated from multiple place.
> 
> Configuration at that point may cause problems. I'm not sure that
> the ServletContext would be available early enough. It would be
> better as an attribute on the Context. That would also be
> consistent with other such configuration parameters.
> 
>>> I'm thinking that Tomcat should simply take a call to
>>> addListener() and ignore any registrations after the first one.
>>> >
>> Yes, I think it is important to have consistent behavior between 
>> web-fragement/@WebListener and programmatic API.
> 
> -1. That behaviour is not consistent with the Servlet spec. The
> spec expects multiple instances. It isn't explicit but it is very
> strongly implied both by the wording used and the complete absence
> of any indication of how de-duplication should be performed.
> 
> Further, de-duplication is not that simple. Some users will want
> the fist listener added. Some the most recent. There are probably
> other complications I haven't thought of.
> 
>>> Would that make sense? Would it violate any spec-defined
>>> behavior?
>> 
>> I can't find any spec describing how to handle the duplications
>> on that part, so I guess it is safe to do so. :)
> 
> There are lots of behaviours the spec doesn't define. That doesn't
> mean implementing them is spec compliant. Exactly the opposite in
> fact.
> 
>> Maybe we can improve spec as well.
> 
> Hopefully, with the move to Eclipse, the various clarifications
> that have been open for a number of years will now start to be
> addressed. I'd recommend adding this to them
> 
> https://github.com/eclipse-ee4j/servlet-api/issues

FWIW, I was not suggesting that all types of listeners be
deduplicated. I was instead focusing on ServletContextListeners, since
that was Huxing's use-case. I should have been more clear in my proposal
.

On the other hand, listeners cannot be registered with any information
other than their class. Therefore I'm not sure that adding the same
class multiple times to the event-notification list would accomplish
anything useful.

Hmm... I just realized that the programmatic interface allows
listeners to be added by /instance/ and not just by class (name), so
theoretically one could instantiate two instances of a single class,
each with different behaviors (configured via constructors or other
mutators) and they would therefore be "distinct".

Rather than deduplicating by class, perhaps we could deduplicate by
using .equals(). In that case, if you had something like this:

class MyListener extends HttpSessionAttributeListener {
  MyListener(String attributeName) { ... }
}

Then registering one instance of this class with attribute name "foo"
versus "bar" could work as long as MyListener can prove that the two
instances are distinct (e.g. by comparing their "attribute names").

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAltaDggACgkQHPApP6U8
pFhg2w//ZuhPBU6LzWYJksEKh/HcPLaXZODjqCUA8xl8EBEXyIbqu6Bafl2QlKxT
J2yprTHefOKAI7TOY8yPWtdiwCFCgI1yMOD6HDp4J5MhWziKV+0bbOjrrG1Vuia1
i1Sspvue3XyWVcpMF40/LGRC6BDlNcN+XqCfwfODXD5JLKxpaFZIKSLNDb2cttEH
7rJhQHwqxqGj5OUxlA5y/TRBzTKihH789PG0XKukXeYLzW64KhzB9kVIYJTgVmT4
rWOMUmMRBB2VVi4ovmmRy/O4Y8t0VXZvdQVb9EwVKlSKvnoO6tVLgsVGAKG966EB
SdTEBeUIkwPdYYbv2lL7OgpHAOUAmwBtwZhs8UFUCIU1nCi2FUS8kqbMNIlDk431
J8Ad9PQ3jh/A01m3XScKL+/4qVx550lxQEk1Zd7wsajgtbJPZo0ZOA+Iy1x5huDx
IbudWubPMJudxJLvjb8kb2aDYamvMtmQF7Xb3R1aWOGezCHuB39f05Nurz8c4ZKt
YrrZHjeqcYnPgpdvWBaobXZt0q3y8cbQnoovdpLiHg5l7Lb4NY9LS87KAamj+T4q
ZwJVHjE7ULlLRlgdAnDu0Z0CZBdMW/Xe0ZmnE+hW6jSmsB/vDdePZTLk/g/1iddr
vR2MKJ56L9xMgbYWPl144XkZN7p8GDuzHWrqZQt/FLwyCXos5L4=
=Ygg3
-----END PGP SIGNATURE-----

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


Re: Duplicate registration of ServletContextListerner

Posted by Mark Thomas <ma...@apache.org>.
On 26/07/2018 04:29, Huxing Zhang wrote:
> Hi,
> 
> On Thu, Jul 26, 2018 at 2:57 AM, Christopher Schultz
> <ch...@christopherschultz.net> wrote:

<sniup/>

>> Can you think of a use-case where addListener() shouldn't
>> automatically perform de-duplication?
> 
> No, I can't think of that case.

Yes, although only for the programmatic case.

Multiple instances of the same listener configured differently. E.g. I 
can see a use for a simple 
javax.servlet.http.HttpSessionAttributeListener that might be added 
multiple times in a single app to define different actions for different 
attributes. Yes it could be implemented as a single listener but I can 
certainly see some scenarios where adding the same listener multiple 
times would give cleaner / simpler code.

> If there is really a case, I think we can use
> javax.servlet.ServletContext#setInitParameter to control that
> behavior.
> For example, use a initialization parameter named
> DEDUPLICATE_LISTENERS, if set to true, any further registration will
> be de-duplicated.
> This parameter is better to be a per call parameter rather than a
> global parameter, because it might be updated from multiple place.

Configuration at that point may cause problems. I'm not sure that the 
ServletContext would be available early enough. It would be better as an 
attribute on the Context. That would also be consistent with other such 
configuration parameters.

>> I'm thinking that Tomcat should
>> simply take a call to addListener() and ignore any registrations after
>> the first one. >
> Yes, I think it is important to have consistent behavior between
> web-fragement/@WebListener and programmatic API.

-1. That behaviour is not consistent with the Servlet spec. The spec 
expects multiple instances. It isn't explicit but it is very strongly 
implied both by the wording used and the complete absence of any 
indication of how de-duplication should be performed.

Further, de-duplication is not that simple. Some users will want the 
fist listener added. Some the most recent. There are probably other 
complications I haven't thought of.

>> Would that make sense? Would it violate any spec-defined behavior?
> 
> I can't find any spec describing how to handle the duplications on
> that part, so I guess it is safe to do so. :)

There are lots of behaviours the spec doesn't define. That doesn't mean 
implementing them is spec compliant. Exactly the opposite in fact.

> Maybe we can improve spec as well.

Hopefully, with the move to Eclipse, the various clarifications that 
have been open for a number of years will now start to be addressed. I'd 
recommend adding this to them

https://github.com/eclipse-ee4j/servlet-api/issues

Mark

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


Re: Duplicate registration of ServletContextListerner

Posted by Huxing Zhang <hu...@apache.org>.
Hi,

On Thu, Jul 26, 2018 at 2:57 AM, Christopher Schultz
<ch...@christopherschultz.net> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> Huxing,
>
> On 7/25/18 11:28 AM, Huxing Zhang wrote:
>> Hi,
>>
>> Recently I am working on implementing a feature that can
>> automatically register a ServletContextListerner instance, say A,
>> to servletContext programmatically during startup.
>>
>> I use ServletContainerInitializer and call the
>> servletContext.addListener() method. This is fine for most of the
>> cases. But if user has specified A in web.xml, it turns that A will
>> be registered twice, which will lead to undesired behavior.
>>
>> My expected behavior will be registering A only once regardless of
>> user specified A in web.xml or not.
>>
>> I can achieve this by specifying A in web-fragment.xml, since it
>> will get merged into web.xml whenever A is defined in web.xml or
>> not, which means duplicates can be removed.
>>
>> I am wondering why we can not achieve this using programatic API.
>>
>> I've checked servlet 4.0/3.1 spec, in 4.4.3.1 "void
>> addListener(String className)", it says:
>>
>> If the class with the given name implements a listener interface
>> whose invocation order corresponds to the declaration order, that
>> is, if it implements javax.servlet.ServletRequestListener,
>> javax.servlet.ServletContextListener or
>> javax.servlet.http.HttpSessionListener, then the new listener will
>> be added to the end of the ordered list of listeners of that
>> interface.
>>
>> It looks tomcat's behavior is spec-compliant.
>>
>> My idea is if I can get all the existing listeners from
>> servletContext, then I can decide whether to add A or not.
>>
>> But I can't find that kind of API from servletContext.
>>
>> I also noticed that there are getServletRegistrations() and
>> getFilterRegistrations() in servletContext, why can't we have API
>> like getListeners()?
>
> Can you think of a use-case where addListener() shouldn't
> automatically perform de-duplication?

No, I can't think of that case.

If there is really a case, I think we can use
javax.servlet.ServletContext#setInitParameter to control that
behavior.
For example, use a initialization parameter named
DEDUPLICATE_LISTENERS, if set to true, any further registration will
be de-duplicated.
This parameter is better to be a per call parameter rather than a
global parameter, because it might be updated from multiple place.

Overall, I don't  think it is necessary to have unless there is a case.

> I'm thinking that Tomcat should
> simply take a call to addListener() and ignore any registrations after
> the first one.

Yes, I think it is important to have consistent behavior between
web-fragement/@WebListener and programmatic API.

>
> Would that make sense? Would it violate any spec-defined behavior?

I can't find any spec describing how to handle the duplications on
that part, so I guess it is safe to do so. :)

Maybe we can improve spec as well.

>
> - -chris
> -----BEGIN PGP SIGNATURE-----
> Comment: GPGTools - http://gpgtools.org
> Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
>
> iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAltYyDIACgkQHPApP6U8
> pFhSmA//We21JrL+KwpbPrNgicIM0T77/WFMQyNoaFrW0+QdJ96CUAWYr6NKn17t
> 0Y0mk9WpRDSIsknpXPTYfisO1RllO7Mde1KuGH6EUMZyYWr84E9YhqBVyOHG48if
> Y/COneCHK3Gs7QlywgRhyKDZFogDFS/X5zW+AGctFIdcdgBu0z8U85a/wlPLUTuk
> XA00qPLrIWSXerB97nsqcdreh7Qs2Uyx3Eye74JE4RwzRYkGVYrMuPpPQwudbAUF
> f2fgAHC5lrJBGLK4yiFce53KcwTzeyBM2yskux/1y02NUyHIASpjV8DqADthV61o
> SOFgG25PJChShsLQipjhcNQtqiluP4FNo1sN78ieMABfOm1zlIh4T4/4M8VD0MqP
> qdoXgqC8vEsCiGUY7rqQKIRTAe6Hpf2yz6Oygwhfk+6z2CpJ4RQfsAFMVJMf2KOM
> wjb6akXnrEzxPG6UEVxtep2cLLVraHlbjDHzNqMrecBC2EYHU/Ovh+gpsHXtJG8v
> +Koh9HR2Ps5h92PI5ND39JsD1KyNhO+zayYD/a+I9ryrQEKV584JyU6q3vyWIwXk
> m8eDlYo0ChCeiGwQ22bAOsdKYTJHruGPEg92VbbDipPLJ+8uzAbtEAlXmiGYkv2B
> Q3EtprVkD1sI88v/iRU8QZg7ux5ebKDHGIk1f33BP3AYUWnwcyY=
> =jKMW
> -----END PGP SIGNATURE-----
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>



-- 
Best Regards!
Huxing

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


Re: Duplicate registration of ServletContextListerner

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Huxing,

On 7/25/18 11:28 AM, Huxing Zhang wrote:
> Hi,
> 
> Recently I am working on implementing a feature that can
> automatically register a ServletContextListerner instance, say A,
> to servletContext programmatically during startup.
> 
> I use ServletContainerInitializer and call the 
> servletContext.addListener() method. This is fine for most of the 
> cases. But if user has specified A in web.xml, it turns that A will
> be registered twice, which will lead to undesired behavior.
> 
> My expected behavior will be registering A only once regardless of 
> user specified A in web.xml or not.
> 
> I can achieve this by specifying A in web-fragment.xml, since it
> will get merged into web.xml whenever A is defined in web.xml or
> not, which means duplicates can be removed.
> 
> I am wondering why we can not achieve this using programatic API.
> 
> I've checked servlet 4.0/3.1 spec, in 4.4.3.1 "void
> addListener(String className)", it says:
> 
> If the class with the given name implements a listener interface
> whose invocation order corresponds to the declaration order, that
> is, if it implements javax.servlet.ServletRequestListener, 
> javax.servlet.ServletContextListener or 
> javax.servlet.http.HttpSessionListener, then the new listener will
> be added to the end of the ordered list of listeners of that
> interface.
> 
> It looks tomcat's behavior is spec-compliant.
> 
> My idea is if I can get all the existing listeners from 
> servletContext, then I can decide whether to add A or not.
> 
> But I can't find that kind of API from servletContext.
> 
> I also noticed that there are getServletRegistrations() and 
> getFilterRegistrations() in servletContext, why can't we have API
> like getListeners()?

Can you think of a use-case where addListener() shouldn't
automatically perform de-duplication? I'm thinking that Tomcat should
simply take a call to addListener() and ignore any registrations after
the first one.

Would that make sense? Would it violate any spec-defined behavior?

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAltYyDIACgkQHPApP6U8
pFhSmA//We21JrL+KwpbPrNgicIM0T77/WFMQyNoaFrW0+QdJ96CUAWYr6NKn17t
0Y0mk9WpRDSIsknpXPTYfisO1RllO7Mde1KuGH6EUMZyYWr84E9YhqBVyOHG48if
Y/COneCHK3Gs7QlywgRhyKDZFogDFS/X5zW+AGctFIdcdgBu0z8U85a/wlPLUTuk
XA00qPLrIWSXerB97nsqcdreh7Qs2Uyx3Eye74JE4RwzRYkGVYrMuPpPQwudbAUF
f2fgAHC5lrJBGLK4yiFce53KcwTzeyBM2yskux/1y02NUyHIASpjV8DqADthV61o
SOFgG25PJChShsLQipjhcNQtqiluP4FNo1sN78ieMABfOm1zlIh4T4/4M8VD0MqP
qdoXgqC8vEsCiGUY7rqQKIRTAe6Hpf2yz6Oygwhfk+6z2CpJ4RQfsAFMVJMf2KOM
wjb6akXnrEzxPG6UEVxtep2cLLVraHlbjDHzNqMrecBC2EYHU/Ovh+gpsHXtJG8v
+Koh9HR2Ps5h92PI5ND39JsD1KyNhO+zayYD/a+I9ryrQEKV584JyU6q3vyWIwXk
m8eDlYo0ChCeiGwQ22bAOsdKYTJHruGPEg92VbbDipPLJ+8uzAbtEAlXmiGYkv2B
Q3EtprVkD1sI88v/iRU8QZg7ux5ebKDHGIk1f33BP3AYUWnwcyY=
=jKMW
-----END PGP SIGNATURE-----

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