©1997-98 Barry Cornelius

Using CORBA and JDBC to produce Three Tier Systems

Using CORBA and JDBC to produce Three Tier Systems is the name of a document used to support a talk. It assumes some knowledge of programming with Java.

The pages of this document are Copyright 1997-98 Barry Cornelius.


Barry Cornelius, IT Service, University of Durham, Durham DH1 3LE, England

+44 191 374 4717 +44 191 374 3741 mailto:Barry.Cornelius@durham.ac.uk

Agenda

  1. Introduction
  2. An example of a three tier system
  3. Using JDBC to access a database server
  4. Using CORBA to talk with remote objects
  5. Compiling the files of the example
  6. Running the example
  7. Further information
  8. Other resources
  9. Conclusions

Introduction

Client-server computing has traditionally been done using sockets. A socket is a point of connection within a program to the Internet, and a program can start to communicate when it arranges for the socket to bind to a port of the computer that is running the program.

The Java classes java.net.DatagramSocket, java.net.ServerSocket and java.net.Socket provide easy-to-use ways of writing programs that use sockets. For some initial experiences of using sockets when teaching distributed computing, see the paper that Alan Battersby (Nottingham Trent University) presented at last year's Java in the Computing Curriculum conference: http://www2.ulst.ac.uk/misc/cticomp/init.html.

However, in Java, client-server computing can be performed without having to work at the level of sockets. This is because Java has several application programming interfaces (APIs) that offer higher levels of abstraction for client-server computing.

In this document, we look at two APIs: Common Object Request Broker Architecture and Java DataBase Connectivity. The latter is a way in which a Java program can use SQL to access database servers, whereas the CORBA API allows us to rise up above the socket-level details of client-server computing when we want to access objects distributed across different computers.

In the past, client-server computing has usually involved just two computers talking to one another. Often a lot of the processing is going on in the client, which often means that the client is a big program. More recently, systems have been produced that use an intermediate layer: the client just provides a user interface whereas the intermediate layer contains all the complicated application logic. The document also introduces the idea of three tier systems.

An example of a three tier system

We will look at an unsophisticated three tier system. It uses a WWW browser that downloads a Java applet (AgesDBLet) from a WWW server running on a computer called perseus:



The Java applet will display three buttons and three textfields:



A click on a button will cause the Java applet to send a request (using JavaIDL) to a Java application (AgesDBServer) that is running on perseus. This Java application will use JDBC to send an appropriate SQL statement to a database server (msql2d) that is running on a computer called hercules.

The purpose of the Java applet is to present a user interface: most of the hard work will be done by the AgesDBServer program. For example, if we type a person's surname, first name and age into the three textfields, and then click on the Add button, the only thing that the Java applet will do is to pass this information on to the AgesDBServer program. The AgesDBServer program has an object that has a method for adding a person, a method for removing a person, and a method for obtaining a person's details. These methods contact the database server to update or inspect the database. In order to provide code for these methods, we need to know something about the JDBC API.

Using JDBC to access a database server

SQL

The Structured Query Language (SQL) is a language for use with relational databases. One of the most used SQL statements is the SELECT statement: it is used to inspect a table of information. The statement:

SELECT last, first FROM ages WHERE age >= 21
would look at a table called ages and produce a new table containing the surnames and first names of the people having an age of at least 21 years.

Although SQL has been evolving since the early 1980's, it was in 1990 that the SQL Access Group defined the Call Level Interface (CLI) as a standard for accessing databases. To implement it, you need a driver that can translate a CLI call into the language used to access a particular database.

ODBC

Microsoft's Open Database Connectivity (ODBC), an API for Microsoft Windows that implements an extended version of the CLI, was first released in 1992. Most database vendors (including CA/Ingres, IBM, Informix, Oracle and Sybase as well as Microsoft) now support the ODBC API.

