Java IoT Authors: Elizabeth White, Liz McMillan, Pat Romanski, Roger Strukhoff, Yeshim Deniz

Related Topics: Java IoT

Java IoT: Article

Java Servlets: Part 2 Design Practices

Java Servlets: Part 2 Design Practices

The Java servlet API specifies a very lightweight framework for developing Web applications. Although servlet technology is just one of the building blocks in the J2EE architecture, developers often use servlets to build full-fledged Web applications. Today several vendors and organizations provide servers and containers that implement the servlet API. For an overview of the servlet programming model, and some of the advanced features of Java servlets, refer to Part 1 of this article (JDJ, Vol. 5, issue 2).

As a lightweight framework, the servlet API doesn't impose a very strict programming model. Specifically, the API specification leaves certain design decisions to the developers. The servlet specification also added and withdrew (deprecated) certain features over its evolution. Unfortunately, though such deprecation was necessary to bring robustness to the servlet model, such changes sometimes cultivated incorrect programming practices. In addition, container vendors follow different models for implementing the API specification. In such a scenario it's essential for servlet programmers to be careful while making assumptions regarding those aspects that aren't covered by the servlet specification.

In this article I'd like to conduct an analysis of some of the design practices that servlet developers often undertake while developing Web applications. I draw some of the inputs for this article from the archives of the Servlet Interest Mailing List. Note: Some of the practices may not affect small-scale Web applications. The focus of my article is on servlets for large-scale Web applications that are required to be portable and scalable. While discussing these practices, I assume the containers will provide advanced features such as clustering, failover, and more.

Explicit Servlet Instantiation
This is a novice practice. Experienced programmers would probably snub me for mentioning this because they never do it. Nonetheless, allow me to elaborate on why you shouldn't instantiate servlets explicitly.

In brief, the hosting servlet container creates servlet instances. Instances created explicitly by applications can't receive HTTP requests from clients.

A servlet container creates servlet instances in response to HTTP requests. As discussed in Part 1 of this article, the purpose of a container is to receive HTTP requests, construct or locate a servlet instance, construct the environment for the servlet instance (a ServletContext), construct the request and response objects (the HttpServletRequest and HttpServletResponse objects), and delegate the incoming request to the servlet instance.

The key point here is that it's the servlet container's responsibility (and prerogative) to create servlet instances and delegate requests. Both the threading model that the developer follows and the instantiation model implemented by servlet containers dictate how and when servlet instances are created.

If a servlet implements the SingleThreadModel interface, the servlet container delegates each concurrent request to a different servlet instance or serializes incoming requests so that a single instance handles all the incoming requests, one after the other. If your LoginServlet implements the SingleThreadModel interface and there are five concurrent requests to this servlet, there are two possibilities. The first is that the container will delegate these five requests to five different instances of the LoginServlet. Alternatively, each of these login requests will be handled in series by just one instance. Once all the requests are served, the container may hold the instance(s) in a pool and reuse them for future requests.

For servlets that don't implement the SingleThreadModel interface, the instantiation policy depends on the container implementation. While some containers maintain a pool of instances, with each instance handling requests in different threads, some other containers delegate all requests in different threads to just one instance. However, the new Java Servlet API 2.2 specification mandates that a container must maintain one instance per servlet per Java Virtual Machine in an application.

Servlet instances are created and destroyed according to the policies . There's nothing that actually prevents you from creating a servlet instance as long as the LoginServlet class is available in the container's class path. Such an instance will be independent of the host servlet container. The container can't know about it. It can't manage the life cycle of such an instance. You're probably loading the servlet container in some unwanted way.

What's Wrong with Instance Variables?
What's wrong with instance variables in servlets? After all, servlets are normal Java objects. Well, yes, they are normal Java objects. But the servlet container manages them and that makes all the difference.

There are at least two reasons why a servlet developer would want to have instance variables in a servlet. One is to store request-specific state (e.g., state pertaining to a user session including any conversational state); the second is to store state that's common to several requests (e.g., application state).

In either case servlet instance variables are not the best solution for handling state. Let me rule it out completely before we discuss better solutions provided by the specification.

