What acts in the role of the 'main method' in a servlet? - java

Servlet is also java program but there is no main method in servlet.Who will take role of main method on servet.

Servlets are designed to run inside a servlet container (eg. Apache Tomcat). Execution of a servlet happens in the following manner: The servlet container calls the GenericServlet.service() method on a servlet which typically calls the appropriate doXxx() method, eg. doGet(), doPost(), etc. The doXxx() method is responsible for interpreting the HTTP request and serving an appropriate response. GenericServlet.service() is roughly analagous to main() in a plain old java class.

Servlet runs inside a container(eg:tomcat). This container perform its work under jvm.
Here container takes "the absence of main method". In simlple java program main method tells
the starting control flow of the execution. But in case of servlet base web application jvm dose not need to search the main method. Servlet container tells jvm about the starting
control flow.

Servlet are deployed on Java application server (servlet container). They are kind of 'passive'. When you write servlet, your servlet code is called by the container whenever there's request or need. So you don't see 'main' in your servlet (the whole thing is not started from servlet), which is inside application server (you could imagine the startup of application server starts from some kind of main).

If you're looking for an area in a servlet to place code that's run on startup (similar to main()), take a look at implementing the ServletContextListener interface.
Its two methods are called on application startup and shutdown.

There is no main method in a Java servlet any more than than an ActionListener on a Swing JButton has a main method. What they both do have are methods that you can hook into when a certain event happens (a click on the JButton for example, or an HTTP PUT request on a HttpServlet). And in both cases, you are provided information about the event that triggered the call - the ActionEvent for the JButton and the ServletRequest for a servlet.
Thinking of servlets in terms of event handlers is probably more useful than trying to think of them like a standalone Java application where you are responsible for the entire control flow.

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

Life cycle management of servlet when SingleThreadModel is used

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?

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.

Clean up after servlet if init() failed

I have an Initializer class that implements the ServletContextListener interface. In its contextInitialized() method, I initialize some global classes that have to be destroyed, otherwise the servlet cannot be unloaded.
However, when the servlet's init() method throws a ServletException, the contextDestroyed() method never gets called --> resources are not release --> servlet does not get unloaded by Tomcat (it remains in "running" state even though its init method never finished).
My question is this - how do I cleanup the resources in this case?
Bonus: why does the servlet even get to "running" state? I understand from the documentation that it's not supposed to be running unless the init() method finishes successfully.
Edit - I think this is because each status line displayed in Tomcat Manager represents an entire war, and not a servlet. A war may contain several servlets, with some succeeding to start and others not. The Initializer is called when the container starts, and its destroy is called only when the entire container is dropped. This leads to a related question - is there a similar built-in way to monitor the state of individual servlets?
(I'm aware I can write custom code to monitor the servlet, either via JMX, or not, but that's out of the scope of
this question).
As far as I can tell there's absolutely no way to do so without an external request. ServletContextListener gives you the correct signal (when all servlets have been initialized - successfully or not), but you can't enumerate all servlets in the context to test their status because the relevant ServletContext methods were deprecated and now return an empty enumerator.
In short, the only way to do this is via a nonstandard API; in particular, it's almost trivial to do this with Tomcat's JMX API, which is the course I'd recommend.
In real world the init() should never fail. If it fails, then it is a programming error which the developer is supposed to fix. The appserver webcontainer has nothing to do with it. The servlet will simply be kept unavailable.
What container are you running?
Tomcat for example does support JMX. You can always write your own JMX-beans.

How to approach shifting a Java Swing app to a Servlet?

I want to use the Model-View-Controller template while writing my Web App. The problem is, the Model part of the code has already been written in Swing. The Model code also must require the container to call its main method before any interaction with its servlets. So is there a way for me to specify the location of the main method in the Deployment Descriptor so that the container calls the main method and compiles the code, and then, keeps it running for the entire duration the server is running without in any way restarting or recompiling the model class in between.
Try looking into load-on-startup parameter of servlet in Deployment Descriptor (DD). Precisely, it will load that particular servlet on server start-up.
Moreover, you should read about request lifecycle, request/session/application context. And you must look into JSP (or any other popular technology) for creating V of MVC. How URL mapping works.
Main method is basically work as an entry point in our application. Whereas in web application there is no particular entry point. Or if there is you can think of a welcome page. You might also want to look into welcome-file-list parameter of DD.
Cheers.
To run initialization when a web app is loaded, you can either use the servlet's init method or a ServletContextListener. You can call the main method from either of those yourself.

Categories