What is the lifecycle of a HttpServlet? - java

Basically, how long is an instance of a servlet around for? I am kind of guessing it is session scope. However, I suppose it could have some sort of timeout or garbage collection to remove old instances.

a servlet is created when the application starts (it is deployed on the servlet container) or when it is first accessed (depending on the load-on-startup setting)
when the servlet is instantiated, the init() method of the servlet is called
then the servlet (its one and only instance) handles all requests (its service() method being called by multiple threads). That's why it is not advisable to have any synchronization in it, and you should avoid instance variables of the servlet
when the application is undeployed (the servlet container stops), the destroy() method is called.

The lifecycle is well defined, and exposed through lifecycle methods exposed in init, service, and destroy methods of the Servlet.
And, despite what else is being said here, this is all you can count on from the specification. Basically, you get those three methods and a guarantee that Servlets are not thread safe. That a single servlet MAY be simultaneously accessed by one or more requests.
There is nothing in the specification that limits a servlet to one instance the container, if a container decides to, it can get a request, create a servlet, call it's init, then service, then destroy methods, and set it free for garbage collection.
Individual containers have potentially different implementations.
Most containers do create a single instance. But the specification does not guarantee that, so you shouldn't rely on it.
Also, consider something like Google App Engine. GAE is VERY aggressive is continually expiring and shutting down entire web apps that receive no traffic. If you have a lightly traveled site, you can very well expect the entire app to start up, init all of its services, init any load-on-startup servlets, execute the request, and then shut everything down. So, on GAE it's imperative that you have a very fast application startup in order to maintain any semblance of performance.
So, simply, what you can count on is what the specification says. Individual containers may offer different run time experiences.

A Servlet lives as long as the application does.

A servlet is not bound to a session, it is a service object that is instantiated by the container when needed, and typically is kept alive for the full life of the webapp. It typically responds to requests from several clients (and sessions), even concurrent requests.
That's precisely why your servlet code must be thread safe, and you never store in a servlet field some data associated to a request or a session.

A servlet life cycle can be defined as the entire process from its creation till the destruction. The following are the paths followed by a servlet
The servlet is initialized by calling the init () method.
The servlet calls service() method to process a client's request.
The servlet is terminated by calling the destroy() method.
Finally, servlet is garbage collected by the garbage collector of the
JVM.
More here ..
http://www.dzone.com/links/r/java_ee_servlets_life_cycle.html

when i remember correctly servlets live as Singletons in the Servlet Container (e.g. Tomcat). Im not sure if the first instantiation is lazy, meaning that the Servlet gets constructed only if needed, but im guessing one could check this in the corresponding Servlet Container's Classloader sources.
The Servlet's lifecycle ends and it's destroy() method gets called when the Servlet Container is shut down.
You can check this easily by setting up breakpoints or logging in the appropriate init() and destroy() methods and Constructor then just check when the code gets executed in your debugger/logfile.
hope that helped.
References:
Tomcat's Classloader howto

The servlet (its one and only instance) will handle n number of request in the fashion of separate single thread for every client ie where CGI limitation is overcomed
A servlet object lives in heap of serverside machine as long as application is undeployed or servletConatiner is shutdown the servlet object will not die.
Technically : servletcontainer holds servletobject and servletobject holds servletConfig object
Servletcontainer can only call the 3 methods of its life cycle 1)init() 2)service() 3)destroy()

Actually the Servlet may be destroyed and recreated at any time ! So the other answers kinda describe the whole lifecycle but miss this important detail. From the servlet specification:
The servlet container is not required to keep a servlet loaded for any particular
period of time. A servlet instance may be kept active in a servlet container for a
period of milliseconds, for the lifetime of the servlet container (which could be a
number of days, months, or years), or any amount of time in between.
[...]
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.

The lifecycle of a typical servlet running on Tomcat might look something like this:
1.Tomcat receives a request from a client through one of its connectors.
2.Tomcat maps this request to the appropriate Engine for processing. These Engines are contained within other elements, such as Hosts and Servers, which limit the scope of Tomcat's search for the correct Engine.
3.Once the request has been mapped to the appropriate servlet, Tomcat checks to see if that servlet class has been loaded. If it has not, Tomcat compiles the servlet into Java bytecode, which is executable by the JVM, and creates an instance of the servlet.
4.Tomcat initializes the servlet by calling its init method. The servlet includes code that is able to read Tomcat configuration files and act accordingly, as well as declare any resources it might need, so that Tomcat can create them in an orderly, managed fashion.
5.Once the servlet has been initialized, Tomcat can call the servlet's service method to process the request, which will be returned as a response.
6.During the servlet's lifecycle, Tomcat and the servlet can communicate through the use of listener classes, which monitor the servlet for a variety of state changes. Tomcat can retrieve and store these state changes in a variety of ways, and allow other servlets access to them, allowing state to be maintained and accessed by various components of a given context across the span of a single or multiple user sessions. An example of this functionality in action is an e-commerce application that remembers what the user has added to their cart and is able to pass this data to a checkout process.
7.Tomcat calls the servlet's destroy method to smoothly remove the servlet. This action is triggered either by a state change that is being listened for, or by an external command delivered to Tomcat to undeploy the servlet's Context or shut down the server.
Reference:
https://www.mulesoft.com/tcat/tomcat-servlet