ODBC is an API written for the programming language C and, although the Java Native Interface (JNI) allows a Java program to call a C function, there are disadvantages with calling C from Java:

So, instead Java has its own API for submitting SQL statements to a database server: it is JDBC (sometimes called Java DataBase Connectivity).

JDBC

The JDBC API forms part of JDK 1.1.x: it is in the java.sql package. It was not part of JDK 1.0.2: however, if you have a JDK 1.0.2 program, a version of the JDBC API can be downloaded for use with JDK 1.0.2.

The JDBC API is implemented via a driver manager that can support multiple drivers connecting to different databases. A JDBC driver can either be written entirely in Java so that it can be downloaded as part of an applet or it can be implemented using native methods to bridge to existing database access libraries.

At the WWW page http://java.sun.com/products/jdbc/jdbc.drivers.html, Sun gives details of the drivers that are available from a number of vendors. On this page, they distinguish between four types of JDBC drivers:

  1. "The JDBC-ODBC bridge provides JDBC access via most ODBC drivers. Note that some ODBC binary code and in many cases database client code must be loaded on each client machine that uses this driver, so this kind of driver is most appropriate on a corporate network, or for application server code written in Java in a 3-tier architecture."
  2. "A native-API partly-Java driver converts JDBC calls into calls on the client API for Oracle, Sybase, Informix, DB2, or other DBMS. Note that, like the bridge driver, this style of driver requires that some binary code be loaded on each client machine."
  3. "A net-protocol all-Java driver translates JDBC calls into a DBMS-independent net protocol which is then translated to a DBMS protocol by a server. This net server middleware is able to connect all its Java clients to many different databases. The specific protocol used depends on the vendor. In general, this is the most flexible JDBC alternative. It is likely that all vendors of this solution will provide products suitable for Intranet use. In order for these products to also support Internet access they must handle the additional requirements for security, access through firewalls, etc., that the Web imposes. Several vendors are adding JDBC drivers to their existing database middleware products."
  4. "A native-protocol all-Java driver converts JDBC calls into the network protocol used by DBMSs directly. This allows a direct call from the client machine to the DBMS server and is a practical solution for Intranet access. Since many of these protocols are proprietary the database vendors themselves will be the primary source for this style of driver. Several database vendors have these in progress."

A Type 4 driver for mSQL

Hughes Technologies has produced mSQL (or Mini SQL). This is a "light-weight relational database management system that has been designed to provide rapid access to data sets with as little system overhead as possible". The system is comprised of a database server that will run on most Unix platforms together with various tools that allow a user or a client application to communicate with the server. Use of mSQL in any commercial environment requires the purchase of a license from Hughes Technologies. However, free licenses are provided to organisations such as Universities, schools and registered charities. For more details about mSQL, see http://www.Hughes.com.au.

George Reese, a software engineer from Minneapolis, provides a free JDBC driver for mSQL. This can be downloaded from the WWW page http://www.imaginary.com/Java/.

A Type 1 driver for Microsoft Access

An ODBC driver for use with Microsoft Windows 95/NT products, such as Access and SQL Server, can be obtained from http://support.microsoft.com/support/kb/articles/Q159/6/74.asp. Once you have an ODBC driver, then the easiest method to use is the JDBC-ODBC bridge. This is provided as part of JDK 1.1.x.

How do you use JDBC?

A Java program that wants to use JDBC to access a database server will normally consist of the following steps:

  1. Use the getConnection method (of the class java.sql.DriverManager) to establish a connection to a database.
  2. Use the createStatement, prepareStatement or prepareCall method.
  3. For the prepareStatement and prepareCall methods, use calls of setXXX methods to establish any parameters that are needed by the statement.
  4. Use execute, executeQuery or executeUpdate to execute the statement.
  5. If the statement is a query, process the result set that is returned.
  6. Close the statement.
  7. Do steps 2 to 6 for each statement you wish to process.
  8. Close the connection that was established by getConnection.
