HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

Distributed object computing in Java has become increasingly popular as more complex products are written using a multi-tier architecture. A number of products and protocols are available for facilitating communication, and many developers have trouble deciding which ones to use in a given situation. Many of the communication methods work well together, and each has its strengths and weaknesses. In this article I'll discuss two of the most popular methods, CORBA and servlets. Both are useful for distributed computing, and they complement each other well.

What Is Distributed Object Computing?
Distributed object computing is development involving communication between two or more independent modules of an application. Usually, it involves communication between a client and a server - for example, a Java time-tracking application. This application would have a client side written as a Java applet and a server side that stores and retrieves information from a database. Users could enter the hours they spent on a specific project on the client side, and that information would be transferred to the server side and stored in the database. Likewise, if they wanted to retrieve previously stored hours, their request would be passed to the database and the information would then be passed back to the client side, generating a report dynamically.

This application is a good example of a multitier architecture. The client communicates with the server, and the server communicates with the database, creating three different layers to the application as well as a need for a communication protocol between each set. Since they have only the two modules, client/server applications are a special case of multitier applications. Communication between the server and the database can be done directly (using JDBC or a similar API), since the database is usually on the same intranet as the server module. However, the client and server modules not only could be on different intranets, they could also be separated by a firewall or another divider. Therefore, communication between them can be difficult. In order to communicate, the application must assemble information on one side, encapsulate it and send it to the other side, which must retrieve and decipher it. This is the problem distributed computing protocols and products are designed to solve.

What Is CORBA?
CORBA stands for Common Object Request Broker Architecture. The Object Management Group (OMG) is the body responsible for creating and maintaining the CORBA specifications. CORBA includes specifications for a language to define objects, a protocol for exchanging information and a protocol for passing objects over the Internet. Several companies have taken these specifications and developed implementations of CORBA for Java. Inprise VisiBroker is the leading commercial implementation, and Sun recently released Java IDL as a core API as part of the Java 2 platform release. There are also implementations available for different languages and platforms.

The language CORBA uses to define objects is the Interface Definition Language, or IDL. Once an object is defined using IDL, it can be translated to a specific language such as C++ or Java. This object can then be used by both the client and server modules as a native object. The object is passed between the client and the server using the Internet Inter-ORB Protocol (IIOP), a protocol for translating the General Inter-ORB Protocol (GIOP) for use with TCP/IP. In other words, IIOP is the protocol used for transferring these CORBA objects from one side to the other over the Internet.

The Object Request Broker (ORB) is the active part of a CORBA implementation. It receives a request for information from one module of the application, finds an implementation of the object associated with that information and handles the transfer between modules. For example, in the time-tracking application above, the applet code might call a method that is actually implemented in the server. When the method is called, the ORB is given the request, passes any parameters of the method to the server side, executes the method and sends the return value back to the client. This is all transparent to the client code, so that writing a client application using CORBA is not significantly different from writing a normal Java application. The CORBA specification includes ORB interoperability, guaranteeing that an object passed to one vendor's ORB can be understood by any ORB written by any other vendor. A simple example of the client server and IDL code for an application can be seen in Listing 1.

CORBA is an excellent protocol to use when the goal is to pass information transparently between the client and server. Many of the implementations exhibit high performance and are easy to use and incorporate into existing applications. The guarantee of ORB interoperability makes it easy to switch implementations and add code or JavaBeans from other sources to existing CORBA-compliant code.

What Are Servlets?
Servlets are Java modules that can be executed by a Web server. They are similar to CGI scripts, but have several significant advantages. First of all, they are run within the same process as the Web server, while CGI scripts are executed in separate processes. This makes servlets faster and more efficient than scripts. Second, servlets are written in Java, so they are immediately portable to multiple platforms and have the range and flexibility of the full Java language. This means, for example, that a servlet could also use the JDBC API to access a database, or even use CORBA to access a different server. CGI scripts are generally written in platform-specific languages or compilations of languages, making them hard to support and less flexible. Finally, the Java Servlet API allows easy access to a full range of information about the request, even allowing objects to pass between the client and server side. The most common uses of servlets are to drive dynamic Web sites and to produce dynamic HTML within a Web-based application.

Servlet objects are usually passed using the Hypertext Transfer Protocol (HTTP). HTTP, the most common Internet transfer protocol, is supported by all Web browsers and servers. It's specifically designed for transferring Hypertext content over the Internet, and is specialized for doing so. This means that while servlets are extremely efficient for producing and transferring dynamic HTML, they are less efficient for transferring objects between an applet and a server. For comparison, they are faster for object transfer than some implementations of CORBA, but slower than most.

