by S. Sangeetha and S. V. Subrahmanya

Adopting Struts 2.0

feature
Oct 11, 200724 mins

The framework for the next generation of Java Web applications

While the Struts framework has been widely deployed, there’s no doubt that its original version held room for improvement. The newly released Struts 2.0 carries much of the power of its predecessor but is simpler for developers to use. In this article, S. Sangeetha and S. V. Subrahmanya outline the changes in Struts 2.0 and offer migration pointers for developers familiar with the Struts framework.

Apache Struts is a very popular Web framework for developing Web applications using Java Enterprise Edition (JEE). The Apache Struts Project is the open source community that develops and maintains the Struts framework. Apache Struts (or simply Struts) was released in July 2001. Since its release, it has become the de facto standard for building Web applications using JEE.

The recently released Struts 2.0 is an elegant, extensible framework for building enterprise-ready Web applications using Java code. The framework is designed to streamline the development cycle, from building to deploying to maintaining applications over time. Following an in-depth introduction to the architecture of Struts 2, you’ll examine code samples that illustrate its advances over Struts 1.0, and get some tips for migrating and integrating code written for the earlier Struts framework with Struts 2.0.

This article assumes prior familiarity with Struts 1.0. If you are familiar with Model-View-Controller (MVC)-based Web development but haven’t used Struts before, you may want to read “Struts 2.0 in action” (JavaWorld, October 2007) to learn the basics of Java Web application development using the Struts framework.

A brief history of Struts 2.0

The Struts framework was created so that developers could build servlets or JavaServer Pages in which database code, page design code and control flow code were not co-mingled. Applications that have code intermixed in this way become difficult to maintain as they grow larger. The Struts framework is based on the MVC architecture, which helps developers create dynamic Web applications with clear separation of concerns.

The Struts framework provides its own Web controller component for handling control-flow logic. For the view, it integrates with other technologies, such as JavaServer Pages (including JSTL and JSF), Velocity Template Engine and XSLT. For the model, it uses technologies such as JDBC, EJB, Hibernate or iBATIS for data access.

Struts 1.0 is mature, well supported by a large developer community, and widely documented. But over the last few years, a lot of open source community Web frameworks have come onto the scene, and there’s been a need to keep up with the changing requirements for Web applications; thus, there has been an impetus for the creation of the next generation of the Struts framework. The initial proposal that sought to fill this need was Struts Ti, a simplified Model 2 framework for developing Web applications for those who are in need of less configuration and better structure and controller features. Another framework that was considered for this purpose was Apache Shale; however, Shale is a component-based framework that is based on JSF. The Shale developer community was hesitant to unify with Struts and has decided to continue developing Shale as a separate top-level project.

The WebWork project was started by the Open Symphony community and was aimed at the Struts developer community. It catered to the needs of people who were looking for a framework similar to Struts but with better features. The WebWork framework was released in 2002. After working independently for several years, the WebWork and Struts communities joined forces in December 2005 to create a new version of Struts; in essence, Struts 2 is Struts 1 plus WebWork. The new version of Struts is simpler to use, and closer to the original vision for the Struts framework.

Struts 2.0 features and architecture