By default, all the SQL statements will automatically be committed: this is called autocommit mode. However, you can disable this and execute calls of commit or rollback yourself.

Using JDBC in our example

Here is an incomplete draft of the AgesDBServer program:

  1:public class AgesDBServer {
  2:   public static void main(String[] args) {
  3:      AgesDBServant AgesDBRef = new AgesDBServant();
  4:   }
  5:}
It creates an object of the class AgesDBServant. Here is an incomplete draft of this class:
  6:public class AgesDBServant {
  7:   public AgesDBServant() {
  8:      Class.forName("COM.imaginary.sql.msql.MsqlDriver");
  9:      String tURLString = "jdbc:msql://hercules.dur.ac.uk:4333/bjc1";
 10:      iConnection = DriverManager.getConnection(tURLString, "", "");
 11:   }
 12:   public synchronized void addPerson(String rLast, String rFirst, String rAge){
 13:      Statement tStatement = iConnection.createStatement();
 14:      String tSQLString = "insert into ages values('"
 15:                           + rFirst + "', '" + rLast + "', " + rAge + ")";
 16:      int tNumberOfRows = tStatement.executeUpdate(tSQLString);
 17:      tStatement.close();
 18:   }
 19:   private Connection iConnection = null;
 20:}
When the constructor of this class is executed, the class COM.imaginary.sql.msql.MsqlDriver is loaded. This class is the main class of George Reese's JDBC-mSQL driver. The constructor also establishes a connection with a database called bjc1 known to an msql server operating through port 4333 on hercules.dur.ac.uk. The Java application's communications with this msql server will be provided by the JDBC-mSQL driver.

Besides the constructor, this class also provides methods called getPerson, addPerson and removePerson. Each of these leads to a call of a method to update or inspect the database. In the above code, only the addPerson method is shown. It causes the JDBC's executeUpdate method to be executed with an argument containing an SQL INSERT statement like:

insert into ages values('Cornelius', 'Barry', 42)

If we now want to modify the AgesDBServer program so that the methods of the AgesDBRef object are executable by programs on other computers, we need to look at how to access remote objects.

Using CORBA to talk with remote objects

What is CORBA?

CORBA is the Common Object Request Broker Architecture. It is an ongoing effort by the Object Management Group (OMG) to define interfaces for interoperable software. Work on CORBA started several years ago, and there are now over 700 members of OMG including virtually all of the computer manufacturers and most of the major software vendors.

Using an Object Request Broker

If you are using CORBA, communications between two computers is performed using an Object Request Broker (ORB). An object in a program running on some computer (the client) can use the ORB to access the public attributes of another object in some other program perhaps on a different computer (the server) that is also using an ORB. The client object can:

In this document, we will only be using Static Method Invocation.

Although an ORB can be running on a single computer, it is more likely to be used to aid communication between one or more client computers and a server computer. If an ORB is unable to satisfy a request from a client, then, if it is connected to other ORBs (elsewhere in the world), the request may be satisfied by an object known to a remote ORB.

Interface Definition Language

One of the key aspects of CORBA is the OMG Interface Definition Language (IDL). This is the language that is used to describe the interface that an object has. It is a language that looks something like C, C++ or Java. For example, it has function declarations and interfaces; it has types such as boolean, char, string, short, long, float and double.

Having produced an IDL file that describes the interface that an object has, we also need some code for the server that creates an object that implements that interface, and we will also need codes for clients that wish to access the object. These codes need to be written in real programming languages. In order for an interface written in IDL to be usable with existing languages, there needs to be a mapping that says what each IDL feature is in each language. For example, the IDL-to-Java mapping defines that an IDL long is an int in Java, an IDL string is a String in Java, ... . Currently, there are bindings for Ada, C, C++, Java and Smalltalk.

The client and server programs may be in different languages. Each program can run on any operating system written in any language so long as you have a compiler to translate the interface from IDL into that language on that operating system.