life cycle of servlet >
1) load the class.
2) instantiate the servlet.
3) servlet container construct the servlet config interface.
4) container call the init() and pass the servlet config object.
5) httpRequest and httpResponse object created.
6) container call the service() and pass the httpRequest and httpResponse object as argument.
7) process the service method.and if have any other request then follow the step 4 again.
8) other wise container call the distroy().

The servlet's container is attached to a web server that listens for HTTP or HTTPS requests on a certain port number (port 8080 is usually used during development and port 80 in production). When a client (user with a web browser) sends an HTTP request, the servlet container creates new HttpServletRequest and HttpServletResponse objects (for every new request) and passes them through any defined Filter chain and, eventually, the Servlet instance.
In the case of filters, the doFilter() method is invoked. When its code calls chain.doFilter(request, response), the request and response continue on to the next filter, or hit the servlet if there are no remaining filters.
In the case of servlets, the service() method is invoked(by multiple threads for different request). By default, this method determines which one of the doXxx() methods to invoke based off of request.getMethod(). If the determined method is absent from the servlet, then an HTTP 405 error is returned in the response.
The request object provides access to all of the information about the HTTP request, such as its headers and body. The response object provides the ability to control and send the HTTP response the way you want by, for instance, allowing you to set the headers and the body (usually with generated HTML content from a JSP file). When the HTTP response is committed and finished, both the request and response objects are recycled and made for reuse.

Related

Disable reuse of ServletRequest instance

Is it possible to disable the reuse of the ServletRequest instance for each request? It looks like the instance is reused multiple times (maybe bound per TCP session?)
What you can see in the spec :
3.13 Lifetime of the Request Object
Each request object is valid only within the scope of a servlet’s service method, or
within the scope of a filter’s doFilter method, unless the asynchronous processing
is enabled for the component and the startAsync method is invoked on the request
object. In the case where asynchronous processing occurs, the request object remains
valid until complete is invoked on the AsyncContext. Containers commonly recycle
request objects in order to avoid the performance overhead of request object
creation. The developer must be aware that maintaining references to request objects
for which startAsync has not been called outside the scope described above is not
recommended as it may have indeterminate results.
In case of upgrade, the above is still true
Containers commonly recycle
request objects in order to avoid the performance overhead of request object
creation
It is container-specific.
In this case it is specific to Jetty.
Jetty recycles the org.eclipse.jetty.server.Request object between requests.
This is normal, is within the definition of the Servlet Spec, and many containers do this.
Be careful of your usage of the HttpServletRequest / ServletRequest / Request object outside of the dispatch from the container.
If you are using it from an AsyncContext you should only use it when you are called by the container, not any other point or from any other thread (unless you are 100% certain you are handling the threading properly, and are ready to handle one of the thousands of corner cases with AsyncContext from a non-container thread)

How multithreading is handled in web containers [duplicate]

This question already has answers here:
How do servlets work? Instantiation, sessions, shared variables and multithreading
(8 answers)
Closed 6 years ago.
What I know
A web container creates a new thread per request.
What I don't know
Are new servlet objects created per request?
Why I am asking this is to get an idea on how thread synchronization issues can happen if the same servlet object is used for multiple requests.If the web container creates a new servlet object for each new reqest, then I don't see an issue. But if it uses the same servlet object to serve multiple requests, synchronization issues can happen.
How is this handled in a typical java web container?
A web container creates a new thread per request.
No. It reuses a thread from a thread pool.
Are new servlet objects created per request?
No. A servlet is a singleton. Only one instance is created per web app. Your servlet must be thread-safe, since it's called concurrently by several threads. But that' usually easy, because a servlet is typically stateless.
Are new servlet objects created per request ?
By default, Servlet container creates a single servlet instance and will be used to serve all of the requests in a separate thread. So ensure that your servlet class is thread safe (i.e., your servlet class should not hold any stateful data as instance variables, etc..).
Adding to that, Servlet containers create the servlet instance either during the container start-up or upon the first request received.
You can force the container to create the servlet instance by specifying the load-on-startup in web.xml or #WebServlet(urlPatterns="/xyz", loadOnStartup=1)).
It is generally better to load the servlets (unless you have any special requirements) using load-on-startup so that the first request will not hit with the performance.
In general sense servlets are Singletons, however if you map the same servlet class to different URL mappings using different names, you will have that many instances of same servlet.
Mostly servlets are stateless, if you do make them statefull, then be very careful about shared mutability .
Earlier servlet API used to have SingleThreadModel Interface to impose single thread access at one point of time, that way you could serve only one request at a time, However I see this interface is deprecated in recent APIs as it doesn't solve the concurrency issues fully, like static variables etc.

Servlet instance life time

