An Application Framework for a Distributed Environment

 

Ramanand Singh

 

Abstract

An Application Framework for a distributed environment has been discussed. The purpose of this Application Framework is to provide a set of application and platform neutral services and components that are based on the best possible design patterns, standards, and practices offered at the present time. The framework encapsulates many of the application complexities and commonalities, as well as encourages appropriate design and implementation principles to its consumers. Special emphasis has been put on J2EE-based application environments.

 

 

1. Introduction

An application framework is a collection of reusable components. These components are designed, developed, and tested in a general environment. These are not intended to be used in just a single software application, rather the goal of this framework is to reuse the services in multiple projects without alterations. Each of these framework components provides a specific set of services to be used in an application. The framework must be designed in such a way that an interested project team can pick and choose its components to be used in its project - based on the project needs. Such framework reduces development time while improving the quality of the software using it. Developers of an application can devote their time concentrating on the business specific problems at hand rather than some auxiliary utility code required to perform generic tasks. A good application framework also enhances the scalability and maintainability of software application through well defined application programming interfaces (APIs) and their documentation.

 

The Application Framework discussed in this document has put special emphasis to Java 2, Enterprise Edition (J2EE) based distributed environment and software applications development using J2EE platform. 

 

1.1 General Features

For an application framework to be successful, following features have been kept in mind:

2 Framework Components

The proposed application framework consists of the following service components: Configuration Services, Logging Services, Exception Handling, EJBXtension Services, and Persistence Services. A general relationships amongst  various components are shown in Figure 1. A scalable design of the framework will allow it to add other components as the need for additional services arises.

 

2.1 Configuration Services

The Configuration Services component provides generic lookup services for any J2EE components as well as for simple Java classes. The component works with an XML input file containing all desired configuration items in an XML hierarchy. After reading the XML file and parsing the XML document, the component maintains an XML document tree. In providing the configuration lookup service, the Configuration Services component makes sure that it retrieves the value for a given key from the correct branch of the XML document tree. An example configuration file is shown in Figure 2 below to depict the possible information hierarchy available in the configuration parameters.

 

It is important to note that this component can handle multiple configuration files. This is accomplished by including auxiliary configuration files into the main configuration file. This mechanism helps keep the various configuration files separately to preserve the modularity and granularity of various other components.

Figure 1 Application Framework Components

2.1.1 Component Services

Various services provided by the Configuration Services component include:

<?xml version='1.0'?>

<configServicesParams>

  <application>

      <class>com.ti.apps.client.ClassLab</class>

  </application>

  <logging>

    <debug>

      <file>/com/ti/apps/classlab/logs/debug.log</file>

      <level>3</level>

    </debug>

    <log>

      <url>http://education.ti.com/apps/classlab/logs/application.log</url>

         <level>1</level>

    </log>

  </logging>

  <parameters>

    <ExpirationPeriod>19</ExpirationPeriod>

    <jdbc>

      <driver>jdbc</driver>

      <vendor>database-vendor</vendor>

      <protocol>vendor-protocol</protocol>

      <host>dbserver.ti.com</host>

      <port>9000</port>

      <dbServer>DatabaseServer</dbServer>

      <mode>database-server-mode</mode>

      <username>db-user</username>

      <password>db-user-password</password>

      <driverClass>com.dbvendor.jdbc.DriverClassName</driverClass>

      <database>database-instance</database>

    </jdbc>

      <ContactInfo>

        <ContactFilename>

          /com/ti/apps/classlab/data/contact-info.xml

        </ContactFilename>

      </ContactInfo>

  </parameters>

</configServicesParams>

 

Figure 2 A sample XML-based Configuration File

 

2.2 Logging Services

Event logging is an essential and the most used component of the Application Framework. Logging services provide facilities for logging various kinds of events - general information, debugging information, application warnings, unexpected errors, and so on. Logging such events and messages helps developers debug their application, quality assurance personnel perform the software testing, and application administrators troubleshoot application problems.

 