Vendors providing ORBs

There are many vendors providing ORBs. In this document, we will be using JavaIDL from Sun Microsystems. Some other ORBs are listed in the Further information about some other ORBs section given later.

At the present time, Sun's JavaIDL is not part of the JDK: however, it can be downloaded from Sun's JavaIDL page at http://java.sun.com/products/jdk/idl/ and used with JDK 1.0.2 or JDK 1.1.x. JavaIDL will form part of JDK 1.2, and a beta release of JDK 1.2 is available from http://java.sun.com/products/jdk/1.2/. A version of JavaIDL is also supplied with Sun's Solaris 2.6 operating system.

Providing an interface for our example

We want the Java applet to access the methods of the AgesDBRef object of the Java application (AgesDBServer) running on perseus. In order to do this using CORBA, we will need an interface (written in IDL) in the file AgesDB.idl that defines the services available from the object:

 21:module AgesDBApp {
 22:   interface AgesDB {
 23:      void getPerson(in string rLast, out string rFirst, out string rAge);
 24:      void addPerson(in string rLast, in string rFirst, in string rAge);
 25:      void removePerson(in string rLast);
 26:   };
 27:};
When JavaIDL's idltojava command is used to translate this file into Java, it will also produce a class called _AgesDBImplBase in a subdirectory called AgesDBApp.

Modifying AgesDBServer to make the object available

Earlier, a draft of the class AgesDBServant was given. We can get AgesDBServant to implement the above interface if it extends the class _AgesDBImplBase:

 28:import AgesDBApp._AgesDBImplBase;
 29:import org.omg.CORBA.StringHolder;
 30:public class AgesDBServant extends _AgesDBImplBase {
 31:   public AgesDBServant() {
 32:      ...
 33:   }
 34:   public synchronized void getPerson(String rLast,
 35:                                      StringHolder rFirst, StringHolder rAge) {
 36:      ...
 37:   }
 38:   public synchronized void addPerson(String rLast, String rFirst, String rAge){
 39:      ...
 40:   }
 41:   public synchronized void removePerson(String rLast) {
 42:      ...
 43:   }
 44:   private Connection iConnection = null;
 45:}

Earlier, a draft of a Java application (AgesDBServer) that creates an object (AgesDBRef) of this class was given. In order for the methods of this object to be available to clients such as our Java applet, AgesDBServer can register the object with the ORB's Naming Service. The following version of AgesDBServer asks the Naming Service to bind the name AgesDB to the object AgesDBRef. After it has done that, it sits waiting for clients to connect:

 46:import org.omg.CosNaming.NameComponent;                 // AgesDBServer.java
 47:import org.omg.CosNaming.NamingContext;
 48:import org.omg.CosNaming.NamingContextHelper;
 49:import org.omg.CORBA.ORB;
 50:public class AgesDBServer {
 51:   public static void main(String[] args) {
 52:      try{
 53:         ORB orb = ORB.init(args, null);
 54:         AgesDBServant AgesDBRef = new AgesDBServant();
 55:         orb.connect(AgesDBRef);
 56:         org.omg.CORBA.Object objRef = 
 57:               orb.resolve_initial_references("NameService");
 58:         NamingContext ncRef = NamingContextHelper.narrow(objRef);
 59:         NameComponent nc = new NameComponent("AgesDB", "");
 60:         NameComponent path[] = {nc};
 61:         ncRef.rebind(path, AgesDBRef);
 62:         java.lang.Object sync = new java.lang.Object();
 63:         synchronized (sync) {
 64:            sync.wait();
 65:         }
 66:      }
 67:      catch (Exception rException) {
 68:         rException.printStackTrace();
 69:      }
 70:   }
 71:}

Accessing the object from a Java applet