My understanding of servlet instance is, there is only one instance of the servlet which is reused for multiple requests from multiple clients.
My question is, where the servlet container store these instance and how long the life time of the instance.
Thank in advance!
Where --> RAM/Heap (It's an instance).
How long? --> Till servlet destroy() called (OR) JVM killed. You may refer Servlet life cycle documentation for more details
In memory and in accordance with the Servlet Life Cycle. The linked Tutorial says (in part)
Servlet Life Cycle
The life cycle of a servlet is controlled by the container in which the servlet has been deployed. When a request is mapped to a servlet, the container performs the following steps.
If an instance of the servlet does not exist, the web container
a. Loads the servlet class.
b. Creates an instance of the servlet class.
c. Initializes the servlet instance by calling the init method. Initialization is covered in Initializing a Servlet.
Invokes the service method, passing request and response objects. Service methods are discussed in Writing Service Methods.
If the container needs to remove the servlet, it finalizes the servlet by calling the servlet’s destroy method. Finalization is discussed in Finalizing a Servlet.

How to destroy servlet before creation?

I had been asked a question in interview, how will you stop a Servlet from instantiating a servlet object?
I said the container decides to destroy servlet object.
He said again that the container will first create the servlet object and then destroy it. My question is servlet object hasn't been created yet, so there is no point in destroying it. How will you code a servlet class when it is trying to instantiate itself trap in severe problem and our code(or any other way) should stop it from instantiating?
You can stop the container from creating an instance of the Servlet in three ways:
Remove the reference to the Servlet in web.xml. If your container is processing annotations, then the #WebServlet annotation also need to be removed.
In the constructor, throw an exception.
In the init() method, throw an exception.
I guess he is expecting you to throw javax.servlet.UnavailableException from init()
public class UnavailableException
extends ServletException
This exception indicates that a servlet is unavailable. Servlets may report this exception at any time, and the network service running the servlet should behave appropriately. There are two types of unavailability, and sophisticated services will to deal with these differently:
Permanent unavailability. The servlet will not be able to handle client requests until some administrative action is taken to correct a servlet problem. For example, the servlet might be misconfigured, or the state of the servlet may be corrupted. Well written servlets will log both the error and the corrective action which an administrator must perform to let the servlet become available.
Temporary unavailability. The servlet can not handle requests at this moment due to a system-wide problem. For example, a third tier server might not be accessible, or there may be insufficient memory or disk storage to handle requests. The problem may be self correcting, such as those due to excessive load, or corrective action may need to be taken by an administrator.
You are right, container is responsible on servlet creation and life cycle. It first creates instance of servlet using default public constructor, then calls its init() method. When container wants to destroy the servlet it calls its destroy() method that is typically (IMHO) empty.
Container can first destroy and then create new servlet during hot re-deployment when it deploys probably new version of your application. Probably this is what your interviewer wanted to hear from you.

JAX-WS - inject WebServiceContext into #WebService that only has #Oneway methods

I'm on SAP NetWeaver 7.3 EHP 1 (JEE5 certified) and I've genereated a Web Service skeleton for an existing WSDL. All methods in this Webservice are non-blocking and thus annotated with #Oneway. The service itself works just fine.
I also need to access an injected WebServiceContext though, and this is where the trouble starts. I can inject the context just fine, but every call to it just ends up in server-specific NPEs or ISEs. I somewhat can understand that since the non-blocking call is executed asynchronously by SAP's JAX-WS implementation. However, I tried to validate this behaviour by looking at the JAX-WS specification. Now I'm either blind or the specification doesn't specifically say that a WebServiceContext must not be used in non-blocking web methods. In fact, in the whole of chapter 5.3 of the latest version of the spec, #Oneway is not mentioned once. The main description is
The javax.xml.ws.WebServiceContext interface makes it possible for an
endpoint implementation object and potentially any other objects that
share its execution context to access information pertaining to the
request being served.
The result of invoking any methods on the
WebServiceContext of a component outside the invocation of one of its
web service methods is undefined. An implementation SHOULD throw a
java.lang- .IllegalStateException if it detects such a usage.
I guess the point is the definition of "request being served". At the time of the asynchronous handling of the SOAP operation, the HTTP request has already finished. But then again, I'm not accessing the context "outside of the invocation of one if its web service methods". I'm confused...
Does any of you guys know if I should be allowed to access the WebServiceContext in a non-blocking web method? Thanks!
You're right: the spec says nothing about this limitation - it's only vaguely implied.
From the JAX-WS spec (2.2 Rev A):
The WebServiceContext is treated as an injectable resource that can be
set at the time an endpoint is initialized. The WebServiceContext
object will then use thread-local information to return the correct
information regardless of how many threads are concurrently being used
to serve requests addressed to the same endpoint object.
Should be operational over the existence of the endpoint, but only if used in the same thread that setup and stored the request contextual information into thread-local memory storage. Given that WebServiceContext is primarily MessageContext information, which is HTTP Request / Servlet Request / WSDL Operation settings, the thread-local contextual information would probably need to be populated by the thread that initially marshalls the SOAP/HTTP request, meaning that the later async processing thread does not have this info available. Just based on reading - haven't tested this combination.

Categories