
A servlet is a Java class that run at the server end, it is instantiated when needed and destroyed when not needed by the Servlet container. The init() and destroy() methods of Servlet interface will allow us to know when a Servlet has been initialized or destroyed by the Servlet container, but the are more methods to know about.
The Java Servlet written in this test will print out a message in the web server's log during the following events: the class loading, the instantiation, the initialization, the service and on the destroying. Thanks to this messages, and playing with the Servlet container while looking at the server's log, we will see when each life cycle event occurs. This way, we will verify when the Servlet is loaded, when is instantiated, how the service is called for every request we make, and how the instance of the Servlet is destroyed when we undeploy the application.
Environment
Required software that has already been installed and configured on the system.
- Ubuntu 9.10
- JDK 6 Update 16
- Apache Ant 1.7.1
- Apache Tomcat 6.0.20
Exercise steps
Step 1 - The LifeCycleServlet Java Servlet
This is the Java source code of the Servlet. It has and static initialization block, which is executed during the class loading. The constructor, obviously called on the instantation of the object, and three publics methods inherited from the HttpServlet and the GenericHttpServlet classes.
package com.onewaytickettojava.jsid;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class LifeCycleServlet extends HttpServlet {
static {
System.out.println("" + System.currentTimeMillis() + " LifeCycleServlet: ClassLoading...");
}
public LifeCycleServlet() {
System.out.println("" + System.currentTimeMillis() + " LifeCycleServlet: Constructor...");
}
public void init() {
System.out.println("" + System.currentTimeMillis() + " LifeCycleServlet: Init...");
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<html><body><h1>Life Cycle Servlet</h1></body></html>");
System.out.println("" + System.currentTimeMillis() + " LifeCycleServlet: service...");
}
public void destroy() {
System.out.println("" + System.currentTimeMillis() + " LifeCycleServlet: destroy...");
}
}
LifeCycleServlet.javaThe Servlet container instantiates only one object to handle all the request to a Servlet. After calling the constructor, the container will call the Servlet's init(), it is typically used to create or load objects that are used by the servlet in the handling of its requests, this method is called only once during the life time of the Servlet and must be called before the servlet can service any requests. Once the Servlet is initialized, it can start serving requests, the service() method and it's broken down methods doGet(), doPost(), etc... will be called as many times as requests are received for the Servlet, remember that a new thread is created to service each request. Finally, the destroy() method, will be called when the web application is stopped, undeployed/removed or when the Servlet container shuts down.
Step 2 - The web.xml Deployment Descriptor
Nothing special here, just mapping the LifeCycleServlet with the /test path.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>LifeCycleTest</servlet-name>
<servlet-class>com.onewaytickettojava.jsid.LifeCycleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LifeCycleTest</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
</web-app>
web.xmlTo make it a little more interesting, we will change the Deployment Descriptor configuration to test the effects of the load-on-startup tag. The Java Servlet 2.5 Specification says the following:
The load-on-startup element indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the web application. The optional contents of these element must be an integer indicating the order in which the servlet should be loaded. If the value is a negative integer, or the element is not present, the container is free to load the servlet whenever it chooses. If the value is a positive integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-start-up value.
By setting the value of this tag to a positive number, we will tell the Servlet container to preload the Servlet when the web application is started.
<servlet> <servlet-name>LifeCycleTest</servlet-name> <servlet-class>com.onewaytickettojava.jsid.LifeCycleServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>web.xml
Test
First of all, we need to keep a view of the server's log during all the test. To achieve this, nothing better an easier than the tail command with the -f parameter to have a live view of the last lines of the Servlet container log. In this case we will see the five last lines, specified by the -n5 parameter. Previous to the tail command we will start the server.
~$ tomcat start Using CATALINA_BASE: /home/me/lab/servers/tomcat Using CATALINA_HOME: /home/me/lab/servers/tomcat Using CATALINA_TMPDIR: /home/me/lab/servers/tomcat/temp Using JRE_HOME: /home/me/lab/jvm/java-6-sun Tomcat started. ~$ tail -f -n5 $CATALINA_HOME/logs/catalina.outTerminal
Servlet class loading
As pointed before, there are two options, two Deployment Descriptors to test, which will produce two different outputs.
INFO: Server startup in 567 ms Dec 31, 2009 7:33:54 PM org.apache.catalina.startup.HostConfig checkResources INFO: Undeploying context [/ServletLifeCycle] Dec 31, 2009 7:33:54 PM org.apache.catalina.startup.HostConfig deployWAR INFO: Deploying web application archive ServletLifeCycle.warTerminal - Output produced by the DD without the load-on-startup element.
With the Tomcat server started, we will deploy the ServletLifeCycle web application which do not have the load-on-startup element defined with the ant deploy command. Nothing happens, because the LifeCycleServlet has not been requested, it has not been instantiated neither loaded. However, if we deploy the web application with the web.xml configuration with a positive value inside the load-on-start-up element, the Servlet is loaded, instantiated and its init() method called, just as the Java Servlet Specification defines.
Dec 31, 2009 7:27:05 PM org.apache.catalina.startup.HostConfig deployWAR INFO: Deploying web application archive ServletLifeCycle.war 1262284025786 LifeCycleServlet: ClassLoading... 1262284025786 LifeCycleServlet: Constructor... 1262284025787 LifeCycleServlet: Init...Terminal - Output produced by the DD with the load-on-startup element.
Instantiation, Initialization and service()
If the Servlet has not been loaded yet, it will be loaded and an instance of this class will be created as soon as a request is received for it by the Servlet Container. Visit: http://localhost:8080/ServletLifeCycle/test.
Dec 31, 2009 7:33:54 PM org.apache.catalina.startup.HostConfig deployWAR INFO: Deploying web application archive ServletLifeCycle.war 1262284507405 LifeCycleServlet: ClassLoading... 1262284507405 LifeCycleServlet: Constructor... 1262284507406 LifeCycleServlet: Init... 1262284507406 LifeCycleServlet: service...Terminal
Every time we refresh the browser (F5), a new request to the LifeCycleServlet is sent, so the service method doGet() is called.
Dec 31, 2009 7:33:54 PM org.apache.catalina.startup.HostConfig deployWAR INFO: Deploying web application archive ServletLifeCycle.war 1262284507405 LifeCycleServlet: ClassLoading... 1262284507405 LifeCycleServlet: Constructor... 1262284507406 LifeCycleServlet: Init... 1262284507406 LifeCycleServlet: service... 1262284520587 LifeCycleServlet: service... 1262284521127 LifeCycleServlet: service... 1262284521543 LifeCycleServlet: service...Terminal
Servlet Destruction
When the application is stopped, removed/undeployed or the Servlet container shuts down, your Servlet's destroy() method will be called. This allows to free any resources obtained inside the Servlet's init() method.
1262284520587 LifeCycleServlet: service... 1262284521127 LifeCycleServlet: service... 1262284521543 LifeCycleServlet: service... 1262284625307 LifeCycleServlet: destroy... Dec 31, 2009 7:37:05 PM org.apache.catalina.startup.HostConfig checkResources INFO: Undeploying context [/ServletLifeCycle]Terminal
There are more cases to try. So if you want to find out more about the Servlet life cycle, keep playing with the Server container and the web.xml configuration file.
Test files
Files used during the test. Click on the file to download it (do not use "Save Link As...").
- ServletLifeCycle.tar.gz - Java Servlet source file, JSPs, web.xml and build.xml Ant script file.
- ServletLifeCycle.war - Deployable Web application archive.



0 comments
Be the first to write a comment!
Post a Comment