Servlet implementation depends mainly on the Web server chosen to incorporate them. Sun has released a product, the Java Web Server, that natively supports servlets. A number of products, including one from Sun, add servlet support to existing Web servers, so most common ones can now support servlets. A complete list of supported servers is available from the JavaSoft home page. Once you've written a servlet and compiled it using the JDK and the Java Servlet API (or the Java Servlet Development Kit), you put the class file into a specific servlet directory in the Web server hierarchy and restart the server. At that point the servlet is ready for use. A simple example of a servlet can be found in Listing 2.

Which Should I Use?
Servlets and CORBA both have their strengths and weaknesses, and which is appropriate depends on the situation. CORBA is optimized for transferring objects transparently, while servlets are designed more for server-side processing resulting in dynamic HTML.

In the time-tracking application listed above, there are two functions that happen with reasonable frequency: storing information to the database and generating reports. In the first case, the application should pass data from the client to the server and store it in the database. This is simple object passing from an applet to a server application, which CORBA does very efficiently. The same process could be done with servlets, but it would require more coding and maintenance to work efficiently, and would generally have poorer performance. The second case is more complicated - are the reports in HTML or in Java? If HTML, then the application is passing a request to the Web server and expecting dynamic HTML in return, something that servlets do most effectively. Again, the same process could be done using CORBA (pass the request to the back end using CORBA and use that to write an HTML file that can then be displayed or downloaded by the client), but in this case CORBA requires more coding and more maintenance, and has poorer performance. However, if the report front end is in Java, CORBA again becomes a better answer.

In the case of a Java front end and HTML reporting, new questions come up. Each method is useful in its area, but there's a lot of overhead involved in implementing two different communication methods in one application, particularly a small one. Some other considerations are budget and memory requirements. Running a client-side applet, an ORB, a server-side application, a Web server and possibly a servlet plug-in can be expensive and memory intensive enough to demand a decision between the two methods. Until recently, servlets tended to be the cheaper alternative, since kits for running servlets with the major Web servers can be downloaded free. The introduction of Java IDL, however, has generated a CORBA option that is also distributed free, so either one is now a reasonable choice on a small budget. In this case, the best way to make a decision, if you can use only one method, is to plan to optimize the application for one method or the other.

One possibility is to change the front end for the application entirely to HTML. Most time-tracking applications have reasonably simple front ends and could be easily converted to HTML. This would eliminate the need for CORBA, since all pages are now dynamic HTML and will be most efficiently served by servlets. Conversely, you might decide to use a different reporting tool that uses a Java front end, eliminating the need for any HTML, which then allows you to use CORBA most effectively. Finally, you might decide to leave both the way they are and do some performance testing to see whether it is more efficient to use CORBA for your HTML or servlets for your applets, since these performance measurements are very much dependent on CORBA implementation and code specifics. Since each method can be used to duplicate the other one, once you have chosen the one with the minimum loss of performance, you can standardize on that method.

Larger applications, on the other hand, benefit greatly from using more than one method of communication. Performance and scalability are critical issues for large applications, and using more than one method can assure that the application is optimized for maximum performance. CORBA and servlets don't interfere with each other at all in an application, and can be used side by side in the same code without any problems. For example, a Web site management application may let the user save dynamic HTML to a database and then view it. CORBA could be used to send the information to the database and a servlet could then be invoked to retrieve the information, do any dynamic substitution necessary and display the final dynamic Web page. Using both can be a distinct advantage over having to optimize an application for only one method.

Where Can I Get More Information?
More information on CORBA, including CORBA, IDL and IIOP specifications, is available at www.omg.org/, the OMG home page. There is also a CORBA home page at www.corba.org and JavaSoft's Java IDL is available for download from the Products and APIs section of the Java home page, java.sun.com/. Information on servlets, the Java Web Server and the Java Servlet API is available from the servlet home page at jeeves.javasoft.com/. This page includes a list of products available from other vendors to support servlets on a number of servers.

About the Author
Rachel Gollub is a senior engineer/architect at Imparto Software Corporation. She started programming in Java (then Oak) in 1995, and was hired by JavaSoft, where she worked until 1997. She contributed some of the demo applets shipped with the JDK, and made contributions to the Java Web Server and the security classes. Rachel can be reached at [email protected]

	