A number of the new features introduced in the Struts 2.0 framework work towards the goal of making Struts simpler to use:

  • Improved design: In contrast with Struts 1, all of the Struts 2 classes are based on interfaces. Core interfaces are HTTP independent. These APIs are not dependent on Servlet APIs.

  • Simplified Actions: Struts 2 Action classes are framework independent and are simplified plain old Java objects (POJO). Any Java class with an execute() method can be used as an Action class.

  • POJO forms: Struts 2 does not support the ActionForms feature. The properties that are defined in the ActionForms can be put directly on the Action classes. You do not need to use all String properties.

  • Intelligent defaults: Most of the configuration elements in the Struts 2 configuration file will have default values, so there is no need to set values unless a different value is required. This helps reduce the configuration you need to do in the XML file. Struts 2’s support for annotations helps make this even easier to achieve.

  • Enhanced results: In Struts 2, the >forward< tag is replaced by the <result> tags. Unlike ActionForwards, Struts 2 results help in preparing the response and provide flexibility to create multiple types of output.

  • Enhanced tags: Struts 2 tags don’t just send output data, but also provide stylesheet-driven markup so that you can create consistent pages with less code. Struts 2 tags can now work with FreeMarker, Velocity, and similar template engines.

  • Introduction of interceptors: Struts 2 provides exhaustive support for interceptors. Interceptors can be executed before and after an Action class is executed. Interceptors are configured to apply common functionality, such as workflow or validation, to a request. All the requests pass through a set of interceptors before they are sent to an Action class. After the Action class is executed, the request passes through the interceptors again in the reverse order.

  • Ajax support: To create dynamic Web applications that use Ajax, Struts 2 provides an Ajax theme, which gives interactive applications a significant boost. Struts 2 tags for Ajax are based on Dojo widgets. Plug-ins are available for other frameworks as well.

  • QuickStart: Deployed configuration files are reloadable; hence, many changes can be made on the fly without the need to restart the Web container.

  • Stateful checkboxes: The Struts 2 framework automatically tracks checkboxes; if a checkbox is missing, the default value — false — is assumed. Hence, unlike in Struts 1, checkboxes do not require special handling for false values.

  • Easy testing: Struts 2 Actions are HTTP independent and thus framework neutral. They can be tested easily without using mock objects.

  • Use of annotations: Applications built using Struts 2 can use Java 5 annotations as an alternative to XML and Java properties configuration. Annotations minimize the need for XML. Annotations are available for Actions, interceptors, validation and type conversion.

  • Easy plug-in: Struts 2 extensions can be installed by dropping the plug-in JAR file into the WEB-INFlib directory. No manual configuration is required.

  • Easy integration with Spring: Struts 2 Actions are Spring-aware. Just adding Spring beans to an application will add Spring support.

  • Easily customized controllers: Struts 1 allows the request processor to be customized per module; in Struts 2, you can customize the request handling per action, if required.

Struts 2 architecture basics

As noted in the introduction, the Struts framework is based on the MVC architecture. Struts 2 is a flexible control layer based on standard technologies such as Java filters, JavaBeans, ResourceBundles, Locales and XML, as well as various Open Symphony packages like OGNL and XWork.

For the model, the framework can interact with standard data access technologies such as JDBC, EJB, and other frameworks, including Hibernate, iBATIS and Cayenne.

For the view, the framework can use JavaServer Pages (including JSTL and JSF), Velocity templates, PDF, XSLT and FreeMarker.

In addition to the Actions and results, the Struts framework provides support for exception handlers and interceptors.

Exception handlers declare the exception handling procedure for defining a global exception and a local exception. There is no need to write try/catch blocks in the code; rather, the framework makes the exception handling easier. The framework catches each exception and displays a page with an appropriate message and exception details.

Interceptors specify the request-processing life cycle for an action. Interceptors specify the sequence of actions that happen before and after the Action class is executed. As noted, interceptors are configured to apply common functionality to a request. Most of the framework’s core functionality is implemented as interceptors. If some actions respond to Ajax, SOAP or JSF requests, the life cycle can be simplified in such a way that the request can simply pass through interceptors without any execution.

Struts 2 request processing flow

How does this architecture work in practice? An initial request goes to the servlet container (Tomcat, for example), where it is then passed through a chain of filters. There is an optional ActionContextCleanUp filter that is useful when integrating with other technologies such as Site Mesh plug-ins. If this filter is used, the request passes through it first.

Then the required FilterDispatcher is called, which uses the ActionMapper to determine whether there is a need to invoke an action for this request. If the ActionMapper determines that an Action should be invoked, the FilterDispatcher delegates the control to the ActionProxy.

The ActionProxy utilizes the framework configuration files manager, which is initialized from the struts.xml file. Then the ActionProxy creates an ActionInvocation, which is responsible for implementing the command pattern. The ActionInvocation process invokes the required interceptors and then invokes an Action. Once the Action is executed, the ActionInvocation is responsible for looking up the proper result associated with the Action result code mapped in struts.xml.

