Skip to main content

Create an asynchronous message framework with Ajax and Apache Geronimo

Craft a responsive, enterprise-grade Web application framework

Jeff Hanson (jeff@jeffhanson.com), Chief Architect, eReinsure.com, Inc.
Jeff Hanson's photo
Jeff Hanson has more than 20 years of experience in the software industry, including working as senior engineer for the Microsoft Windows port of the OpenDoc project and lead architect for the Route 66 framework at Novell. Jeff is currently the chief architect for eReinsure.com, Inc., building frameworks and platforms for J2EE-based reinsurance systems. Jeff is the author of numerous articles and books, including .NET versus J2EE Web Services: A Comparison of Approaches, Pro JMX: Java Management Extensions, and Web Services Business Strategies and Architectures.

Summary:  Combine Apache Geronimo with an Asynchronous JavaScript + XML (Ajax) user interface (UI), an asynchronous messaging system, and loosely coupled business services to build a responsive, enterprise-grade Web application framework.

Date:  19 Jun 2007
Level:  Intermediate
Activity:  1370 views

Overview of the framework's components

A well-designed service-oriented business tier helps you compose processes and composite applications from loosely coupled services. This composition of services within a Service-Oriented Architecture (SOA) lets you build applications and processes with services from heterogeneous environments without knowing the finer details of each environment. The benefits you'll reap using SOA depend on the services you design and implement with generic, coarse-grained interfaces.

Ajax programming gives you a lot of power and flexibility for developing browser-based UIs. Combining this UI power with a service-oriented business tier offers you an even greater degree of flexibility. Ajax programming, by design, lends itself well to asynchronous requests and responses. When you combine the asynchronous nature of Ajax with an asynchronous-based messaging system, you can build browser-based applications with user experiences that more closely resemble desktop applications, and that can give users a more real-time feel.

Apache Geronimo is a modular Java™ 2 Platform, Enterprise Edition (J2EE)-compliant application server platform based on an architecture that uses Inversion of Control (IoC) to decouple components and services to build enterprise-grade applications and services.

In this article, you learn about the interactions between multiple Ajax-based clients and a Geronimo-based server using a message-based framework or bus to handle asynchronous business requests from clients. Find out how Ajax-based client requests are traced from browser to server and back. And see how these requests are traced on the server side through a message-oriented service bus to targeted business services.


Introduction to Ajax

Check out the Ajax Resource Center, your one-stop shop for information on the Ajax programming model, including articles and tutorials, discussion forums, blogs, wikis, events, and news. If it's happening, it's covered here.

Ajax is a framework of UI capabilities and concepts driven by an XML-based request and response server invocation model. Many of these concepts are arbitrary in nature but standard by convention. Much of what has emerged as standard in Ajax application development has been the result of the capabilities of the major Web browsers.

An Ajax UI relies on the Document Object Model (DOM) features and JavaScript components in the browser that is being used to parse and display a Web page at any given time. Many — but not all — of these features and components are shared by most of the major Web browsers. This can be frustrating, so this article discusses only the most fundamental capabilities of the DOM and Ajax-oriented JavaScript code.

Fundamental to almost all applications that call themselves Ajax based is the creation of a component known as the XMLHttpRequest object. This JavaScript object is used to construct and transmit requests back and forth from browser to server. The snippet in Listing 1 creates an instance of the XMLHttpRequest object that can be used between a Mozilla Firefox browser or Microsoft® Windows® Internet Explorer® browser and a server.


Listing 1. Creating the XMLHttpRequest object
                