Listing 1.
 
* Client.java 
 */ 

import java.applet.Applet; 
import java.awt.*; 
import java.awt.event.*; 

/** 
 * This class demonstrates a simple client side 
 * applet that uses CORBA for communication with  
 * the server.  It takes in two text fields, 
 * name and hourse, and deposits them in an 
 * Oracle database using Inprise VisiBroker. 
 */ 
public class Client extends Applet  
  implements ActionListener { 
  

  // Server is the handle to the server side 
  // code, accessed by the ORB. 
  private Server server; 
  

  // The name to pass to the database 
  private TextField name; 
  

  // The hours string to pass to the database 
  private TextField hours; 
  

  /** 
   * The init method of the applet contains the 
   * initialization of the ORB. 
   */ 
  public void init() { 
    // This line is where the ORB is 
    // initialized. 
    org.omg.CORBA.ORB orb =  
      org.omg.CORBA.ORB.init(this, null); 
  

    // Next, the server object is bound to 
    // the actual object on the server side. 
    server = ServerHelper.bind(orb, "Server"); 
  

    // This method just sets up the GUI. 
    gridBagLayout(); 
  } 
  

  /** 
   * gridBagLayout creates a simple GUI 
   * to communicate with the server code. 
   */ 
  public void gridBagLayout() { 
    GridBagLayout gbl = new GridBagLayout(); 
    setLayout(gbl); 
    GridBagConstraints c =  
      new GridBagConstraints(); 
    c.fill = GridBagConstraints.BOTH; 
    c.gridx = 0; 
    c.gridy = 0; 
    c.gridwidth = 1; 
    c.gridheight = 1; 
    c.weightx = 0.0; 
    c.weighty = 0.0; 
    Label label = new Label("Name:"); 
    gbl.setConstraints(label, c); 
    add(label); 
    c.gridy = 1; 
    label = new Label("Hours worked:"); 
    gbl.setConstraints(label, c); 
    add(label); 
    c.gridx = 1; 
    c.gridy = 0; 
    c.weightx = 1.0; 
    name = new TextField(15); 
    gbl.setConstraints(name, c); 
    add(name); 
    c.gridy = 1; 
    hours = new TextField(15); 
    gbl.setConstraints(hours, c); 
    add(hours); 
    c.gridy = 2; 
    Button button = new Button("Submit"); 
    button.addActionListener(this); 
    gbl.setConstraints(button, c); 
    add(button); 
  } 
  

  /** 
   * When the Submit button is pressed, this 
   * method is called.  This is where the 
   * actual communication with the server 
   * takes place. 
   */ 
  public void actionPerformed(ActionEvent evt) { 
    // The Data object defined by the IDL file 
    // is initialized just like any other object 
    // in Java. 
    Data data = new Data(); 
  

    // The data is filled in from the text 
    // fields.  In a commercial application, 
    // error checking and validation would 
    // happen here. 
    data.name = name.getText(); 
    data.hours = hours.getText(); 
  

    // The method in the server code that 
    // records data is called as if it were 
    // on the client side, and returns a 
    // value the same way. 
    if (server.record(data) == false) { 
      destroy(); 
    } 
  } 
  

  /** 
   * stop is called before destroy, so 
   * the server.close() method must be 
   * called here. 
   */ 
  public void stop() { 
    // This server side method is called 
    // to wrap things up neatly. 
    server.close(); 
  } 
  

} 
  

----------------------------------------------- 
  

// example.idl 
  

// This is the IDL file that defines the objects 
// and interfaces accessible to the client and  
// server. 
  

// The Data struct, when converted to Java, will 
// create a Java Data object and a few helper 
// files that facilitate communication. 
struct Data {    
  string name;  
  string hours; 
}; 
  

// Server is an interface, implemented by 
// ServerImpl.java on the server side.  All 
// server methods accessed by the client must 
// be listed here. 
interface Server {  
  boolean record(in Data data); 
  boolean close(); 
}; 
  

------------------------------------------------ 
  

/* 
 * ServerImpl.java 
 */ 
  

import java.sql.*; 
  

/** 
 * Server.java implements the methods defined in t 
 * the IDL file.  It uses JDBC to connect to an 
 * Oracle database.  It extends the IDL defined 
 * ServerImpl class, which implements the Server 
 * interface defined in the IDL.  The Java files 
 * referred to are created by the utility that 
 * maps IDL files to Java classes. 
 */ 
