On May 30, 2013, at 3:38 PM, Mark Thomas wrote:

> On 30/05/2013 21:04, Nick Williams wrote:
>> 
>> On May 29, 2013, at 6:58 AM, Pid wrote:
>> 
>>> On 29/05/2013 00:24, Nick Williams wrote:
>>>> Guys,
>>>> 
>>>> Can some of the fine experts on this list double check my
>>>> assertions below and let me know if I'm going wrong anywhere? I
>>>> hope I got it all right. :-)
>>>> 
>>>> Assertion #1 If metadata-complete="true" is present in the
>>>> deployment descriptor: A) The container does NOT scan
>>>> /WEB-INF/classes for annotations, B) The container does NOT scan
>>>> /WEB-INF/lib JARs for ServletContainerInitializers,
>>> 
>>> "The metadata-complete and invocation of
>>> ServletContainerInitializers are independent."
>>> 
>>> https://java.net/jira/browse/SERVLET_SPEC-36
>> 
>> Thanks. I'm assuming that I got everything else correct since this is
>> the only thing you corrected and nobody else replied.
> 
> Or pid just stopped at the first invalid assumption ;)
> 
>> But I want to make sure I understand the discussion at this link
>> correctly. Rajiv says here: "Ordering does not apply to
>> ServletContainerInitializers." Is that really correct? There's really
>> no way at all to order the invocation of
>> ServletContainerInitializers' onStartup methods??? Mark, you seemed
>> to be involved in this discussion a lot. Is this really true???
> 
> If that is what the spec lead says then yes. Tomcat will process them in
> the order they are found: i.e. respecting the fragment order but you
> can't rely on a) any other container doing the same, b) Tomcat
> continuing to do the same (although it is unlikely to change unless a
> spec feature mandates a change)
> 
>>>> C) The container does NOT scan /WEB-INF/lib JARs for
>>>> web-fragment.xml files
> 
> False. The scan still occurs because the ordering elements determines
> whether or not SCIs are scanned for.
> 
> , and D) The container does NOT scan
>>>> /WEB-INF/lib JARs for annotations.
>>>> 
>>>> Assertion #2 If class loading is configured "parent last," the
>>>> ServletContainerInitializers in the application are fired before
>>>> ServletContainerInitializers provided by the container. If class
>>>> loading is configured "parent first", the
>>>> ServletContainerInitializers provided by the container fire
>>>> before the ServletContainerInitializers in the application.
> 
> False. Ordering of SCIs from the container is undefined, as is the
> mechanism by which they get added to the app. It is a container specific
> process.
> 
>>>> Assertion #3 ServletContainerInitializers in the container and in
>>>> /WEB-INF/lib JARs are fired before any ServletContextListeners.
>>>> The order in which they are fired is determined by
>>>> <absolute-ordering> (web.xml) and/or <order> (web-fragment.xml),
>>>> but if neither of those are present the order is unspecified.
> 
> Listeners defined in a single web[-fragment].xml will be fired in the
> order they are defined.
> 
>>>> Assertion #4 The init methods of ServletContextListeners declared
>>>> in the container, in /WEB-INF/classes, and in /WEB-INF/lib JARS
>>>> are all fired BEFORE the init methods of any Filters or Servlets.
>>>> The destroy methods of ServletContextListeners declared in the
>>>> container, in /WEB-INF/classes, and in /WEB-INF/lib JARs are all
>>>> fired AFTER the destroy methods of any Filters or Servlets.
>>>> 
>>>> Assertion #5 The init methods of Filters declared in the
>>>> container, in /WEB-INF/classes, and in /WEB-INF/lib JARs are all
>>>> fired BEFORE the init methods of any Servlets. The destroy
>>>> methods of Filters declared in the container, in
>>>> /WEB-INF/classes, and in /WEB-INF/lib JARs are all fired AFTER
>>>> the destroy methods of any Servlets.
>>>> 
>>>> Assertion #6 If any given ServletContainerInitializer is the
>>>> first ServletContainerInitializer to be fired when an application
>>>> starts up, and that ServletContainerInitializer adds a
>>>> ServletContextListener and a Filter to the ServletContext: A) The
>>>> Listener it adds will be the first Listener whose init method is
>>>> called and the last Listener whose destroy method is called,
> 
> False.
> 
>>>> B)
>>>> The Filter it adds will be the first Filter whose init method is
>>>> called and the last Filter whose destroy method is called, and
> 
> It depends.  Look for isMatchAfter
> 
> C)
>>>> The Filter will be the first Filter on the Filter chain, always.
> 
> False.
> 
> The detail for all of the above is in the spec.