In addition to the container's instantiation model and the servlet's threading model discussed above, two more issues are to be considered here:

  1. Clustering and load balancing: As discussed in Part 1, if your container provides clustering facilities, you can mark your Web applications as distributable. In this case the container instantiates the servlets in multiple JVMs. Although the servlet specification requires a sticky load-balancing strategy, container vendors may choose to implement instance-independent load balancing with distributed sessions and state. In such cases there's no guarantee that all requests from the same client session will be handled by the same JVM, and hence the same set of instances.
  2. Swapping user sessions: Containers are free to swap user sessions and the associated load from one node to another in a cluster. In case of failure - say, a crash - of one JVM on one host, the cluster can also be configured to shift the load (and the session data) to another JVM (failover) or to restart the failed node.
Thus there's no guarantee that the same servlet instance will receive all the requests (from one user or all users) in a Web application.

Therefore, if not by specification, servlets are stateless by implication.
What's the solution for handling state?

The best solution for handling request-specific state is to store it in the HttpSession object associated with the request. In the case of distributable servlet applications, the Servlet API 2.2 specification mandates that such state be serializable. It's good practice to ensure that all your session variables are serializable whether your application is distributable or not. Who knows? When your user base increases, you may want your Web application to be distributable.

For handling application-specific state (say, a list of addresses that's common to all users), servlet containers provide you with a ServletContext object. This object is similar to HttpSession in functionality. The main difference is that while an HttpSession object is specific to a client session, a ServletContext object is specific to a Web application on a given container. Irrespective of user sessions, all servlets in a Web application in a given container can access and share information via a ServletContext object.

What happens if your application is distributable and you want your application state stored in the ServletContext object to be shared across containers in a cluster? The servlet API doesn't provide for this.

The specification doesn't guarantee any kind of persistence of the state information (whether you store it in HttpSession or in ServletContext objects). In case you require persistent state management, it's better to devise your own mechanism, using some external data storage (files or databases), or delegate this to some other back-end component or system. Alternatively, check with your container vendor.

What about using static variables in servlets? There are three points to consider:

  1. Are your static variables read-only? If not, you need to synchronize while updating such variables.
  2. In case your static variables aren't read-only, you should also consider the effects of the distribution of the application. How do you make sure that static variables in different JVMs are consistent?
  3. How do you protect your static variables/methods from other Web applications deployed on the same container (and JVM)?
To avoid these issues, consider storing such data in ServletContext objects.

SingleThreadModel - Why? And Why Not?
When and why should you implement the SingleThreadModel interface? This is a dilemma often faced by servlet developers.

Let me address the why part first.

Your servlets may implement the SingleThreadModel interface to make them (but not necessarily the resources that your servlets access) thread-safe. To quote from the API documentation: "If a servlet implements this interface, you are guaranteed that no two threads will execute concurrently in the servlet's service method. The servlet container can make this guarantee by synchronizing access to a single instance of the servlet, or by maintaining a pool of servlet instances and dispatching each new request to a free servlet."

Thus the specification guarantees that an instance of a SingleThreadModel servlet handles one incoming HTTP request at a time. Your servlets should implement this interface if you want to protect instance variables and other nonshareable resources from multiple request threads. But this doesn't guarantee that requests to a SingleThreadModel servlet will be handled sequentially. As discussed above, this is implementation-specific. Don't expect a "hit counter" servlet to work with a SingleThreadModel. This doesn't suffice.

The same effect can be achieved by synchronizing the various entry points (methods such as init(), service(), destroy(), etc.) into a servlet instance from the container. In this case the specification requires that containers serialize requests to that servlet instance instead of creating an instance pool, as is done in the case of SingleThreadModel servlets. However, you may not be required to take such an extreme step. For performance reasons it's better to narrow down the synchronization blocks in your code.

To summarize: three threading scenarios are possible (see Table 1).

What About Connection Pools?
How do you manage connections to databases and other resources/systems in a servlet-based Web application?

First, why do you need connection pooling? It saves the connection creation and disposal overheads. Once your application gets a connection to a relational database and finishes processing the database updates, it's better if it retains the connection object for future use. For efficient resource utilization you need connection pooling, which is a mechanism for recycling your connection objects.

Let's now examine some typical connection pooling strategies that servlet developers adopt. I draw these strategies from Java Servlet Programming and from various discussions from the Archives of the Servlet Interest Mailing List.

Connection Object as an Instance Variable
In this approach each servlet maintains its own connection object as an instance variable. The connection object is usually created in the init() method of the servlet. Thus each instance of the servlet holds a connection object. Look at the sample code in Listing 1. This approach is adequate for nontransactional database updates in the autocommit mode, since connection objects are specified to be thread-safe. But what happens if you want to implement multiple updates/inserts within a single transaction?

In the case of transactions your database server will associate each connection object with a single transaction. Consider the case of a servlet implementing a transaction. If an instance of this servlet is processing two concurrent requests in different threads, your transactions get mixed up. Instead of two transactions (as you'd expect), the database sees only one. Try the Java program in Listing 2. The TestThread class emulates a servlet instance processing two concurrent requests. In this class two threads are trying to do different transactions in two threads on the same connection object. You'll find that only those updates that occur after the rollback in the second thread will be committed to the database. Try it with different sleep intervals. The result? This approach doesn't preserve atomicity of transactions.

You can avoid this by synchronizing the transactional calls on the connection object as a group (try synchronizing the transact() method in Listing 2) or by implementing the SingleThreadModel interface, but your servlets will be penalized in terms of performance.

This solution isn't safe for transactional database access.

Connection Object Held in HttpSession
Instead of holding the connection object as an instance variable, you may want to store it in the HttpSession associated with a client so that all servlets serving a client may reuse the connection object. However, you should consider the following here:

  • What happens if your servlet container chooses to serialize some of the session objects to conserve memory or to shift the load from one JVM to another in the same cluster? The serialization process would fail since connection objects aren't serializable.
  • In case your application is distributable, the container requires that the session variables be serializable. If you try to pass a connection object to the HttpSession, the container may throw an IllegalArgumentException.
  • What happens if your application is serving a thousand concurrent users? Your application would attempt to get a thousand connection objects from your database server.
As you can see, the foregoing solution isn't appropriate for developing production quality applications.

Connection Pool Managers
Another widely used solution for connection pooling is to develop a connection pool manager. Such a manager can take at least three forms: a singleton, a static class or a servlet with static attributes/methods. In all these cases the manager class would provide accessor methods to manage a pool of connection objects.

This solution may open up a major security breach because such a manager class/object is accessible from all servlets within the same JVM. If your servlet container is hosting multiple applications, there's nothing to prevent a rogue servlet from getting hold of one of the connection objects and destroying your database tables. Be wary of such a solution. You may need to provide an additional security mechanism (using the protection domains and principles of Java 2 security architecture) for returning connection objects only to trusted objects.

The DBConnectionBroker toolkit from Java Exchange recommends an alternative approach to the use of connection pool manager. This toolkit provides a DBConnectionBroker class to implement a connection manager and an HttpServletJXGB servlet that holds it as a static protected variable. This servlet is supposed to serve as a base class for all your servlets requiring database access. Instances of the derived servlet classes can therefore make use of the connection pool manager. In servlet containers before version 2.2, if servlets from multiple applications deployed on the same JVM extend from the same HttpServletJXGB class, there's still scope for the security issue mentioned above.

JDBC 2.0 Optional Package Extension API
This Optional Package Extension API has several enhancements over the standard JDBC API. One of the enhancements is connection pooling. In this API the getConnection() method of the javax.sql.DataSource class returns connection objects. Depending on how the DataSource class is implemented, the getConnection method can return pooled connections. A significant implication of this approach is that the responsibility of connection pooling is delegated to the driver implementer. In addition to the above API, some of the JDBC driver vendors also implement connection pooling. Check the list of vendors at http://java.sun.com/products/jdbc/drivers.html.

Of all the approaches discussed in this section, database drivers complying with the JDBC 2.0 Optional Package Extension API offer the most robust solution for connection pooling.

Servlets and Operating Environment Resources
Application Threads

Can a servlet start new threads? Not in all cases, as discussed below. The environment in which servlet instances operate is guaranteed to be valid only during the course of a client request, that is, during the service() method. This environment includes the HttpSession, ServletContext, HttpServletRequest and HttpServletResponse objects. Make sure your application threads don't refer to these objects beyond the context of the service() method. In case you need specific information from these objects, consider copying such data into temporary objects (defined to suit your requirements) before starting any thread, and program the threads to use data from these temporary objects.

As indicated in the Servlet Specification 2.2, a servlet container may impose additional security restrictions on the accessing resources in the servlet environment. These resources include the JVM (threads, etc.), network, file system, and more. Although none of the container vendors seem to be moving in this direction currently, we can expect such restrictions from specialized servlet containers or domain-specific e-commerce products.

File System
The servlet specification doesn't guarantee any specific "current working directory" from which you can access text files, configuration files, images, and so on. Two approaches can guarantee container-independent file system access. The first approach is to keep all such resources accessible to the class path, and use the getResource() or getResourceAsStream() methods of the class loader to get the URL or an InputStream corresponding to resources. Alternatively, you can store the absolute locations of such resources on the file system as initialization (init-param) or context (context-param) entries in the associated deployment descriptor.

As Douglas Bennet points out, software is soft because of the soft programming constructs used to build software. There are many ways to implement a piece of functionality and many ways to use an API. Although most of these ways might work, not all of them may be resilient to changes. It's not always easy to grasp the implications of our designs, and there's always scope for debate. Nonetheless, there are better means to be considered that lead to better applications.

In this article I discussed some of the design practices with Java servlets. While most of the discussion is based on the Java Servlet Specification v2.2, by no means is it complete. The particular practices chosen for this discussion were motivated more by the need to probe into the intricacies involved in servlet development than on the practices per se.


  1. Java Servlet Specification v2.2:
  2. Archives of Servlet-Interest Mailing List:
  3. Hunter, J., and Crawford, W. (1998). Java Servlet Programming. O'Reilly & Associates.
  4. Gamma, E., Helm,R., Johnson, R., and Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley.
  5. Db Connection Broker:
  6. The JDBC 2.0 Optional Package:
  7. Bennet, D.W., (1996). Hard Software: The Essential Tasks. Manning Publications.

More Stories By Dr. Subrahmanyam

Dr. Subrahmanyam is a technical consultant with the electronic
commerce division of Wipro Technologies, based in Bangalore, India.
You can visit him at his Web site, www.Subrahmanyam.com.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.

@ThingsExpo Stories
DevOpsSummit New York 2018, colocated with CloudEXPO | DXWorldEXPO New York 2018 will be held November 11-13, 2018, in New York City. Digital Transformation (DX) is a major focus with the introduction of DXWorldEXPO within the program. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive over the long term. A total of 88% of Fortune 500 companies from a generation ago are now out of bus...
Dion Hinchcliffe is an internationally recognized digital expert, bestselling book author, frequent keynote speaker, analyst, futurist, and transformation expert based in Washington, DC. He is currently Chief Strategy Officer at the industry-leading digital strategy and online community solutions firm, 7Summits.
DXWordEXPO New York 2018, colocated with CloudEXPO New York 2018 will be held November 11-13, 2018, in New York City and will bring together Cloud Computing, FinTech and Blockchain, Digital Transformation, Big Data, Internet of Things, DevOps, AI, Machine Learning and WebRTC to one location.
Widespread fragmentation is stalling the growth of the IIoT and making it difficult for partners to work together. The number of software platforms, apps, hardware and connectivity standards is creating paralysis among businesses that are afraid of being locked into a solution. EdgeX Foundry is unifying the community around a common IoT edge framework and an ecosystem of interoperable components.
Cloud-enabled transformation has evolved from cost saving measure to business innovation strategy -- one that combines the cloud with cognitive capabilities to drive market disruption. Learn how you can achieve the insight and agility you need to gain a competitive advantage. Industry-acclaimed CTO and cloud expert, Shankar Kalyana presents. Only the most exceptional IBMers are appointed with the rare distinction of IBM Fellow, the highest technical honor in the company. Shankar has also receive...
Enterprises have taken advantage of IoT to achieve important revenue and cost advantages. What is less apparent is how incumbent enterprises operating at scale have, following success with IoT, built analytic, operations management and software development capabilities - ranging from autonomous vehicles to manageable robotics installations. They have embraced these capabilities as if they were Silicon Valley startups.
DXWorldEXPO LLC announced today that ICOHOLDER named "Media Sponsor" of Miami Blockchain Event by FinTechEXPO. ICOHOLDER give you detailed information and help the community to invest in the trusty projects. Miami Blockchain Event by FinTechEXPO has opened its Call for Papers. The two-day event will present 20 top Blockchain experts. All speaking inquiries which covers the following information can be submitted by email to [email protected] Miami Blockchain Event by FinTechEXPO also offers s...
Poor data quality and analytics drive down business value. In fact, Gartner estimated that the average financial impact of poor data quality on organizations is $9.7 million per year. But bad data is much more than a cost center. By eroding trust in information, analytics and the business decisions based on these, it is a serious impediment to digital transformation.
Predicting the future has never been more challenging - not because of the lack of data but because of the flood of ungoverned and risk laden information. Microsoft states that 2.5 exabytes of data are created every day. Expectations and reliance on data are being pushed to the limits, as demands around hybrid options continue to grow.
The standardization of container runtimes and images has sparked the creation of an almost overwhelming number of new open source projects that build on and otherwise work with these specifications. Of course, there's Kubernetes, which orchestrates and manages collections of containers. It was one of the first and best-known examples of projects that make containers truly useful for production use. However, more recently, the container ecosystem has truly exploded. A service mesh like Istio addr...
Digital Transformation: Preparing Cloud & IoT Security for the Age of Artificial Intelligence. As automation and artificial intelligence (AI) power solution development and delivery, many businesses need to build backend cloud capabilities. Well-poised organizations, marketing smart devices with AI and BlockChain capabilities prepare to refine compliance and regulatory capabilities in 2018. Volumes of health, financial, technical and privacy data, along with tightening compliance requirements by...
As IoT continues to increase momentum, so does the associated risk. Secure Device Lifecycle Management (DLM) is ranked as one of the most important technology areas of IoT. Driving this trend is the realization that secure support for IoT devices provides companies the ability to deliver high-quality, reliable, secure offerings faster, create new revenue streams, and reduce support costs, all while building a competitive advantage in their markets. In this session, we will use customer use cases...
Business professionals no longer wonder if they'll migrate to the cloud; it's now a matter of when. The cloud environment has proved to be a major force in transitioning to an agile business model that enables quick decisions and fast implementation that solidify customer relationships. And when the cloud is combined with the power of cognitive computing, it drives innovation and transformation that achieves astounding competitive advantage.
Cloud Expo | DXWorld Expo have announced the conference tracks for Cloud Expo 2018. Cloud Expo will be held June 5-7, 2018, at the Javits Center in New York City, and November 6-8, 2018, at the Santa Clara Convention Center, Santa Clara, CA. Digital Transformation (DX) is a major focus with the introduction of DX Expo within the program. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive ov...
DXWorldEXPO | CloudEXPO are the world's most influential, independent events where Cloud Computing was coined and where technology buyers and vendors meet to experience and discuss the big picture of Digital Transformation and all of the strategies, tactics, and tools they need to realize their goals. Sponsors of DXWorldEXPO | CloudEXPO benefit from unmatched branding, profile building and lead generation opportunities.
Digital Transformation and Disruption, Amazon Style - What You Can Learn. Chris Kocher is a co-founder of Grey Heron, a management and strategic marketing consulting firm. He has 25+ years in both strategic and hands-on operating experience helping executives and investors build revenues and shareholder value. He has consulted with over 130 companies on innovating with new business models, product strategies and monetization. Chris has held management positions at HP and Symantec in addition to ...
With 10 simultaneous tracks, keynotes, general sessions and targeted breakout classes, @CloudEXPO and DXWorldEXPO are two of the most important technology events of the year. Since its launch over eight years ago, @CloudEXPO and DXWorldEXPO have presented a rock star faculty as well as showcased hundreds of sponsors and exhibitors! In this blog post, we provide 7 tips on how, as part of our world-class faculty, you can deliver one of the most popular sessions at our events. But before reading...
The best way to leverage your Cloud Expo presence as a sponsor and exhibitor is to plan your news announcements around our events. The press covering Cloud Expo and @ThingsExpo will have access to these releases and will amplify your news announcements. More than two dozen Cloud companies either set deals at our shows or have announced their mergers and acquisitions at Cloud Expo. Product announcements during our show provide your company with the most reach through our targeted audiences.
The IoT Will Grow: In what might be the most obvious prediction of the decade, the IoT will continue to expand next year, with more and more devices coming online every single day. What isn’t so obvious about this prediction: where that growth will occur. The retail, healthcare, and industrial/supply chain industries will likely see the greatest growth. Forrester Research has predicted the IoT will become “the backbone” of customer value as it continues to grow. It is no surprise that retail is ...
Andrew Keys is Co-Founder of ConsenSys Enterprise. He comes to ConsenSys Enterprise with capital markets, technology and entrepreneurial experience. Previously, he worked for UBS investment bank in equities analysis. Later, he was responsible for the creation and distribution of life settlement products to hedge funds and investment banks. After, he co-founded a revenue cycle management company where he learned about Bitcoin and eventually Ethereal. Andrew's role at ConsenSys Enterprise is a mul...