function getHTTPObject()
{
   var xmlhttp = null;
   var success = false;
   
   // List of MS XMLHTTP versions - newest first
   var MSXML_XMLHTTP_PROGIDS = new Array(
       'MSXML2.XMLHTTP.5.0',
       'MSXML2.XMLHTTP.4.0',
       'MSXML2.XMLHTTP.3.0',
       'MSXML2.XMLHTTP',
       'Microsoft.XMLHTTP'
   );

   for (var i = 0; i < MSXML_XMLHTTP_PROGIDS.length && !success; i++)
   {
      try
      {
         xmlhttp = new ActiveXObject(MSXML_XMLHTTP_PROGIDS[i]);
         success = true;
         return xmlhttp;
      }
      catch (e)
      {
         xmlhttp = false;
      }
   }

   if (!xmlhttp && typeof XMLHttpRequest != 'undefined')
   {
      try
      {
         xmlhttp = new XMLHttpRequest();
      }
      catch (e)
      {
         xmlhttp = false;
      }
   }

   return xmlhttp;
}
      

After creating an instance of the XMLHttpRequest object, you can use it to send and receive HTTP requests to and from an HTTP server component, such as a Java servlet. The snippet in Listing 2 uses the XMLHttpRequest object to send an HTTP GET request to an HTTP server component.


Listing 2. Sending an HTTP GET request using the XMLHttpRequest object
                
function callService(url)
{
  if (!isWorking)
  {
    httpObj.open("GET", url, true);
    try
    {
       httpObj.setRequestHeader("Content-type", "text/plain");
    }
    catch(e)
    {
       // setRequestHeader is missing in versions of Opera
    }
    isWorking = true;
    httpObj.onreadystatechange = handleServiceResponse;
    httpObj.send(null);
    return true;
  }
}
      

HTTP responses are handled asynchronously by a JavaScript callback function that is specified as the value of the XMLHttpRequest object's onreadystatechange field. This is specified in Listing 2 as handleServiceResponse. The snippet in Listing 3 shows an example of a typical incarnation of the onreadystatechange callback function.


Listing 3. Handling an XMLHttpRequest instance's response in a callback function
                
function handleServiceResponse()
{
  if (httpObj.readyState == 4) // a value of 4 represents a request-completed state
  {
    isWorking = false;
    if (httpObj.status == 200)
    {
	   var contentType = httpObj.getResponseHeader("Content-type");
      var xmlDoc = httpObj.responseXML.documentElement;
      var textResponse = httpObj.responseText;
      // do something with either xmlDoc or textResponse or with both
    }
  }
}
      

Now that HTTP requests can be sent and received by an Ajax-based browser page, you must construct a server component to handle the requests and transmit responses. This example uses a Java servlet deployed to the Apache Geronimo application server.


Introduction to Apache Geronimo

The Geronimo application server is a fully compliant J2EE application platform that can be used to build enterprise-grade applications and services. Geronimo is extremely configurable, modular, and is based on an architecture that uses IoC techniques to effectively decouple components and services. Geronimo also takes advantage of Java Management Extensions (JMX) and a similar proprietary management framework that makes Geronimo an easy platform to monitor, configure, and manage.

Download and install Apache Geronimo

Download the Geronimo platform from the site listed in the Resources section, and extract the files to a directory to be referred to as {GERONIMO_HOME}. Then execute the startup script found in the {GERONIMO_HOME}\bin\ directory of your Geronimo installation. You should see a console window similar to Figure 1.


Figure 1. Geronimo startup
Geronimo startup

The startup console shows a number of modules, connectors, and applications that are loaded and started, and from which the Geronimo runtime environment is created. You can stop the Geronimo runtime using the shutdown script, also found in the {GERONIMO_HOME}\bin\ directory of your Geronimo installation.


Asynchronous messaging

Asynchronous messaging systems revolve around the idea that a message receiver doesn't know or care about the origin of a given message; instead, a message receiver assumes that it will receive all the information it needs to execute its tasks with each message that it receives. This decoupling between message senders and message receivers is sometimes referred to as a publish/subscribe relationship and is one of the most useful features of an asynchronous messaging system.

An asynchronous messaging system typically relies on a message bus or broker to expose queues or event channels that receive messages published by message producers. This same bus or broker exposes a subscription interface that interested message receivers or event consumers can use to register themselves as notification listeners to a given type of message or event.