2.2.1 General Features

General features of the Logging Services component are briefly noted below.

2.2.2 Component Services

The various services of Logging Services component fulfilling the above mentioned features are listed in this section.

 

2.2.3 Design Considerations

From the point of view of flexibility, scalability, configurability and other such capabilities of a Logging Service component, one of the best implementation of this component would be based on Message Driven Bean (MDB). The MDB based design will easily support the distributed

environment of J2EE.

 

In this design scenario the MDB will be the real engine to provide the actual logging activity of writing the log message to the desired channel. In order to log a message, a client component (it could be any J2EE component, such as session EJB, entity EJB, or a client program) finds the appropriate message queue and sends the log message to it. Alternately, the application component can publish its message (to be logged) to the JMS topic.

 

The component sending the message to the message queue or topic is known as message sender or a publisher, respectively. Once, a message sender sends the message or a message publisher publishes a message, the message driven bean is automatically instantiated, if not already exists. The onMessage (Message) method gets invoked. This onMessage method is the one who handles the log message as per the log policy set forth for the application.

 

2.3 Exception Handling

Software engineering process is usually a very methodical and rigorous if followed correctly. However, omission can not be completely ruled out at one of the stages of software life cycles. Also, it is almost impossible to test an application for all possible error conditions it can encounter in production. Exceptions provide a clean way to check for such omissions and/or errors in the application by signaling errors directly rather than using flags. An unexpected error condition in a method necessitates for throwing an exception, which is then caught further up in the method invocation stack. Uncaught exceptions result in the termination of the execution thread  which prints a stack trace information. On occurrence of an exception, actions after the point at which the exception occurred do not take place. The next action will be either a finally block or a catch block that catches the exception.

 

 2.3.1 Exception Type

Exceptions can be classified in two categories – System and Application exceptions, and synchronous and asynchronous exceptions.

 

2.3.1.1 System Exceptions

A system exception indicates a problem with the services that support an application. Examples of these problems include: unable to obtain a database connection, a failure of SQL insert clause due to a full database, unable to find a desired object through a lookup method, and so on. RuntimeException types and subtypes are known as system exceptions. More serious errors are signaled by exceptions of type Error. These exceptions can occur at any time and in any code.  The system exceptions are not supposed to be listed in the throws clause of  a method. These are ubiquitous and every method can potentially throw them, making them unchecked by the compiler.

 

In the EJB environment, javax.rmi.RemoteException types and subtypes including javax.ejb.EJBException are also known as system exceptions.  System exception is generated when a method (enterprise bean business method, onMessage method, or container callback method) encounter various exceptions or errors that prevent the method from successfully completing.  This happens because either the exception/error is unexpected, or the EJB provider does not know how to recover from it. Failure to obtain a database connection, unexpected RuntimeException, JVM errors, unexpected RemoteException, and JNDI exceptions are few examples of system exceptions and errors.

 

An EJB container catches a system exception; logs it; and, except in the message driven beans, throws the javax.rmi.RemoteException to the remote client, or throws the javax.ejb.EJBException to the local client.  The container in which the bean method participated rolls back transaction and makes sure that no other method is invoked on an instance that threw a system exception.

 

2.3.1.2  Application Exception

Any exception that does not extend javax.lang.RuntimeException or the javax.rmi.RemoteException is an application exception. These are checked exceptions – forcing compiler checking for their validity. Such exceptions must be declared in a throw clause. An application exception signals an error in the business logic, i.e., program logic.

 

An application exception thrown by an enterprise bean instance should be reported to the client precisely (i.e., the client get the same exception). Such exceptions should not automatically rollback a client’s transaction. The client should be given a chance to recover a transaction from an application exception. An unexpected exception that may have left the instance’s state variables and/or underlying persistent data in an inconsistent state can be handled safely.

 

2.3.1.3 Synchronous Exception

Synchronous exceptions occur as a result of either a throw statement or an execution of a particular instruction (such as divide-by-zero).

 

