tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Steven Elliott <ttoi...@mac.com>
Subject Servlet init() callin twice on startup. PLease help.
Date Tue, 30 Apr 2002 10:15:45 GMT
 -----Original Message-----
 From: IvanLatysh [mailto:ivan@yourmail.com]
 Sent: 29 April 2002 19:17
 To: Tomcat Apache
 Subject: Servlet init() callin twice on startup. PLease help.
>
> I have servlet that executing on start up.
> And when I see log - i can see that servlet was started twice.
> I need to start it one.
> Where I am wrong ?
>
> Sincerely yours, Ivan Latysh.
> Ivan@yourmail.com
> http://ivan.yourmail.com

The *problem* is related to multiple class loaders, specifically the Tomcat
container classloader which for some reason will load and init servlets
indicated as load-on-startup in web.xml files belonging to applications
heirarchically contained within the Tomcat webapps directory.  IOW your
servlet is being loaded on startup by not only your application but also by
the Tomcat container.  For this reason you are seeing it being loaded (and
inited) twice.

Not sure why this happens but maybe if Craig or one of the other developers
has a moment to explain because I've not seen it documented, I just know
this from testing.

What I've learned from my tests is that from your application you will never
see the servlet instanced by the container context nor will you be
influenced by the container instance changing class variables, etc: it is as
if two instances had been created by two different VM's.  So in most cases
unless you are sensitive to the resources being consumed you would never
notice two instances of you servlet are being load-on-startup.

But there are cases when this behavior is problematic.  In my case the init
method of the servlet was used to set in motion a separate class; a
scheduler which periodically emailed reports and sent messages.  Of course
initing two instances of this servlet caused duplicate threads to run.  You
seem to have a similar problem and even implementing a singleton pattern
made no difference because of course the class was being instantiated by two
different classloaders.

I have found one way to get around this problem (there are certainly
others).  Put the servlet as another separate application within your
application.  It would look something like the following:

webapps
  |
  | YourApplicationDirectory
             |
             |------- internalApplicationDirectory
             |                  WEB-INF
             |                          | classes
             |                                  | your servlet
             |                          | web.xml (w/your servlet
             |                                             load-on-startup )
             | -------WEB-INF
                            |  classes
                            |  lib
                            |  web.xml

In my case my YourApplicationDirectory is the appBase of a virtual host.  So
I am able to declare <host ........ unpackWARs="true"> which will autoload
my internalApplicationDirectory.  I am NOT SURE if this method will work in
your case because I do not know what your server.xml or your application
web.xml files look like.

I am sure there are other ways around the problem, I just haven't had time
to test them and from what I can see the next version of Tomcat (4.1.x) will
be somewhat different (i.e. Things like global resources, JMX, etc) so I am
waiting before I put a lot of effort into testing 4.0.x.

Hope the above helps.

Steven


--
To unsubscribe:   <mailto:tomcat-user-unsubscribe@jakarta.apache.org>
For additional commands: <mailto:tomcat-user-help@jakarta.apache.org>
Troubles with the list: <mailto:tomcat-user-owner@jakarta.apache.org>


Mime
View raw message