Objectives
What are the stages in the life cycle of a servlet?
How do class loaders affect the behavior of the server?
Class files placed in this directory are automatically reloaded whenever they are updated. ( maybe )
Does not apply to related resources such as jars, gifs or helper classes.
Class files loaded by this class loader operate under special restrictions.
Servlets placed elsewhere in the server's CLASSPATH are loaded by the default class loader.
Not reloaded automatically whenever they are updated.
When is a servlet class actually loaded?
Prior to satisfying the first client request.
A closer look at the init method.
What is its purpose?
To initialize the state of the servlet prior to client access.
Initialize shared or static resources.
Identify or establish connections with external resources.
When is it called?
Prior to invoking the service method for the first client request.
How often is it called?
Once in the life of the servlet.
If the class file is modified using the special class loader, the servlet's destroy method will be invoked, then the servlet will be reloaded and its init method invoked again.
Are there any built in persistence mechanisms across servlet loads?
No.
The state of a servlet is not preserved when the servlet is shut down or the server crashes.
If you need persistence, you will have to build this functionality into the servlet yourself.
Can other clients invoke the service methods prior to completion of the init method?
No.
What does this imply about the thread-worthiness of the init method?
The init method is completely thread-safe.
What does an init method look like?
Review source code init
Key Elements :
Receiving the ServletConfig parameter - Line 2.
Provides information about the configuration of a servlet.
Servlet parameters configured from the web server.
Access to servlet context.
Implementation of this interface is provided by the web server.
Saving the ServletConfig for later use - Line 4.
ServletConfig contains information, access to which you may require later.
If you do not save it now, you will not be able to reclaim it later.
You can save it directly or you save it to your ancestor class by passing it on to the super.init method.
If you pass it to super.init, no other work is required.
If you declare it yourself, you must also override the getServletConfig method.
If you do not preserve the ServletConfig object, other API methods that rely on an initialized version of this variable (such as getInitParameter on line 7) will generate a NullPointerException.
Reading initialization parameters - Line 7
getInitParameter - Reads a designated parameter using the ServletConfig object.
getInitParameterNames - Reads all parameters using the ServletConfig object.
Name value pairs.
Where do these values come from?
Input into a web server tool by the user (configured within a Web Server - differs with web servers).
What do these values represent?
Application specific information such as file and directory information, system defaults, database names, RMI registry names, etc.
What does the service method do?
Actual service method invokes the corresponding do method. ( see page 17 of Hall and SUN)
Do method processes the form in its own service thread.
One thread for each client request.
Many concurrent threads, but only 1 servlet instance.
Does not execute for any client until init method has completed.
All service methods receive 2 parameters :
ServletRequest - Provides access to client input.
getParameter
Identity of the remote host.
ServletResponse - Provides a channel for a server response.
OutputStream
API methods to set headers.
setContentType
Therefore, class level variables (variables declared outside of the service methods) are NOT thread-safe.
Are servlets thread-safe?
What does the term thread-safe mean?
That critical sections of code that access data shared by several threads concurrently do not interrupt one another.
How is code made thread-safe?
Place critical sections of code in synchronized blocks or methods.
What are the recommended practices for making code thread-safe?
Make class level variables private.
Make variables that access external resources private.
Remember that one always has only one instance of a servlet, so Instance variables are all shared.
Provide getter methods to read the states of those variables and external resources.
Synchronize as needed.
Provide setter methods to write the states of those variables and external resources.
Synchronize as needed.
The need to synchronize setters generally exceeds the need to
synchronize getters.
Synchronize can only be applied to Objects and methods - not to primitives
What are the costs of making code thread-safe?
Performance.
Synchronization introduces blocking.
What can be done to optimize the performance of a thread-safe servlet?
Get in and out of the data as quickly as possible.
Do not do real-time IO within synchronized code blocks.
What does this interface do?
Each client executes a separate instance of the servlet, rather than a separate thread within a single servlet.
What are the benefits of this technique?
Each servlet has its own data, therefore changes made by 1 client do not affect another.
What are the costs of this technique?
It is useless if you want changes made by 1 client to affect another...no more shared data (back to CGI separate forks)
When might you use SingleThreadModel?
To synchronize access to a database, without the need for synchronized blocks. (Each servlet's connection could be handled as a separate transaction; the database equivalent of synchronized code).
A closer look at the destroy method. The destroy method should undo any initialization work and synchronize persistent data with the current in-memory state of the servlet.
What is its purpose?
To finalize a servlet, prior to termination.
Save state variables.
Close open streams / resources.
When is it called?
Manually, through the web server's administrative tool.
Automatically by the special class loader whenever a servlet's class file is modified.
It is not called in the face of a server crash.
It is not called programmatically. (no exit(0) for a servlet)
Manually, by the server administrator through a program
Prior to invoking the service method for the first client request.
How often is it called?
Once in the life of the servlet.
Are there any built in persistence mechanisms?
No.
The state of a servlet is not preserved when the servlet is shut down or the server crashes.
If you need persistence, you will have to build this functionality into the servlet yourself.
Can new clients invoke the service method while the destroy method is executing?
No.
What happens to existing service threads if the destroy method is invoked while they are executing?
Before the servlet container can call the destroy method, it must allow any threads that are currently running in the service method of the servlet to either complete, or exceed a server defined time limit.
Based on the aforementioned description, is the destroy method thread-safe?
No.
A timed out thread still lives and may contain state that needs to be protected.
What does a typical destroy method do?
Close resources.
Log Exceptions.
But what if you change one of the servlets that's in memory? Rather than restarting the server each time, we would like to have servlet reloading.
To get servlet reloading you need to set it for the server.
Example: Tomcat
When this option is on, Tomcat
checks to make sure the requested servlet in memory is the same as the one on
disk. Then, if the one on disk has been modified, it reloads the servlet before it
runs it. This means that you don't have to stop and restart Tomcat each time you
change a servlet.
To turn servlet reloading on, you add a line of code to the context.xml (or server.xml?) file
that's stored in Tomcat's conf directory. This XML file controls how Tomcat is
configured. Here are some notes from the Murach book to show how this is done.
Hmmm, interesting. Murach says to put it in the install_dir/conf/server.xml but Hall says in the install_dir/conf/context.xml
I suppose since the server looks at both it might not matter, but since context.xml actually has it listed there, I would probably use that one.
Review Delay.java which has a service method that handles incrementing the service counter each time it is entered and decrements the counter each time it returns.
And another - This uses SUNs suggested technique of a flag isShuttingDown for long running methods to check for status of the servlet (rather than stop, sleep, etc).
Summary of the four tasks involved in handling threads at service termination:
For more on the life cycle, see section 2.6 of Hall's book.
Or the J2EE servlet tutorial life cycle section - interesting use of Listeners to see what is happening