Java & J2EE Programming Best Practices
_
Best Practice 1 - Do not store large object graphs in HttpSession
Large applications require using persistent HttpSessions. However, there is a cost. An HttpSession must be read by the servlet whenever it is used and rewritten whenever it is updated. This involves serializing the data and reading it from and writing it to a database. In most applications, each servlet requires only a fraction of the total session data. However, by storing the data in the HttpSession as one large object, an application forces Application Server to process the entire HttpSession object each time.
JDBC alternative to Using HttpSession Data for Storing Servlet State Data
In most applications, each servlet needs only a fraction of the entire application’s state data. As an alternative to storing the entire object in the HttpSession, use JDBC for partitioning and maintaining the state data needed by each servlet in the application.
Best Practice 2 - Release HttpSessions when finished
HttpSession objects live inside the web container (Web server/App Server) servlet engine until:
The application explicitly and programmatically releases it using the API, javax.servlet.http.HttpSession.invalidate(); quite often, programmatic invalidation is part of an application logout function.
WebServer/Application Server destroys the allocated HttpSession when it expires (by default, after 1800 seconds or 30 minutes). A Server can only maintain a certain number of HttpSessions in memory. When this limit is reached, Application Server serializes and swaps the allocated HttpSession to disk. In a high volume system, the cost of serializing many abandoned HttpSessions can be quite high.
Best Practice 3 - Do not create HttpSessions in JSPs by default
By default, JSP files create HttpSessions. This is in compliance with J2EE to facilitate the use of JSP implicit objects, which can be referenced in JSP source and tags without explicit declaration. HttpSession is one of those objects. If you do not use HttpSession in your JSP files, then you can save some performance overhead with the following JSP page directive:
<%@ page session="false"%>
Note: Do not load a session with heavy objects. Instead of using a session object, create a cache object, which can hold application data. The cache object can include all the application’s static data and user specific data. An application level cache object will be loaded during the application startup and user specific data will be loaded when the user logs into the application. User specific data will be available with the cache object while the user’s session is alive.
Best Practice 4 - Minimize synchronization in Servlets
Servlets are multi-threaded. Servlet-based applications have to recognize and handle this. However, if large sections of code are synchronized, an application effectively becomes single threaded, and throughput decreases.
Best Practice 5 - Do not use SingleThreadModel
SingleThreadModel is a tag interface that a servlet can implement to transfer its reentrancy problem to the servlet engine. As such, javax.servlet.SingleThreadModel is part of the J2EE specification. The web/application servlet engine handles the servlet’s reentrancy problem by creating separate servlet instances for each user. Because this causes a great amount of system overhead, SingleThreadModel should be avoided.
Developers typically use javax.servlet.SingleThreadModel to protect updateable servlet instances in a multithreaded environment. The better approach is to avoid using servlet instance variables that are updated from the servlet’s service method.
Best Practice 6 - Use JDBC connection pooling
To avoid the overhead of acquiring and closing JDBC connections, Application Server provides JDBC connection pooling based on JDBC 2.0. Servlets should use Application Server JDBC connection pooling instead of acquiring these connections directly from the JDBC driver. Application Server JDBC connection pooling involves the use of javax.sql.DataSources.
Best Practice 7 - Reuse datasources for JDBC connections
A javax.sql.DataSource is obtained from Application Server through a JNDI naming lookup. Avoid the overhead of acquiring a javax.sql.DataSource for each SQL access. This is an expensive operation that will severely impact the performance and scalability of the application. Instead, servlets should acquire the javax.sql.DataSource in the Servlet.init() method (or some other thread-safe method) and maintain it in a common location for reuse.
Best Practice 8 - Release JDBC resources when done
Failing to close and release JDBC connections can cause other users to experience long waits for connections. Although a JDBC connection that is left unclosed will be reaped and returned by Application Server after a timeout period, others may have to wait for this to occur.
Close JDBC statements when you are through with them. JDBC ResultSets can be explicitly closed as well. If not explicitly closed, ResultsSets are released - then their associated statements are closed. Ensure that your code is structured to close and release JDBC resources in all cases, even in exception and error conditions.
Large applications require using persistent HttpSessions. However, there is a cost. An HttpSession must be read by the servlet whenever it is used and rewritten whenever it is updated. This involves serializing the data and reading it from and writing it to a database. In most applications, each servlet requires only a fraction of the total session data. However, by storing the data in the HttpSession as one large object, an application forces Application Server to process the entire HttpSession object each time.
JDBC alternative to Using HttpSession Data for Storing Servlet State Data
In most applications, each servlet needs only a fraction of the entire application’s state data. As an alternative to storing the entire object in the HttpSession, use JDBC for partitioning and maintaining the state data needed by each servlet in the application.
Best Practice 2 - Release HttpSessions when finished
HttpSession objects live inside the web container (Web server/App Server) servlet engine until:
The application explicitly and programmatically releases it using the API, javax.servlet.http.HttpSession.invalidate(); quite often, programmatic invalidation is part of an application logout function.
WebServer/Application Server destroys the allocated HttpSession when it expires (by default, after 1800 seconds or 30 minutes). A Server can only maintain a certain number of HttpSessions in memory. When this limit is reached, Application Server serializes and swaps the allocated HttpSession to disk. In a high volume system, the cost of serializing many abandoned HttpSessions can be quite high.
Best Practice 3 - Do not create HttpSessions in JSPs by default
By default, JSP files create HttpSessions. This is in compliance with J2EE to facilitate the use of JSP implicit objects, which can be referenced in JSP source and tags without explicit declaration. HttpSession is one of those objects. If you do not use HttpSession in your JSP files, then you can save some performance overhead with the following JSP page directive:
<%@ page session="false"%>
Note: Do not load a session with heavy objects. Instead of using a session object, create a cache object, which can hold application data. The cache object can include all the application’s static data and user specific data. An application level cache object will be loaded during the application startup and user specific data will be loaded when the user logs into the application. User specific data will be available with the cache object while the user’s session is alive.
Best Practice 4 - Minimize synchronization in Servlets
Servlets are multi-threaded. Servlet-based applications have to recognize and handle this. However, if large sections of code are synchronized, an application effectively becomes single threaded, and throughput decreases.
Best Practice 5 - Do not use SingleThreadModel
SingleThreadModel is a tag interface that a servlet can implement to transfer its reentrancy problem to the servlet engine. As such, javax.servlet.SingleThreadModel is part of the J2EE specification. The web/application servlet engine handles the servlet’s reentrancy problem by creating separate servlet instances for each user. Because this causes a great amount of system overhead, SingleThreadModel should be avoided.
Developers typically use javax.servlet.SingleThreadModel to protect updateable servlet instances in a multithreaded environment. The better approach is to avoid using servlet instance variables that are updated from the servlet’s service method.
Best Practice 6 - Use JDBC connection pooling
To avoid the overhead of acquiring and closing JDBC connections, Application Server provides JDBC connection pooling based on JDBC 2.0. Servlets should use Application Server JDBC connection pooling instead of acquiring these connections directly from the JDBC driver. Application Server JDBC connection pooling involves the use of javax.sql.DataSources.
Best Practice 7 - Reuse datasources for JDBC connections
A javax.sql.DataSource is obtained from Application Server through a JNDI naming lookup. Avoid the overhead of acquiring a javax.sql.DataSource for each SQL access. This is an expensive operation that will severely impact the performance and scalability of the application. Instead, servlets should acquire the javax.sql.DataSource in the Servlet.init() method (or some other thread-safe method) and maintain it in a common location for reuse.
Best Practice 8 - Release JDBC resources when done
Failing to close and release JDBC connections can cause other users to experience long waits for connections. Although a JDBC connection that is left unclosed will be reaped and returned by Application Server after a timeout period, others may have to wait for this to occur.
Close JDBC statements when you are through with them. JDBC ResultSets can be explicitly closed as well. If not explicitly closed, ResultsSets are released - then their associated statements are closed. Ensure that your code is structured to close and release JDBC resources in all cases, even in exception and error conditions.