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
Related
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.
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 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.
I have implemented my domain layer classes and i have used them in a java application.
Now i want to use same classes in a java web application,but i don't know how can i do it?
In the java application we make and run some objects in main(class and method) and use them while program is running.
for example an object that hold a collection of data that will be needed for all user requests.
My question is:
How can i create and hold such objects and data that should be available for all users and clients.
Place them in the application context. I.e. in a Servlet call getServletContext().setAttribute("name", yourCollection);
Then they can be retrieved by getServletContext().getAttribute("name")
You could create a singleton which represents the common application logic, initialising and cleaning up the common information and objects on web-app startup and shutdown.
All servkets can use the application singleton to retrieve and store.
To initialise and cleanup on web-app startup and shutdown you can define an administrative servlet which has the load-on-startup flag set in the deployment descriptor web.xml managing the application singleton from the init() and destroy() methods.
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.