Having shown some of the code of the server, we will now look at the code of the client, the Java applet. The following WWW page assumes that all the classes we wish to download have been stored in a Java Archive:

 72:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
 73:<HTML><HEAD><TITLE> The AgesDBLet Program </TITLE></HEAD>
 74:<BODY>
 75:<APPLET ARCHIVE=AgesDBLet.jar CODE="AgesDBLet.class" WIDTH=700 HEIGHT=700>
 76:<PARAM NAME=org.omg.CORBA.ORBInitialHost VALUE="perseus.dur.ac.uk">
 77:<PARAM NAME=org.omg.CORBA.ORBInitialPort VALUE=1050>
 78:</APPLET>
 79:</BODY></HTML>
When the page is visited, the WWW browser will download all the classes in the Java Archive AgesDBLet.jar and then it will start interpreting using an object of the class AgesDBLet.class passing to it the two parameters mentioned in the PARAM tags.

If the Java applet wishes to access the methods of our object, then it first has to connect to an ORB and find the object registered with the name AgesDB. This is done by the following code. Because of the parameters that have been passed to the applet, the ORB knows that we wish to use the Naming Service running on perseus:

 80:ORB orb = ORB.init(this, null);
 81:org.omg.CORBA.Object objRef = 
 82:       orb.resolve_initial_references("NameService");
 83:NamingContext ncRef = NamingContextHelper.narrow(objRef);
 84:NameComponent nc = new NameComponent("AgesDB", "");
 85:NameComponent path[] = {nc};
 86:iAgesDB = AgesDBHelper.narrow(ncRef.resolve(path));
where iAgesDB is a private variable of the interface AgesDB. Having executed this code, the reference variable iAgesDB is a means by which the Java applet can refer to the remote object.

The above code needs to be executed when the applet is loaded, and so it is best placed in the applet's init method. The init method also needs the following statements to add the buttons and the textfields to the applet:

 87:add(iGetButton);
 88:add(iAddButton);
 89:add(iRemoveButton);
 90:add(iLastTextField);
 91:add(iFirstTextField);
 92:add(iAgeTextField);

Since this applet may be executed from a browser that only understands JDK 1.0.2, we will override the handleEvent method in order to react to any clicks on the three buttons. For example, the following code in the handleEvent method will be executed if there is a click on the Add button:

 93:if (rEvent.target.equals(iAddButton)) {
 94:   iAgesDB.addPerson(iLastTextField.getText(), 
 95:         iFirstTextField.getText(), iAgeTextField.getText());
 96:   return true;
 97:}

How does an ORB work?

The client program does not have immediate access to the object on the server. Instead, a lot of magic takes place:



The value assigned to iAgesDB in the AgesDBLet program is a reference to an object that is part of the client program. This object is a stub that acts as a proxy for the remote object. When the client program calls a method, say, it calls iAgesDB.addPerson(...), then it is actually calling a method called addPerson of the stub. This method knows nothing about how to add a person to the database. Instead, what it does is to transmit the required operation to the server: it does this by arranging for the method and its parameters to be marshalled into a stream of bytes.

Within the Java application running on the server, there is the real object. However, besides this real object there is also a skeleton object (of class _AgesDBImplBase). The skeleton has a method that arranges for any incoming requests to be unmarshalled. By this means, it finds out what method is to be called and what arguments are to be supplied to the call. It then calls the appropriate method of the real object with the appropriate arguments.

If the method being called returns some result, then the skeleton's method will get the result, serialize the result, and pass the bytes back to the client computer. The method in the stub will receive these bytes, de-serialize them, and return a value to the caller.

So besides the code that you write for the client and the server, you will also need code for the stub and the skeleton. Fortunately, JavaIDL's idltojava command (which was mentioned earlier) will automatically generate the stub and skeleton files for you.

Compiling the files of the example

First, compile the interface in the file AgesDB.idl by executing JavaIDL's idltojava command:

setenv JAVAIDL_HOME /users/hplives/JavaIDL-1.1EA
setenv PATH $JAVAIDL_HOME/bin:$PATH
idltojava -fclient -fserver AgesDB.idl
This command creates a directory called AgesDBApp for the stub and skeleton classes.

