See intermixed below.

On Thu, 31 Jan 2002, Anton Brazhnyk wrote:

> Date: Thu, 31 Jan 2002 12:20:16 +0200
> From: Anton Brazhnyk <[EMAIL PROTECTED]>
> Reply-To: Tomcat Users List <[EMAIL PROTECTED]>
> To: Tomcat Users List <[EMAIL PROTECTED]>
> Subject: RE: multiple init() calls
>
> Hi,
>
> > -----Original Message-----
> > From: David Rault [mailto:[EMAIL PROTECTED]]
> > Sent: Thursday, January 31, 2002 11:36 AM
> > To: Tomcat Users List
> > Subject: Re: multiple init() calls
> >
> >
> > hi
> >
> > i think there may be a misunderstanding (or i misunderstood your
> > message ?!)
> > the servlet must create _only_ one instance of each servlet class per web
> > application
>
> I believe there is no such MUST in spec.

If your servlet does not implement SingleThreadModel, there is indeed such
a "must" requirement, in Section 2.2 of the Servlet 2.3 spec:

    "For a servlet not hosted in a distributed
    environment, the servlet container must use
    only one instance per servlet declaration."

The very next sentence covers SingleThreadModel semantics:

    "However, for a servlet implementing the
    SingleThreadModel interface, the servlet
    container may instantitate multiple instances
    to handle a heavy request load and serialize
    requests to a particular instance."

(Personal aside -- SingleThreadModel should be avoided, because it implies
promises about thread safety that get beginners into all sorts of
trouble.)

Note that both sentences above refer to a "servlet declaration", which is
a single instance of a <servlet> element in your web.xml file.  It's legal
to use the same servlet class in more than one servlet declaration
(perhaps with different initialization parameters) if you wish -- but you
will get a separate servlet instance for each declaration.

Tomcat also supports the non-standard "invoker" mechanism to execute
servlets that have not been defined in web.xml, by using context-relative
paths like "/servlet/foo".  For the purposes of the above discussion, each
unique value of "/foo" creates a unique servlet declaration on the fly,
which is initialized once (if non-STM) or potentially multiple times (if
STM) and then reused for the remainder of the lifetime of this webapp.

>
> > then this instance must receive _one_ message init()
> > at this point user request may be served
> > for each user request, a thread is started and executes the service(...)
> > method on the
> > _shared_ instance
> >
> > the singleThreadModel only tells the servlet engine not to serve several
> > request simultaneously
> > this is the behaviour required by the J2EE specs
> >
> > as for your problem, i'm doing servlet for about 2 years now and
> > i never saw
> > that kind of
> > behaviour... may be a look at your code would help...
> >
>
> So, lets turn to spec (Servlet 2.3)
>
> <cite>
> SRV.14.2.20 SingleThreadModel
> public interface SingleThreadModel
> Ensures that servlets handle only one request at a time. This interface has no
> methods.
> If a servlet implements this interface, you are guaranteed that no two threads will
> execute concurrently in the servlet?s service method. The servlet container can
> make this guarantee by synchronizing access to a single instance of the servlet, or
> by maintaining a pool of servlet instances and dispatching each new request to a
> free servlet.
> This interface does not prevent synchronization problems that result from servlets
> accessing shared resources such as static class variables or classes outside the
> scope of the servlet.
> </cite>
>
> I believe TC (at least 4.0.2b2) chose the second variant. The pool of instances.
> So any instance have to be properly initialized.
>

The ability to pool SingleThreadModel (STM) instances was recently added
to Tomcat 4.0.  Previously, the instance pool was limited to one.  Now,
the default maximum number of instances is 20.

> just an example
>
> package webtests;
>
> import javax.servlet.*;
> import javax.servlet.http.*;
> import java.io.*;
> import java.util.*;
>
> public class SingleThread extends HttpServlet implements SingleThreadModel {
>
>     private static int cnt = 0;
>
>     private static final String CONTENT_TYPE = "text/html; charset=windows-1251";
>
>     /**Initialize global variables*/
>     public void init() throws ServletException {
>         System.err.println("init at " + Thread.currentThread().toString());
>         System.err.println("Counter: " + (++cnt));
>         System.err.println("Instance: " + this.toString());
>     }
>
>     /**Process the HTTP Get request*/
>     public void doGet(HttpServletRequest request, HttpServletResponse response) 
>throws ServletException, IOException {
>         response.setContentType(CONTENT_TYPE);
>         PrintWriter out = response.getWriter();
>         out.println("<html>");
>         out.println("<head><title>SingleThread</title></head>");
>         out.println("<body>");
>         out.println("<p>The servlet has received a GET. This is the reply.</p>");
>         out.println("</body></html>");
>     }
>
> }
>
> and TC console:
>
> init at Thread[HttpProcessor[8080][0],5,main]
> Counter: 1
> Instance: webtests.SingleThread@19dc16
> init at Thread[HttpProcessor[8080][0],5,main]
> Counter: 2
> Instance: webtests.SingleThread@405d3b
>
> BTW, I'm not sure but it looks like TC3.2 creates only one instance.

That is correct ... Tomcat 3.2 does not implement instance pooling for STM
servlets.
>
> > have fun!
> >
> > David
> >
>
> Anton.
>

There are three easy ways to cause the "multiple inits" problem seen by
the initial poster on this thread:

* Use a SingleThreadModel servlet (as discussed above).

* Configuration errors, such as defining your servlet in the
  global "$CATALINA_HOME/conf/web.xml" file instead of inside
  your webapp, or installing the same webapp more than once.

* Having your servlet's init() method throw an exception.  In
  such cases, the container will destroy that instance and create
  another one on the next request.  The exception will be logged
  in one of the log files in "$CATALINA_HOME/logs" so that you can
  see if this is actually happening.

Craig McClanahan


--
To unsubscribe:   <mailto:[EMAIL PROTECTED]>
For additional commands: <mailto:[EMAIL PROTECTED]>
Troubles with the list: <mailto:[EMAIL PROTECTED]>

Reply via email to