2.3.1.4 Asynchronous Exceptions

On the other hand, an asynchronous exception can occur at any time and it can occur only due to an  internal error in JVM. Java developers can not do much about such exceptions.

 

2.3.2 General Guidelines for Exception Handling

 

2.3.3 Component Services

Exception Handling component provides exception propagation and handling services to other components of the application. Any component needing to handle an exception in a special way may simply pass the exception to this component. The exception handling component uses logging services to log the exception and any reformulation of the exception desired. This component also provides a list of predefined exceptions useful for handling various kinds of unexpected error conditions in EJB instantiations as well as its business methods.

 

2.4 EJBXtension Services

EJBXtension Services component provides the commonly and repeatable functionalities from Enterprise JavaBeans. Using the services of this component results in a cleaner and consistent code for various EJB and other client components.

 

2.4.1 Services

2.5 Persistence Services

Databases are the integral part of any enterprise system. J2EE based enterprise system is no exception. However, most of the J2EE developers do not want to know where the database resides or what kind (vendor wise) of database they are dealing with. They just want to get

a connection to the database to talk to it. Since, JDBC has become standard protocol for connecting Java and J2EE based applications to relational databases, this component provides JDBC based services.

 

2.5.1 Features

 

2.5.2 Services

3 Framework Driver

Framework components are presented in the previous section. Now, wee need a way to bootstrap the framework for business application. The framework makes sure that the business application should not be burdened by the details of starting the framework. In fact, business applications will have the framework and its components readily available through the framework component’s service APIs.

 

Framework driver performs the component creation and initialization, determines the application server it has been deployed to, and makes all its information available to its client components. The framework driver serves two different kind of users: developers who want to extend the framework, and developers who just want to use the framework. Members of the first group are primarily interested in the underlying implementation of the framework itself, while those in the second group are just interested in the public interfaces of the framework.

Framework driver provides a basic framework interface and abstraction which each and every framework components will need to extend. This restriction will help new services to be easily added to the framework.

 

4 Deployment Consideration

Building the framework and its components is not enough for it to be accepted amongst the developers. We need to provide ease of use for the framework just as any other packages. The framework and its components can be developed as an independent Java package and deployed across application servers. JDK 1.2 and above provides a hook for this purpose – the $JAVA_HOME/ext directory which is auto-inspected by the Java runtime. This gives us an easy way to make sure that the framework is located in a consistent location and also the framework is automatically added to the classpath. Developers need only to import the classes they require to start using the framework.

 

5 Conclusions

A basic idea of an application framework for J2EE has been discussed. General introduction, component features, services for each of the components have been presented. Some of the design considerations have also been presented in the document. A relatively thorough guideline for exception handling has been discussed with J2EE components in mind. It is hoped that design and implementation of this application framework will help software development teams perform their tasks more easily, cleanly, and consistently.

 

About Author

Ramanand Singh is an Enterprise Java Architect with Nalanda Technology, Inc. He has over 14 years of experience in software industry. His focus has been on architecture, design, and implementation of enterprise applications using Object-Oriented technologies, design patterns, Java technology, CORBA technology, and J2EE technology. Mr. Singh was an invited guest speaker recently at IEEE Computer Society meeting for a presentation entitled “Building n-tier Enterprise Application using J2EE Platform.” He can be reached at rsingh@nalandatech.com.

 

Resources

  1. “Enterprise JavaBeans Specification, Version 2.0”, Sun Microsystems, Inc., April 2001.
  2. Richard Monson-Haefel, “Enterprise JavaBeans, Second Edition”,  Orielly & Associates, Inc., MARCH 2000.
  3. Ken Arnorld, James Gosling, David Holmes, “The Java Programming Language, Third Edition”, Addison-Wesley, June 2000.
  4. Seth White, et. Al., “JDBC API Tutorial and Reference, Second Edition”, Addison-Wesley, December 1999.

Back