We need to compile AgesDBServer.java, the Java application of the middle tier. In order to compile this file, we will need access to the bytecodes of the classes of the JavaIDL API. These classes are provided in the file $JAVAIDL_HOME/lib/classes.zip. For a technical reason (to do with JavaStations), this file will be unzipped, to create two directories in the current directory called com and org. Having done that, we can compile the Java application of the middle tier with a JDK 1.1.x compiler:

javac AgesDBServer.java

Finally, compile the client program with a JDK 1.0.2 or JDK 1.1.x compiler:

javac AgesDBLet.java
This compilation will use the JavaIDL classes in the com and org directories that were created earlier. In order to simplify the loading of these classes whenever the Java applet is downloaded, we will use JDK 1.1.x's jar command to build a Java Archive that contains all of these files:
jar cf AgesDBLet.jar AgesDBLet.class AgesDBApp org com

Running the example

Before running the server, we need to start JavaIDL's Naming Service program. We can do this using JavaIDL's nameserv command:

nameserv -ORBInitialPort 1050 &
This command will produce output like:
Initial Naming Context:
IOR:000000000000002849444c3a6f6d672e6f72672f436f734e616d696e672f4e616d696e67436
f6e746578743a312e3000000000010000000000000034000100000000000968657263756c657300
00805e0000001cafabcafe000000023448a50500000000000000080000000000000000
TransientNameServer: setting port for initial object references to: 1050

The server can then be started using the commands:

setenv CLASSPATH /users/dcl0bjc/public_html/Java:.
java AgesDBServer -ORBInitialPort 1050 &

Having started the server, the Java applet can be run by anyone having a WWW browser that can handle Java Archives. Examples are Microsoft's Internet Explorer, Netscape's Navigator 3.0x and JDK 1.1.x's appletviewer:

appletviewer http://perseus.dur.ac.uk/~dcl0bjc/Java/ThreeTier/Ages/AgesDBLet.html
Because of an incompatibility, such applets do not work with Netscape's Navigator 4.0x. I have also used this applet as the applet behind one of the buttons on the desktop when using HotJava Views on a JavaStation.

The complete texts of the programs referred to in this document are in the directory located at http://www.dur.ac.uk/~dcl0bjc/Java/ThreeTier/Ages/.

Further information

Further information about JDBC

Sun has a JDBC page at http://java.sun.com/products/jdk/1.1/docs/guide/jdbc/. A useful guide to JDBC is at http://java.sun.com/products/jdk/1.1/docs/guide/jdbc/getstart/introTOC.doc.html.

Sun's main JDBC page at http://java.sun.com/products/jdbc/ includes details about vendors who have JDBC drivers, an FAQ, and a link to download a JDBC for use with JDK 1.0.2.

Another JDBC FAQ is at http://javanese.yoyoweb.com/JDBC/FAQ.txt.

As mentioned above, details about mSQL can be obtained from http://www.Hughes.com.au and details about the mSQL-JDBC driver can be obtained from http://www.imaginary.com/Java/. This latter page also contains a link to some documentation for the driver, details about the msql-jdbc mailing list, and some details about George Reese's book Database Programming with JDBC and Java. This book is published by O'Reilly; its ISBN is ISBN 1-56592-270-0.

Netscape has a technical note about writing database applications in Java at http://developer.netscape.com/library/technote/database/web/.

Further information about JavaIDL

Sun's main JavaIDL page is at http://java.sun.com/products/jdk/idl/. On that page, you will find links to some useful pages entitled Documentation, Examples, Download/EarlyAccess and Other references. In particular, the Download/EarlyAccess link enables you to download the Early Access Release of JavaIDL for use with JDK 1.0.2 or JDK 1.1.x.