The result is then executed, which, most of the time, renders a JSP or a template written using FreeMarker or Velocity. Interceptors are executed again after completing the Action in the reverse order. Finally, the response returns through the filters configured in web.xml. If the ActionContextCleanUp filter is configured, the FilterDispatcher will not clean up ThreadLocal ActionContext. (ActionContext has the complete details of the runtime request and response. The framework uses ThreadLocal in connection with the ActionContext class to make the configuration and other runtime details available.) If the ActionContextCleanUp filter is not configured, the FilterDispatcher will clean up all ThreadLocals present.

Figure 1 depicts the architecture of the Struts 2 framework.

Figure 1. Struts 2 architecture (click for a larger image)

That all might seem kind of abstract. To help you get a firmer handle on it, here’s what a typical architectural request flow would look like:

  1. When the user performs an action on the Web application, the Web browser sends a request for some resource to the Web server.

  2. The request is received by the servlet filter dispatcher, which looks at the request and determines the appropriate Action to be invoked to serve it.

  3. The set of interceptors configured for applying some common functionality to the request — validation, workflow, or file upload, for instance — are automatically applied to the request before the Action is executed.

  4. A new instance of the Action class is created and then the action method is executed for storing or retrieving information to or from a database.

  5. The output — be it HTML, images, PDF, or in some other format — is rendered by the result.

  6. Then the request traverses through the interceptors in the reverse order. The returning request allows for the performance of additional processing or clean-up operations.

  7. Finally, the container sends the output to the browser.

This sequence is illustrated in Figure 2.

Figure 2. Struts 2 request processing flow (click for a larger image)

Struts 1 and Struts 2 compared

Struts 1 and Struts 2 have three basic concepts in common: request handlers, response handlers and tag libraries. But in Struts 2, these components have been redesigned and enhanced to be simpler for developers.

As a developer, you’ll notice a lot of modifications in the Struts 2 framework. For example, filters have replaced servlets, and the corresponding changes will be reflected in the deployment descriptor file. Similarly, the configuration file has been revamped completely. Changes in the Action class, support for annotations, and changes in validations are some of the other key features that you’ll notice. These changes are explained in detail in Table 1.

Table 1. Feature changes in the new version of Struts

