tags:

views:

55

answers:

3

Hello,

I have a class public class GAE_SERVLETREQUESTServlet extends HttpServlet {

Not sure what the spec says about recycling of the HTTPServlet: Should the servlet container create new instance of this class on each incoming request or can the implementation reuse classes between requests?

I'm investigating a funny issue where it seems that a Map created on the GAE_SERVLETREQUESTServlet instance maintains state between requests.

Thank for the help, Maxim.

+4  A: 

The container is permitted to instantiate as many servlets as it chooses to. In practice, however, it's only going to do it once - I've never seen a container do otherwise. So every request will be serviced by the same servlet instance.

You should not keep this sort of transient state in your servlet class, for this very reason.

skaffman
Thank you for the answer.
Maxim Veksler
It is not ;) by spec it must use exactly one instance (in case of non-distributed environment)
Bozho
Indeed. It's only allowed for the ones implementing (the deprecated!) `SingleThreadModel`. They will in turn however usually be pooled, so instantiation is also limited.
BalusC
@Bozho: I'd delete my own answer if it'd let me...
skaffman
note that I'm not sure this is true for Servlet 2.5.
Bozho
A: 

If you are saving data that is relevant to each user, you should store it in the HTTP Session. As stated by skaffman, do not store data in the servlet class that you expect to be different for each each user. Here is a quick example.


class MyServlet extends HttpServlet
{
    private Object ThisIsTheWrongPlaceToStorePerUserData;

    ... stuff ... doPut(HttpServletRequest httpRequest, ... more stuff ...)
    {
        Object iAmGood = new Object();
        HttpSession session = httpRequest.getSession(true);

        session.setAttribute("GoodPlaceToStorePerUserData", iAmGood);

        ... stuff ...
    }
}

dwb
I don't want to store the object in a session because I have no reason to initiate a cookie on the user, nor do I want to store server side "per user" state data. This is a backend service and that is the whole reason I started to look for alternatives. I've fixed my code now and frankly am a bit embarrassed to have made such a rookie mistake :)
Maxim Veksler
+4  A: 

For the general case - non-distributed, multi-threaded, it is guaranteed that there will be only one instance of the servlet. From the Servlet 3.0 specification:

2.1 Request Handling Methods

The basic Servlet interface defines a service method for handling client requests. This method is called for each request that the servlet container routes to an instance of a servlet. The handling of concurrent requests to a Web application generally requires that the Web Developer design servlets that can deal with multiple threads executing within the service method at a particular time. Generally the Web container handles concurrent requests to the same servlet by concurrent execution of the service method on different threads.

2.2 Number of Instances

The servlet declaration which is either via the annotation as described in Chapter 8, “Annotations and pluggability” or part of the deployment descriptor of the Web application containing the servlet, as described in Chapter 14, “Deployment Descriptor”, controls how the servlet container provides instances of the servlet. For a servlet not hosted in a distributed environment (the default), the servlet container must use only one instance per servlet declaration. However, for a servlet implementing the SingleThreadModel interface, the servlet container may instantiate multiple instances to handle a heavy request load and serialize requests to a particular instance.

In the case where a servlet was deployed as part of an application marked in the deployment descriptor as distributable, a container may have only one instance per servlet declaration per Java Virtual Machine (JVM™)1. However, if the servlet in a distributable application implements the SingleThreadModel interface, the container may instantiate multiple instances of that servlet in each JVM of the container.

Bozho