Yea, I've read these areas of the spec since then. I see where some of my 
assertions were wrong now, but I still have some uncertainties with a couple:

#2: 8.2.4 says of ServletContainerInitializers: "the order in which these 
services are discovered MUST follow the application’s class loading delegation 
model." So, SCI /classes/ in the application should be discovered before SCI 
classes in the container /if/ "parent last" class loading is used (it is by 
default in Tomcat), and SCI classes in the container should be discovered 
before SCI classes in the application /if/ "parent first" class loading is used 
(it is by default in WebSphere, for example). If they get reordered from the 
order they're discovered in before they're fired, I'm not sure why Tomcat is 
doing that. You say that Tomcat, specifically, respects the fragment order 
(even though the spec doesn't say you must do so), but SCIs provided by the 
container don't belong to fragments and thus can't have a fragment order, so 
that ordering scheme only works for SCIs provided by the application. So if 
Tomcat is ordering them differently from the order they're discovered in, how 
is it determining that order?

#6: 8.2.3(1) says "The order for listeners, servlets, filters if relevant must 
be specified in either the web-fragment.xml or the web.xml." 8.2.2(1)(b) says 
"The web.xml and WEB-INF/classes MUST be processed before any of the 
web-fragments listed in the absolute-ordering element." 8.2.2(2)(b) says "The 
web.xml and WEB-INF/classes MUST be processed before any of the web-fragments 
listed in the ordering element." So, I know for sure that <filters> in web.xml 
and web-fragment.xml come before programmatically-registered filters (this was 
part of my mistake before). What I'm still uncertain on is:
    - If there are /no/ <filters> in web.xml or web-fragment.xml and filters 
are /only/ registered programmatically, is their order unspecified, or are they 
in the order addFilter is called?
    - What comes first: @WebFilters or programmatically-registered filters? Or 
is this unspecified?
    - If there are <filters> and programmatically-registered filters, will the 
<filters> be placed on the chain in the order they are declared and /then/ the 
programmatic filters placed on the chain in the order they are declared, or is 
this unspecified?

My overriding concern is ordering something "before anything else." Based on 
reading the various specs, reading the link Pid sent me, and your answers, I've 
concluded the following, which I pray someone can tell me is wrong, because if 
I'm right it seems like a backwards movement in the spec:

- In Servlet 2.5, there was a way to execute something "before anything else" 
on application startup. You could define a ServletContextListener as the /very 
first listener/ in the deployment descriptor (web.xml), and its 
contextInitialized method would always be invoked before the initialize methods 
on any other listeners, servlets, or filters.
- As of Servlet 3.0 and the introduction of ServletContainerInitializers, there 
is no longer a way to guarantee that something can be executed "before anything 
else." A) Any ServletContainerInitializers' onStartup methods will always be 
called before ServletContextListeners' contextInitialized methods, so you can't 
rely on the ServletContextListener to come first anymore. B) You can't create 
your own ServletContainerInitializer and make it run before any others because 
the order of ServletContainerInitializers is unspecified. C) You can disable 
all web fragments with <absolute-ordering /> and that will stop those SCIs from 
firing but you still can't stop the container SCIs from firing so, again, 
there's no way to *make* something run first anymore.

I hope I'm wrong about this...
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to