views:

899

answers:

4

According to my understand, Tomcat is allowed to raise as many copies of a servlet as it wishes in order to service requests.

This forces my servlets to have no heavyweight state, and instead store all state in the (singleton) servlet context.

Is it possible to configure Tomcat to treat my servlets as singletons, and always raise exactly one servlet instance regardless of load?

+1  A: 

No, I don't think so. However, in practice tomcat will only ever instantiate a single servlet, even if the JavaEE spec allows it to instantiate several. Most, if not all, of the MVC frameworks out there rely on that assumption, and store a lot of config state in the servlet.

If you want to play it safe, then don't store your state in the servlet, stick it in another class which uses the singleton pattern, and reference that singleton from your servlet.

skaffman
I like Spring MVC - it can be used as a fairly thin wrapper over servlets, but gives you lots of nice things including dependency injection, which would let you assign shared objects/services to your controllers (equivalent to servlets) without hardcoding them (which then makes testing/maintenance much nicer). Try the tutorials or read a book like "Spring in Action" to get started. Separating your controller and model logic is just as important to good MVC design as separating your view (and I would count your shared state and services as the 'model' here).
paulcm
"JavaEE spec allows it to instantiate several" -- it depends. One *container* (i.e. tomcat) can only instantiate single servlet per declaration, unless servlet implements `SingleThreadModel` interface.
Peter Štibraný
Well SingleThreadModel guarantees one instance per thread, but I don't believe omitting it guarantees one instance per container.
skaffman
Servlet specification guarantees one instance per container, unless you use SingleThreadModel. In that case, container is permitted to instantiate servlet multiple times.
Peter Štibraný
+2  A: 

The other main reason why you don't want to store state in your Servlet is that it introduces synchronization issues, serialization issues if you want to run in a clustered environment, etc. All of these are simple to avoid if you don't store state internally in the servlet, but rather where it belongs in the Session (or Request) objects.

So really ... why do you want to store state? It's a "recommended practice" for a reason.

matt b
+7  A: 

According to Servlet Specification, (v2.4, section 2.2 "Number of Instances"):

SRV.2.2 Number of Instances

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.

Answer to your question is simple: don't implement SingleThreadModel, and don't declare your servlet multiple times in web.xml descriptor file.

Peter Štibraný
Related question - Is it guaranteed that the container will not keep references to the servlet after destroy() is called?
ripper234
Yes. Check out section SRV.2.3.4, End of Service: "Once the destroy method is called on a servlet instance, the container may not route other requests to that instance of the servlet. If the container needs to enable the servlet again, it must do so with a new instance of the servlet’s class. *After the destroy method completes, the servlet container must release the servlet instance so that it is eligible for garbage collection."*
Peter Štibraný
+1  A: 

Ditto Matt B. I got badly burned once before I learned this lesson. I stored state information in statics in a servlet object. It all worked great in testing where we had a single server. Then we deployed to production where there we had a server cluster, and we got really strange errors before we finally figured it out.

Use your Session or Application objects. That's what they're for.

Moral of the story: When the designer of the structure provides a tool and says to use this tool when you want to do X, there is probably a reason for it. Be very cautious about ignoring such advice.

Jay