The Ajax system

The asynchronous message-based framework covered in this article uses a message bus that transmits Ajax-originated messages to business services by means of event channels. The event channels can also notify interested listeners about events successfully handled by business services.

Coupling refers to the degree to which software components or services depend on each other. The degree of coupling that defines a group of services or components determines which objects must be present at compile time and run time. Loosely coupled components can operate independently from one another and can be developed and deployed separately from each other with their relationships being specified at run time. This is often referred to as runtime binding or late binding.

Employing a message-based framework or bus that handles asynchronous business requests depends on the existence of loosely coupled business services to handle the business logic targeted by each independent asynchronous message.

You can use a number of mechanisms to decouple business services from service consumers. Remote Procedure Call (RPC) stubs and skeletons, XML Schema Definition (XSD) schema-based signatures, and standardized interfaces are just a few of these. This example uses a standard coarse-grained interface, BusinessService, defining one execution method with generic message data as the parameter.

The goal of a method signature that accepts generic data instead of strongly typed objects is to ensure loose coupling between the caller and the target object. Using strongly typed objects as parameters, thereby combining data and code, implies a specific behavior. After behavior crosses component or service boundaries, tight couplings can emerge easily. Passing generic message data implies no behavior and resists tight couplings from forming.

The code snippet in Listing 4 illustrates the BusinessService interface.


Listing 4. A standardized business service interface
                
public interface BusinessService
   extends Serializable
{
   public void setID(String id);

   public String getID();

   public Object execute(String methodName, Object[] params)
      throws ServiceException;
}
      


Message flow from client to server and back

The UI for this example consists of one simple Ajax-enabled JavaServer Pages (JSP) component. The JSP defines one form (see Listing 5) that's used to pass service requests to the server using the XMLHttpRequest object discussed earlier.


Listing 5. An Ajax-enabled HTML form
                
<form name="ServiceRequestForm" method="POST" onSubmit="return false">
  <table>
     <tr>
       <th>
         Raw Ajax XML
       </th>
       <th>
         User Names
       </th>
     </tr>
     
     <tr>
       <td>
         <textarea name="result" id="result" COLS="40" ROWS="8"></textarea>
       </td>
       <td>
         <textarea name="users" id="users" COLS="20" ROWS="8"></textarea>
       </td>
     </tr>
     
     <tr>
       <td colspan="2">
         <input name="submit" id="submit" type="submit" value="Get User Names"
                onclick="callService('services?ServiceName=UserAccountService&'
                                     + 'MethodName=getUserNames&ServiceParams=');">
         <input name="reset" id="reset" type="reset"
                onclick="resetFields();">
       </td>
     </tr>
  </table>
</form>
      

Requests initiated by the form are made using the callService JavaScript function, which uses the XMLHttpRequest object to handle the HTTP communications. After the message is received by the servlet, it's converted to an asynchronous message and routed through a framework of Java components that eventually results in a business service request and an XML-based service response.

Figure 2 illustrates the flow of messages and method calls for the Ajax system.


Figure 2. Asynchronous system flow
Asynchronous system flow

As shown in Figure 2, the process is as follows:

  1. The FrontController servlet receives a message at the Web tier.
  2. The FrontController servlet employs the request processor to convert each HTTP request to a normalized asynchronous message.
  3. Each message is published, along with an asynchronous callback listener, to a message bus residing on the business tier.
  4. The message bus creates an event object and dispatches it, along with an instance of a business service, to an event channel.
  5. The event channel performs the task of calling the business service and notifying any listeners subscribed to the event channel of the event's successful completion or failure.

Data is passed back and forth between tiers and components in the form of model objects. The model objects can be serialized to XML as needed, such as when the FrontController servlet responds to an XML-based Ajax client.

