Life cycle management of servlet when SingleThreadModel is used - java

According to the java docs, it says that If SingleThreadModel is used there are two ways a servlet instance will be created and used
1. Create one servlet instance and make the service() method synchronized and thus allow only one thread to execute the service method.
2. Create a pool of servlets and serve the request by using one servlet instance from the pool for each request.
THe question which I want to ask is I have also read a new Servlet instance is created and destroyed for every request. Now which one is correct

Here's what the spec says (version 3.0, section 2.2):
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 (JVMTM)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.
Note that you should really not use the single thread model. Just make sure your servlet is thread-sae. A servlet is typically stateless, so you don't have anything to do to make it thread-safe.

From the docs for SingleThreadModel:
Ensures that servlets handle only one request at a time
This is in essence a way to make non thread-safe servlet code work. Note that the container is free to choose any of the two implementations to adhere to the spec:
Create a single instance of the servlet and ensure that it handles only one request at a time
Create a pool of servlet instances and hand over a request to an available servlet instance.

Related

Synchronized on Servlet service method

I was reading the Servlet Specification and came across this:
For servlets not implementing the SingleThreadModel interface, if the service
method (or methods such as doGet or doPost which are dispatched to the service
method of the HttpServlet abstract class) has been defined with the synchronized
keyword, the servlet container cannot use the instance pool approach, but must
serialize requests through it.
I don't understand why the servlet container cannot use the instance pool approach with a synchronized service method. Doesn't the instance pool contain different instances of the servelet so that every instance will use itself to synchronize the method (not blocking each other)?
From what I understand the the synchronize will be useless in this case but it does not stop the servlet container from using an instance pool.
What am I missing?
Thanks.
What that sentence is saying is that if you dont implement SingleThreadModel then your Servlet instance wont be pooled at all no matter it it uses synchronization or not. The only reason it mentions synchronization is to warn you that Servlet container wont be using multiple instances of your Servlet per VM to allow it to process multiple requests at the same time.
Here is another missing fragment from the spec:
SRV.2.2 Number of Instances
The servlet declaration which is part of
the deployment descriptor of the Web application containing the
servlet, as described in Chapter SRV.13, “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. Servlet Life Cycle 19 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 (JVMTM) 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

ThreadPoolExecutor.run and Servlet re-initialization

This link says that earlier versions of Tomcat (before 7.0.54) "renews its threads" thru ThreadPoolExecutor.run().
Why doesn't the init() method of contained Servlets seem to get called again?
A Servlet is initialized only once, either at web application startup or upon first use.
The same instance will then be used to serve all incoming requests, if necessary even multiple requests at the same time (unless you use the deprecated option to synchronize access, but even then there will be just a single instance, and a queue of requests for it).

When exactly a web container initialize a servlet?

When exactly a web container initialize a servlet?
Is it guaranteed that it does it at web container start up time?
Thanks.
No, it's not. First, the webapp itself is not guaranteed to be started when the container starts (that depends on the specific container configuration). And even if the webapp is started, the specification says:
Servlets are initialized either lazily at request processing time or eagerly during deployment. In the latter case, they are initialized in the order indicated by their load-on-startup elements.
When exactly a web container initialize a servlet?
Either at the time of loading the web application or on the first request to the servlet. This is configurable in web.xml using load-on-startup flag
Is it guaranteed that it does it at web container start up time?
Nothing is guranteed when it comes to the container. It depends how the contianer is written .The only way to request the container is through configurable param load-on-startup in in web.xml.
Depends on how you are defining and configuring your servlet.
You might find this clearly in docs
Initializing a Servlet
After the web container loads and instantiates the servlet class and before it delivers requests from clients, the web container initializes the servlet. To customize this process to allow the servlet to read persistent configuration data, initialize resources, and perform any other one-time activities, you override the init method of the Servlet interface. A servlet that cannot complete its initialization process should throw UnavailableException.
If you want to participate in that process ovveride init method of the Servlet interface and do the required stuff there.

Does each request access the same servlet object?

Does each HTTP request access the same servlet object but in a different thread? or does it create a new thread and new Servlet Instance ?
The container will use the same servlet instance if your servlet don't implement SingleThreadModel.
Otherwise there is no guarantee that the same Servlet object is hit. The container is free to create more servlet instances if it considers necessary. But the requests comes on different threads, not necessarily newly created (as Sanjay mentioned).
From the Servlet 3.0 specification:
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.
...
Generally the Web container handles concurrent requests to the same servlet by
concurrent execution of the service method on different threads.
Each HTTP request creates a new thread but accesses the same instance of the Servlet.
EDIT: In case of one server node, you will have the same Servlet instance on that node. In case of load balancing/many servers you will usually have one instance per Java VM.

WebService/SLSB a Singleton in JBossWS?

I am using the JAX-WS "WebService" annotation on a class to expose its "WebMethod"s as a web service. The class is denoted as the servlet class handling calls to "/MyService".
As essentially a servlet, I would expect an instance of this class to be created once and to basically be a singleton. I have code in the constructor of this class to create an EntityManagerFactory for assignment to a member variable. What I'm seeing is that the constructor is being called for every client request to the web service. This is not good.
Does anyone know what's going on here? Does anyone understand what I'm trying to ask? :)
Thanks.
As essentially a servlet, I would expect an instance of this class to be created once and to basically be a singleton.
It's up to container. You cannot rely on it.
Create a real singleton -- a simple Java class -- which does all the heavy lifting, and call it from the servlet.
Your topic mentions a SLSB, which I assume is "Stateless Session Bean". In Java EE 5 you can create web services either from a Stateless Session Bean, or you can annotate a class and the runtime will publish it as a webservice when deployed in a compliant web container.
In either case, neither of these are Servlets per se, and don't follow a Servlet lifecycle.

Categories