public class ServerImpl extends _ServerImplBase { 
  

  // This is the database connection object. 
  Connection connection; 
  

  /** 
   * The constructor does the initialization 
   * required by the parent class, and sets up 
   * the database connnection. 
   */ 
  public ServerImpl(String name) { 
    super(name); 
    try { 
      // The following two lines connect to the 
      // database and initialize the connection 
      // object. 
      Class.forName 
        ("oracle.jdbc.driver.OracleDriver"); 
      connection = DriverManager.getConnection 
        ("jdbc:oracle:thin:imparto/password" + 
         "@databasem:1521:ORCL2"); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 
  

  /** 
   * record() is the method that takes in the 
   * client data (passed using the IDL defined 
   * Data object) and inserts it into the 
   * database. 
   */ 
  public boolean record(Data data) { 
    PreparedStatement statement = null; 
    String sqlstring; 
    try { 
      // The prepared statement inserts the 
      // data into the SQL update, which  
      // is passed to the database. 
      sqlstring = 
        "INSERT into user_data " + 
        "(name, hours)" + 
        "VALUES (?, ?)"; 
      statement = connection 
        .prepareStatement(sqlstring); 
  

      // The following two lines put the 
      // actual client data into the 
      // statement. 
      statement.setString(1, data.name); 
      statement.setString(2, data.hours); 
      if (statement.executeUpdate() < 0) 
        return false; 
      return true; 
    } catch (Exception e) { 
      e.printStackTrace(); 
      return false; 
    } finally { 
      try { 
        statement.close(); 
      } catch (Exception e) { 
        e.printStackTrace(); 
      } 
    } 
  } 
  

  /** 
   * This is a utility method to make 
   * sure the connection is closed when 
   * the client side exits. 
   */ 
  public boolean close() { 
    try { 
      connection.close(); 
      return true; 
    } catch (Exception e) { 
      return false; 
    } 
  } 
} 
  

----------------------------------------------- 
  

/* 
 * ServerWrapper.java 
 */ 
  

/** 
 * ServerWrapper initializes the ORB and creates 
 * the server side object. 
 */ 
public class ServerWrapper { 
  /** 
   * The application just initializes everything, 
   * loads the ServerImpl object, and notifies 
   * the ORB that everything's ready. 
   */ 
  public static void main(String[] args) { 
    // This initializes the ORB on the 
    // server side. 
    org.omg.CORBA.ORB orb =  
      org.omg.CORBA.ORB.init(args, null); 
  

    // This initializes the BOA, or Basic 
    // Object Adapter.  The BOA is implementation 
    // specific, and adapts objects so that they 
    // can be understood by the ORB.  It also 
    // handles the interface between the server 
    // and the ORB. 
    org.omg.CORBA.BOA boa = orb.BOA_init(); 
  

    // The server implementation is 
    // instantiated here. 
    Server server = new ServerImpl("Server"); 
  

    // The next two lines tell the BOA to 
    // notify the ORB that everything is ready. 
    boa.obj_is_ready(server); 
    boa.impl_is_ready(); 
  } 
} 

Listing 2.
 
/* 
 * ReportApplet.java 
 */ 
  

import java.applet.Applet; 
import java.awt.*; 
import java.awt.event.*; 
import java.net.URL; 
  

/** 
 * This is a simple applet that uses a servlet to 
 * generate a report.  The applet accepts a name 
 * as a parameter - if no name is specified, the 
 * whole list is shown. 
 */ 
public class ReportApplet extends Applet  
  implements ActionListener { 
  

  // The user name is entered here. 
  TextField name; 
  

  /** 
   * The init method simply calls the layout 
   * method. 
   */ 
  public void init() { 
    gridBagLayout(); 
  } 
  

  /** 
   * gridBagLayout creates a simple GUI 
   * to communicate with the servlet code. 
   */ 
  public void gridBagLayout() { 
    GridBagLayout gbl = new GridBagLayout(); 
    setLayout(gbl); 
    GridBagConstraints c = 
      new GridBagConstraints(); 
    c.fill = GridBagConstraints.BOTH; 
    c.gridx = 0; 
    c.gridy = 0; 
    c.gridwidth = 1; 
    c.gridheight = 1; 
    c.weightx = 0.0; 
    c.weighty = 0.0; 
    Label label = new Label("Name:"); 
    gbl.setConstraints(label, c); 
    add(label); 
    c.gridx = 1; 
    c.gridy = 0; 
    c.weightx = 1.0; 
    name = new TextField(15); 
    gbl.setConstraints(name, c); 
    add(name); 
    c.gridy = 1; 
    Button button = new Button("View Report"); 
    button.addActionListener(this); 
    gbl.setConstraints(button, c); 
    add(button); 
  } 
  

  /** 
   * When the Submit button is pressed, this 
   * method is called.  This is where the 
   * actual communication with the server 
   * takes place. 
   */ 
  public void actionPerformed(ActionEvent evt) { 
    try { 
      // The url string is dependent on where 
      // the web server (or servlet runner) is 
      // running. 
      String urlString =  
        "http://mymachine:8080/" + 
        "servlet/ReportServlet"; 
  

      // If the name isn't filled in, generate 
      // the full report (see servlet code). 
      // If it is, send the name as part of 
      // the query. 
      if (!name.getText().equals("")) 
        urlString = urlString + "?name=" +  
          name.getText(); 
      URL url = new URL(urlString); 
  

      // Finally, show the report. 
      getAppletContext().showDocument(url, "reportWindow"); 
  

    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 
} 
  

---------------------------------------------------------- 
  

/* 
 * ReportServlet.java 
 */ 
  

import java.sql.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 
  

/** 
 * The report servlet gets the name of a user from 
 * the client side, and generates a report from 
 * the database.  If no name is specified, the 
 * servlet shows the full report.  This example 
 * uses an Oracle database. 
 */ 
public class ReportServlet extends HttpServlet { 
   
  /** 
   * doGet is the primary method for a GET 
   * request.  The information about the request 
   * is recorded here in req, and information 
   * about the response can be set using res. 
   */ 
  public void doGet (HttpServletRequest req,  
                     HttpServletResponse res) { 
  

    // The database connection 
    Connection connection = null; 
  

    // A prepared statement for accessing the 
    // database 
    PreparedStatement statement = null; 
  

    // A result set to hold the database results 
    ResultSet resultSet = null; 
  

    // The SQL string 
    String sqlstring = null; 
  

    try { 
       
      // The following line gets the value of 
      // the parameter "name" from the query 
      // string.  lName will be set to null 
      // if the parameter is not set. 
      String lName = req.getParameter("name"); 
  

      // The following two lines connect to the 
      // database and initialize the connection 
      // object. 
      Class.forName 
        ("oracle.jdbc.driver.OracleDriver"); 
      connection = DriverManager.getConnection 
        ("jdbc:oracle:thin:imparto/password" + 
         "@databasem:1521:ORCL2"); 
       
      // This sets the type to text/html, and 
      // opens the output stream.  Anything 
      // written to this stream will show up 
      // on the generated page. 
      res.setContentType("text/html"); 
      ServletOutputStream out =  
        res.getOutputStream(); 
       
      // The SQL query depends on whether a 
      // name is specified or not. 
      if (lName == null) { 
        sqlstring =  
          "SELECT name, hours " + 
          "FROM user_data"; 
        statement =  
          connection.prepareStatement(sqlstring); 
      } else { 
        sqlstring = 
          "SELECT name, hours " + 
          "FROM user_data " + 
          "WHERE name = ?"; 
        statement =  
          connection.prepareStatement(sqlstring); 
        statement.setString(1, lName); 
      } 
  

      // The result set is pulled from the  
      // database. 
      resultSet = statement.executeQuery(); 
       
      // Before the servlet examines the result 
      // set, it sets up the HTML page it is 
      // writing to. 
      out.println("<html>"); 
      out.println("<head><title>Name And Hours" 
                  + " Report</title></head>"); 
      out.println("<body>"); 
      out.println("<h1>Report:</h1>"); 
      out.println("<table border=1><tr><th>" + 
                  "Name</th><th>Hours" + 
                  "</th></tr>"); 
       
      // Now the servlet examines the result 
      // set, and adds the information to 
      // the report. 
      while (resultSet.next()) 
        out.println 
          ("<tr><td>" +  
           resultSet.getString("name") +  
           "</td><td>" +  
           resultSet.getString("hours") +  
           "</td></tr>"); 
  

      // The HTML page is closed. 
      out.println("</table>"); 
      out.println("</body></html>"); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 
} 
 
 
 
      

Download Assoicated Source Files (Zip format - 5.58 KB)
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.