The essential concept in the system is the use of callback objects by which failure or success of a given operation can be relayed back to the components responsible for handling the failure or success. Ultimately, this failure or success state is sent to the Ajax client and displayed to the user. The reliance on callback objects and asynchronous notifications raises a concern that isn't usually found in typical request or response Web applications: the challenge of responding to a client in a timely manner, keeping in mind user attention span and HTTP timeout limits. To address this concern, timeouts are typically employed within the business tier to ensure that a process doesn't block beyond a reasonable length of time. Java Timer objects, child threads, begin-wait-abort loops, and message-queue timeouts are a few of the mechanisms you can use to enforce effective timeout limits. The system in this example uses simple begin-wait-abort loops.


Integrate the asynchronous messaging system with Apache Geronimo

Geronimo facilitates a simple deployment of the asynchronous messaging system. The system is packaged as a WAR file, which is deployed to Geronimo using the Deployer tool distributed with the Geronimo platform. The Deployer tool is found in deployer.jar, which is located in {GERONIMO_HOME}\bin\, where {GERONIMO_HOME} is the directory for your Geronimo installation.

Create the WAR file

Run the command shown in Listing 6 to compile the system classes and create the WAR file.


Listing 6. Creating the WAR file
                
{YOUR_PROJECT_DIR}{MAVEN_HOME}\bin\mvn clean compile war:war        
      

Deploy the WAR file

Run the command in Listing 7 to deploy the WAR file to the Geronimo application server.


Listing 7. Deploying the .war file
                
{YOUR_PROJECT_DIR}{JAVA_HOME}\bin\java -jar {GERONIMO_HOME}\bin\deployer.jar deploy \
target/GeronimoAndAJAX-1.1.war        
      

You should see results similar to those in Listing 8.


Listing 8. WAR file deployment results
                
Username: system
Password: *******
    Deployed default/GeronimoAndAJAX-1.1/1169329928406/war @
    http://localhost:8080/GeronimoAndAJAX-1.1
      


Run the asynchronous messaging system

You send a message from the Ajax-enabled start page of the asynchronous messaging system to the server by directing a Web browser to http://localhost:8080/GeronimoAndAJAX-1.1. Doing so displays a start page similar to Figure 3.


Figure 3. Asynchronous system start page
Asynchronous system system start page

When you see the start page, click Submit Query to make the asynchronous service call. The page shown in your browser window should look similar to Figure 4.


Figure 4. Asynchronous system results page
Asynchronous system results page

Notice how the raw XML received from the server is shown in the left column, and a formatted list representing the results is shown in the right column.


Conclusion

Ajax programming has given Web application developers greater power and flexibility than traditional Web development methods. Combining this power with a loosely coupled, service-oriented business tier gives you even more flexibility and power. Ajax is designed to operate in an asynchronous request and response environment. The asynchronous nature of Ajax combined with an asynchronous-based messaging system provides a more real-time, desktop application feel for your users.

This article discussed one way to use Apache Geronimo to build a system that combines the asynchronous nature of an Ajax UI with an asynchronous messaging system using loosely coupled business services. Interactions were traced between Ajax-based clients and a message-based framework or bus that dispatches asynchronous business requests initiated by Ajax clients to business services.



Download

DescriptionNameSizeDownload method
Sample code for this articleGeronimo_and_Ajax_Src.zip25KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

About the author

Jeff Hanson's photo

Jeff Hanson has more than 20 years of experience in the software industry, including working as senior engineer for the Microsoft Windows port of the OpenDoc project and lead architect for the Route 66 framework at Novell. Jeff is currently the chief architect for eReinsure.com, Inc., building frameworks and platforms for J2EE-based reinsurance systems. Jeff is the author of numerous articles and books, including .NET versus J2EE Web Services: A Comparison of Approaches, Pro JMX: Java Management Extensions, and Web Services Business Strategies and Architectures.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source, Web development, WebSphere
ArticleID=232009
ArticleTitle=Create an asynchronous message framework with Ajax and Apache Geronimo
publish-date=06192007
author1-email=jeff@jeffhanson.com
author1-email-cc=ruterbo@us.ibm.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers