Ivano,
On 12/27/24 12:48 PM, Ivano Luberti wrote:
Chris, first of all thanks for your response.
Il 27-Dec-24 18:37, Christopher Schultz ha scritto:
Ivano,
On 12/27/24 11:48 AM, Ivano Luberti wrote:
> Tomcat version is 9.0.96
>
> I have two questions:
>
> 2) The docs (https://tomcat.apache.org/tomcat-9.0-doc/servletapi/
javax/ servlet/ServletContextListener.html) state that
>
>> All servlets and filters have been destroyed before any
ServletContextListeners are notified of context destruction.
>>
> Now in my code I have a servlet class (MyServletClass) that
implements ServletContextListener and contextDestroyed
>
> and another not servlet class (say MyClass) that implements those
as well.
You have a Servlet that implements ServletContextListener, and also
includes a contextDestroyed(ServletContextEvent) method? Okay.
> Using breakpoints I see that MyClass.contextDestroyed called BEFORE
MyServletClass.contextDestroyed
>
> and for what I understand it should be the other way around.
For what reason? If they are both implementing ServletContextListener,
they should both be called. But there is no guarantee of the order in
which they are called.
The fact that one of them is a Servlet is not relevant.
The doc says:
All servlets and filters have been destroyed before any
ServletContextListeners are notified of context destruction.
Correct. So your servlet's destroy() method should be called before any
ServletContextListener.contextDestroyed() method is called, and for your
Servlet/ServletContextListener, you should get one call before the
second, reliably.
If you use a debugger (or just logging statements), you should be able
to confirm that.
Note that, typically, classes implementing ServletContextListener do not
have a superclass (other than java.lang.Object) and so both the methods
specified by that interface must be implemented.
On the other hand, most servlets will inherit from GenericServlet which
includes a do-nothing implementation of destroy(), so your servlet
doesn't need to implement it if there is no clean-up work to be done.
Don't confuse Servlet.destroy() with
ServletContextListener.contextDestroyed().
So I guess that if the servlet and filters have already been destroyed
the contextDestroyed method had been called before their destruction and
by consequence the contexttDestroyed method have to be called after
those of the servets and filters
I'm not following you. Can you say that any differently?
> 2) I cannot find documentation on this matter.
The Servlet Specification is what you are looking for. The one
relevant for all supported Tomcat 9 versions is Servlet 4.0 which can
be found here:
https://javaee.github.io/servlet-spec/downloads/servlet-4.0/
servlet-4_0_FINAL.pdf
OK
> a) if I have more than one class (neither servlet) implementing
ServletContextListener interface in which order the contextDestroyed
method is called?
How are you registering your event listeners? If you register them in
WEB-INF/web.xml then they will be invoked in the order in which they
appear in web.xml. Initialization notifications will be sent in top-
down order and destruction notifications will be sent in bottom-up order.
If you are using @Annotations, then I don't believe an order can be
specified because there is no guaranteed order of .jar-file processing
and/or .class-file processing when searching for annotations.
I have to use the @Annotations,
I think there is no reliable way for you to specify the ordering of the
Servlet init/destroy and ServletContextListener init/destroy methods.
> b) if I have more than one servlet class implementing
ServletContextListener interface in which order the contextDestroyed
method is called?
There is no Servlet.contextDestroyed method defined, so it will never
be called by the container (Tomcat). If you happen to have a class
which implements both interfaces, then the container will invoke the
right methods at the right times, but don't think that because you
have a Servlet that is also a ServletContextListener that Tomcat will
call contextDestroyed on it earlier than any other
ServletContextLsistenrt just because it's a Servlet.
Yes I have written
"if I have more than one servlet class implementing
ServletContextListener interface in which order the contextDestroyed
method is called? "
so I have (and I want) to implement contextDestroyed
From Tomcat's perspective, it's just a ServletContextListener like any
other. I would bet that you get two separate instances of that class
in memory, as well: one to serve as the Servlet and another to serve
as the ServletContextListener. Forcing them to be the same object
might be difficult to accomplish.
I can't follow you: if I have a class like
public class MyServlet extends HttpServlet implements
ServletContextListener {
there will be two objects in memory?
Most likely, yes. Try this:
public class MyServlet extends HttpServlet implements
ServletContextListener {
public void init() {
getServletConfig().getServletContext().log(getClass().getName()
+ " instance " + hashCode() + " init()");
}
public void destroy() {
getServletConfig().getServletContext().log(getClass().getName()
+ " instance " + hashCode() + " destroy()");
}
public void contextInitialized(ServletContextEvent sce) {
sce.getServletContext().log(getClass().getName() + " instance "
+ hashCode() + " contextInitialized()");
}
public void contextDestroyedServletContextEvent sce) {
sce.getServletContext().log(getClass().getName() + " instance "
+ hashCode() + " contextDestroyed()");
}
}
You should end up with log messages that look like this:
MyServlet instance 3876ace contextInitialized()
MyServlet instance ab65de init()
MyServlet instance ab65de destroyed()
MyServlet instance 3876ace contextDestroyed()
If that's not the case, please post source for a web application that
reproduces the issue and we will look at it.
-chris
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org