The above code is derived from Sun's Hello example which is subject to the copyright and licensing information given at http://java.sun.com/products/jdk/idl/docs/examplelicense.html.

The details of the JavaIDL being released with JDK 1.2 are documented at http://java.sun.com/products/jdk/1.2/docs/guide/idl/.

In many ways, Remote Method Invocation (RMI) and CORBA are competing technologies. Sun's position about this is explained at http://java.sun.com/features/1997/nov/rmi.html.

Further information about some other ORBs

Here are a few details about some other ORBs:

The Cetus Links on ORBs are at http://www.parallax.co.uk/cetus/oo_object_request_brokers.html.

Further information about CORBA

OMG has a lot of information about CORBA at http://www.omg.org/.

The CORBA FAQ is at http://www.cerfnet.com/~mpcline/Corba-FAQ/.

The Advanced Computing Laboratory at the Los Alamos National Laboratory has a page of resources about CORBA and the OMG at http://www.acl.lanl.gov/CORBA.

The Cetus Links on CORBA are at http://www.parallax.co.uk/cetus/oo_corba.html.

Netscape has a CORBA White Paper http://developer.netscape.com/library/wpapers/corba/, and other CORBA documents at http://developer.netscape.com/library/documentation/corba.html.

Further information about three tier systems

Sun has a WWW page describing three tier systems at http://java.sun.com/products/jdk/1.2/docs/guide/idl/jidlDistApp.html.

For more about JavaStations and HotJava Views, see http://www.sun.com/javastation/ and http://java.sun.com/products/hotjavaviews/.

Other resources

One good book is Client/Server Programming with Java and CORBA (1997) by Robert Orfali and Dan Harkey published by Wiley (0-471-16351-1) http://www.corbajava.engr.sjsu.edu/Progrmg.htm. It contains extensive sections on both CORBA and JDBC, and the use of CORBA and JDBC to build multi-tier systems. They also compare CORBA with other methods: sockets, HTTP/CGI and RMI. The second edition of this book (0-471-24578-X) "with 250 pages of new material" is due out in February 1998. Working with Jeri Edwards, Orfali and Harkey have three other books in this area: Essential Client/Server Survival Guide (2nd edition 1996), Essential Distributed Objects Survival Guide (1996) and Instant CORBA (1997). See http://www.corbajava.engr.sjsu.edu/mbooks.htm.

Prashant Sridharan's book Advanced Java Networking explores the topics covered in this document. Its ISBN is 0-13-749136-0 and it is published by Prentice-Hall http://www.prenhall.com/.

Sams.net Publishing have several overlapping books on Java, and their Unleashed book keeps moving into new editions. Many of the chapters of Java 1.1 Unleashed Third Edition describe various aspects of client-server computing. Its ISBN is 1-57521-298-6. For more details, see: http://merchant.superlibrary.com:8000/catalog/hg/PRODUCT/PAGE/15752/bud/1575212986.html.

CORBA, JDBC and three tier systems are explored in more detail in my 30 page document entitled Developing Distributed Systems. This document also covers Remote Method Invocation (RMI), includes details about IORs, discusses the use of OmniBroker which is another ORB, discusses the mixing of JavaIDL and OmniBroker, and includes some ORB clients written in C++. It is available from http://www.dur.ac.uk/~dcl0bjc/Java/. This WWW page also contains other documents on Java including a 52 page tutorial on Java, an overview of the material of the tutorial, and some notes comparing Java and C++.

Conclusions

Many distributed systems have been built that are two tier. This is a system that has a client program communicating with a server program. Typically, the user interface is in the client and the server is there to process data, e.g., to manipulate a database. The complicated application logic (or business logic) is often put in the client (or in the server).

More recently, three tier systems have come into favour. This is where an additional tier is interposed: it is there to handle the application logic leaving the client just to handle the user interface. There are a number of advantages to this approach. For example:

In this document, we have outlined the way in which a three tier system can be built using the APIs for JDBC and CORBA.