FeatureStruts 1Struts 2
web.xmlUses <servlet /> and <servlet-mapping /> tags to map the controller, ActionServlet.Uses <filter /> and <filter-mapping /> tags to map the dispatcher, FilterDispatcher.
URI patternStruts 1 actions can handle *.do URIs.Generally, Struts 2 actions are mapped to /* because /* is better to use with filters; but by default, Struts 2 actions can handle *.action. The default extension for Struts 2 actions can be set in the properties file.
Struts configuration fileThe default name of the configuration file is struts-config.xml.The default name of the configuration file is struts.xml. This file requires fewer elements to be configured than struts-config.xml does, and the elements need fewer attributes.
The configuration file’s <form-beans /> tagUsed to specify the input handling.Obsolete.
The configuration file’s <action-mappings /> tagUsed to specify the list of Action classes.Replaced with the <package /> tag.
The configuration file’s <action /> tag.The attributes in this tag are used to specify the Action class, form beans, validation, etc. The response page is specified by the <forward> tag.The attributes of this tag are simplified and the <forward> tag is replaced by the <result> tag. The <result> tag has intelligent defaults set; for instance, its default name is “success,” its default path is the current location, and its default content is the MIME type specified. However, the default values can always be overridden.
ActionFormsActionForms are used to capture input and they must inherit from a base class, which results in many redundant classes.Obsolete. The properties are now part of the Action class itself and hence there is no need to have another input object.
Action classExtends from the abstract base class Action.Generally extends from the base class ActionSupport and may implement the Action interface. The advantage here is that any POJO can be used as an Action.
Singleton ActionsStruts 1 Actions are singletons and hence need to be thread-safe, since only one instance of the class will be available to handle all requests for that Action.Struts 2 Actions are not singletons; they are instantiated for each request, and hence they need not be thread-safe.
HTTP independence of ActionStruts 1 Actions use the Servlet API and hence are HTTP dependent.Struts 2 Actions are not coupled to a container and hence are HTTP independent.
Unit testingA major limitation of Struts 1 is that Actions can’t be tested separately.Struts 2 Actions can be tested easily with the support of dependency injection. Actions can be instantiated with the properties set and the methods invoked.
Output to viewsUses standard JSP mechanism page context for binding objects to views.Uses a value stack to bind objects to view. The advantage here is that the view that is rendered is not coupled with the type of the object.
Support for validationSupports validation through the Validator framework and with the validate method.Supports validation through the XWork validation framework and the validate method. The XWork validation framework supports chaining of validation.
Controller customizationSupports separate request processors for each module.Supports separate request handling for each Action.
AnnotationsNot supported.Supports Java 5 annotations, which can be used as an alternate to XML files.

Migrating to Struts 2.0

To migrate an existing Struts 1 application to Struts 2, you’ll need to make a lot of changes. Fortunately, such transitions can be eased by the fact that Struts 1 and Struts 2 elements can actually co-exist in the same application. If Struts 2 elements are added to a Struts 1 application, the pre-existing Struts 1 actions handle *.do requests, while the new Struts 2 actions handle *.action requests. The easiest approach to migration is to add the Struts 2 JAR file (available from the Apache Project; see Resources) to the application and migrate code on one page at a time. Many changes are just a matter of removing Struts 1 classes and tags that are not needed and including what is required for Struts 2. Optionally, some common things, such as Tiles configurations and validation rules, can be used by both the versions of the framework.

In the rest of this section, you’ll compare code snippets written for Struts 1 with their Struts 2 counterparts.

Changes in web.xml

Listing 1 illustrates a sample web.xml file that might be used in the Struts 1 framework.

Listing 1. A sample Struts 1 web.xml file

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">

<web-app>
    <display-name>Demo Application</display-name>
    <description>Demo for the Struts 1 framework</description>

  <!-- Standard Action Servlet Configuration (with debugging) -->  
  <servlet>

    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
      <param-name>config</param-name>

      <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

    <!-- Standard Action Servlet Mapping for URI -->
    <servlet-mapping>
      <servlet-name>action</servlet-name>
      <url-pattern>*.do</url-pattern>
    </servlet-mapping>

  <!-- The Usual Welcome File List -->
    <welcome-file-list>
      <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    
  <!-- Struts Tag Library Descriptors -->

      <taglib>
        <taglib-uri>/tags/struts-bean</taglib-uri>
        <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
      </taglib>
    
      <taglib>

        <taglib-uri>/tags/struts-html</taglib-uri>
        <taglib-location>/WEB-INF/struts-html.tld</taglib-location>
      </taglib>
      <taglib>
        <taglib-uri>/tags/struts-logic</taglib-uri>

        <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
      </taglib>
    
      <taglib>
        <taglib-uri>/tags/struts-nested</taglib-uri>
        <taglib-location>/WEB-INF/struts-nested.tld</taglib-location>

      </taglib>
    
      <taglib>
        <taglib-uri>/tags/struts-tiles</taglib-uri>
        <taglib-location>/WEB-INF/struts-tiles.tld</taglib-location>
      </taglib>   

</web-app>

To make this application support the Struts 2 framework, the Struts 2 FilterDispatcher must be added to the web.xml file. You’d also need to add a filter mapping tag to configure the FilterDispatcher and (since Struts 2 by default is Spring aware) a Spring Listener as well. Listing 2 illustrates the sample web.xml from Listing 1 modified for use with Struts 2.

Listing 2. Sample web.xml file, modified for Struts 2

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">
<web-app>
    <display-name>Demo Application</display-name>
    <description>Demo for the Struts 2 framework</description>

  <!-- Struts 2 Elements --> 
  <filter>
     <filter-name>struts2</filter-name>
     <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filterclass>
  </filter>

  <!-- Filter Mapping for URI -->
   <filter-mapping>
     <filter-name>struts2</filter-name>
     <url-pattern>/*</url-pattern>

   </filter-mapping>

  <!-- Spring Listener -->
   <listener>
      <listener-class>
org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>

  <!-- The Usual Welcome File List -->
    <welcome-file-list>
      <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>


In Struts 2, the <servlet /> and <servlet-mapping /> tags are replaced by <filter /> and <filter-mapping /> tags. Struts 2 tags are simpler and easier to use than their Struts 1 counterparts, as fewer elements are required with fewer attributes.

Changes in the Struts configuration file

A lot of changes have been made to the Struts configuration file. Perhaps the most obvious is its new name: in Struts 2, the file is now referred to as struts.xml instead of struts-config.xml. Listing 3 illustrates a sample Struts 1 configuration file.

Listing 3. Sample struts-config.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_3.dtd">

<struts-config>

<form-beans>
     <form-bean   name="formDataForm"
                  type="com.demo.form.FormDataForm">
      </form-bean>

</form-beans> 

<!-- Action Mapping Definitions -->
<action-mappings>
    <action  path="/formData"
         name="formDataForm"
             type="com.demo.action.FormDataAction"             
             scope="request"
         validate="false">

      <forward name="success"  path="/jspUserProfile.jsp"/>      
    </action>
</action-mappings>

<message-resources parameter="ApplicationMessageResources" null="false"/>

</struts-config>

The corresponding configuration file for Struts 2 is simpler: it has fewer elements and the elements have fewer attributes. There is no concept of FormBeans in Struts 2. The properties can now be defined in the Action class directly. Listing 4 illustrates the the Struts 2 struts.xml configuration file.

Listing 4. Sample struts.xml file, based on the struts-config.xml in Listing 3

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd ">
<struts>
   <include file="struts-default.xml"/>
   <package name="form-default" extends="struts-default">
      <action name="FormData" class=" com.demo.action.FormData">

         <result>/jspUserProfile.jsp</result>
      </action>
   </package>
</struts>

The configuration file has been changed in many ways. The DTD must be Struts 2-compliant. The root element in the configuration file is <struts>, and it must include a file called struts-default.xml to inherit the default behavior. Because there is no support for FormBeans, <form-beans> and its related tags are removed. <package> tags replace the <action-mappings> tags. The <action> tag attributes have changed. The <forward> element is replaced by the <result> element. All these changes have been introduced to maintain consistency across the framework so that it is on par with other frameworks such as Spring and iBATIS. These changes have been introduced to take advantage of the many new features in Version 2 of the framework. For example, the configuration file utilizes the advantage of intelligent defaults, where the result name defaults to “success.”

The end of the ActionForm class

The ActionForm classes no longer exist in the Struts 2 framework. These classes have become obsolete, and whatever had been written in the ActionForm class is now part of the Action class itself.

Changes in the Action class

The Action class has become simpler in the Struts 2 framework. Take a look at Listing 5, which illustrates a Struts 1 Action class.

Listing 5. A Struts 1 Action class

package com.demo.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;


public class FormDataAction extends Action {


    public ActionForward execute(ActionMapping mapping,
                 ActionForm form,
                 HttpServletRequest request,
                 HttpServletResponse response)
    throws Exception {
        request.setAttribute("FORMDATA", form);
        return (mapping.findForward("sucess"));

    }
}

The Action class in Struts 2 generally extends from ActionSupport and may optionally implement the Action interface. The advantage here is that any POJO can be used as an Action. Also, the Action class in Struts 2 is not a singleton; an Action class is initiated for each request. Hence, it need not be thread safe and can have member variables. Listing 6 illustrates the Action class in Struts 2. It corresponds to the Struts 1 code in Listing 5, and it also incorporates the functionality that in Struts 1 would be encapsulated in an ActionForm class.

Listing 6. A Struts 2 Action class

package com.demo.action;

import com.opensymphony.xwork2.ActionSupport;

public class FormData extends ActionSupport {
    public String execute() throws Exception {
        // Code having the processing logic
        ...........
        ...........
        ...........
        return (SUCCESS);
    }

    private String strFirstName="";
    private String strLastName="";

    public void setFirstName(String strFirstName) {
        this.strFirstName = strFirstName;
    }

    public String getFirstName() {
        return this.strFirstName;
    }

    public void setLastName(String strLastName) {
        this.strLastName = strLastName;
    }

    public String getLastName() {
        return this.strLastName;
    }    
}


Changes to tags

The bean tags supported in Struts 1 have been completely replaced by <s /> tags. The new tags provide a number of improvements over Struts 1 tags. Struts 2 framework tags can be generally broken into two categories: generic tags and UI tags.

Generic tags are used to handle the execution flow when the pages are rendered, and for data extraction as well. These are further broken down into control tags, which are used for flow control functions such as if, else, append, iterate and merge, and data tags, which are used for data manipulation, internationalization, localization, beans, bean properties, and so on. Generic tags generally output tag content directly.

UI tags are mainly designed to use the data retrieved from the data tags. These tags are generally used to display the data on an HTML page. They are further broken down into form tags, which are used to specify form elements, and non-form tags, which are used to specify an error in an action, an error in a particular field, or advanced UI elements like trees or tables. UI tags use templates and themes, and their output is usually a combined display.

Listing 7 demonstrates a simple example using Struts 1 bean tags.

Listing 7. Struts 1 tags

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<html>
<head>
    <title>This is a demo!</title>
</head>
<body>
    <h2><bean:write name="DemoForm" property="message" /></h2>

</body>
</html>

In Listing 8, the same example has been transformed to use Struts 2 tags.

Listing 8. Struts 2 tags

<%@ taglib uri="/struts-tags" prefix="s" %>
<html>
<head>

    <title>This is a demo!</title>
</head>
<body>
    <h2><s:property value="message"/></h2>
</body>
</html>


In this example, to transform the code, the value for the @taglib directive has been replaced with Struts tags. The advantage here is that the Struts tags automatically find the property; thus, there is no need to specify the ActionForm.

This is a fairly simple example, and details of each tag is beyond the scope of this article. Please refer to Apache Struts documentation (see Resources) for more details on Struts tags.

In conclusion

The Struts 2 framework features a simple architecture that is not hard to extend. It is smarter and easier to use than Struts 1 because it is POJO based. It also boasts a number of advantages over the previous release. The Struts 2 framework comes with rich set of features, such as enhanced Actions, enhanced tag support, support for Ajax, and support for annotations, all of which can be really helpful to the larger developer community. However, Struts 1 cannot be made obsolete immediately, as there are plenty of developers still using it.

Migrating from Struts 1 to Struts 2 is not very difficult, but it involves some effort. The easiest approach to migration would be migrating one page at a time. Even though this is a simple idea, there are still many changes to make. We recommend that you use Struts 2 for new projects and continue to use Struts 1 for existing applications already written for that framework. However, both versions of the framework can co-exist within a single application.

This article hasn’t covered everything related to Struts 2. However, it hopefully has offered an overall idea of the new features and reasons you might want to migrate to or adopt the Struts 2 framework.

Acknowledgments

The authors would like to acknowledge Jagdish Bhandarkar for reviewing this article.

S. Sangeetha works as a technical architect at the E-Commerce Research Labs at Infosys Technologies Ltd. She has over eight years of experience in design and development of Java and JEE applications. She has co-authored a book on J2EE architecture and also has written articles for JavaWorld and java.net.

S. V. Subrahmanya, popularly known as SVS, is vice president at Infosys Technologies and the founder of the E-Commerce Research Labs. He has coauthored books on Web services, JEE architecture, and enterprise IT architecture. He has published over 15 papers at international conferences and has written articles for JavaWorld and java.net. He has also filed two patents at USPTO.