Introduction
In
this article we describe the author's experience with the unconventional development
of Internet applications. They were developed for a Suisse bank as a joint cooperation
between the author located in Belgrade, Yugoslavia, and a Suisse software development
company. The software was developed in a distributed fashion without any physical
access to the production site.
Due
to the very strict bank's security rules, previously developed applications
used by the newly developed applications were not available for installation
on the remote development site. For that reason, simple stubs were developed
to emulate the behavior of previously developed but unavailable, CORBA (Common
Object Request Broker Architecture) and database applications.
In
addition, the application had to support multiple spoken languages, thus the
developed software had to be internally independent of any particular spoken
language. In this article we describe a number of useful tips and tricks of
trade that may be helpful to developers facing similar situations. We will describe
the three-tier system architecture, the development of CORBA and database portions
of the applications, and present tips on multi-lingual application development.
System Architecture
Figure
1 depicts the three-tier system architecture typical for Internet applications.
Users use web browsers to access various online banking applications via the
Internet. Applications are executed by a web server. An example of such an application
is the quotation of currency exchange rates. The user selects desired currencies
and a branch of bank on a query input form and submits the query. The web server
accepts the query, processes it, and returns the response back to the user's
browser. Depending on the particular application, the web server may consult
with a CORBA application server and/or a database server. The response is returned
in the user's language of choice (German, French, Italian, or English).
Figure
1. System architecture

Per
the bank's internal software development standard, all Internet applications,
executed by the web server, are written using Java programming language and
Java servlets. Although people from the Microsoft camp will
most certainly disagree, this is a de facto standard for writing serious Internet
applications.
All
servers in the production environment run Sun Microsystems Solaris
UNIX operating system. The web server is NES (Netscape
Enterprise Server) with the addition of JRun engine
for running Java servlets. The database server is Oracle.
The CORBA application server is IONA OrbixWeb. CORBA clients
use an internally developed API (Application Programming Interface) and wrapper
Java classes developed on top of OrbixWeb.
The
challenge in this project was to develop software in a distributed fashion without
any physical presence at the production site, while still adhering to the very
strict bank's security rules.
First,
per the bank's development protocol, software developers do not have direct
physical access to the production system. Instead, the developed software is
handed over to the production system staff for final testing and installation
on the production system.
Second,
for security reasons, the already developed software cannot be taken out of
the bank's premises for installation on a remote development system. It means
that copies of the database and the applications running on the CORBA server
were not available at the development site. Instead, stubs had to be developed
to emulate the behavior of CORBA and database servers.
The
entire software described in this article was developed on a single Windows
NT Workstation. The CORBA server was one that comes with the JDK
(Java Development Kit). The database was Microsoft
Access. The web server was Apache with the JServ engine for running
Java servlets. Software was developed using Oracle JDeveloper
IDE (Integrated Development Environment). Obviously, the development
and the production environments were very different, which was one of the development
challenges.
The
only contact between the development and the production sites was over the phone
and via e-mail, thus software was developed solely in a telecommuting fashion.
Once the database and CORBA stubs were set-up on the development site, and a
basic skeleton of the application was set-up on the production site, it was
easy to gradually build the application on the development site and test it
on the production site. Software was shipped via e-mail in the form of compiled
JAR (Java Archive) files and static text, HTML (Hyper-Text Markup Language),
and graphic files.
Throughout
the rest of this article, we will describe some of the tricks of trade used
to overcome the development challenges.
CORBA Implementation
CORBA
standard was, at least in theory, developed to standardize invocation of remote
applications in networks. However, in practice, this is far from reality. In
theory, the development of code which invokes remote, already developed applications,
involves the following steps:
-
Use the remote application's IDL (Interface Definition Language) specification,
and an IDL compiler to generate API stub code for invoking remote applications
in the desired programming language (Java, C, C, C++).
-
Develop code for initiating the ORB (Object Request Broker) within the calling
application under development.
-
Develop code for invoking remote applications from within the calling application
under development.
However,
in practice, there are a number of problems:
-
CORBA applications developed in different programming languages may have problems
talking to each other even when the development tools and the underlying libraries
are produced by the same vendor.
-
Java API specification is developed to standardize API and IDL stubs of all
Java applications, thus maximize code portability. However, vendors of CORBA
development tools like IONA did not adhere to this standard, so software developed
using JDK and it's IDL compiler and CORBA name server cannot run using IONA's
CORBA name server.
-
Even different CORBA development tools of the same vendor, like IONA's OrbixWeb
and Orbix 2000, are not mutually compatible, and require different application
code.
Fortunately,
the differences and incompatibilities in the application code apply mostly to
a relatively small portion of the ORB initiation code. For that reason, it was
possible to develop code using JDK CORBA environment and port it to the OrbixWeb
production environment as follows:
-
Use the JDK IDL compiler to compile IDL specification and generate Java stubs
for the development environment.
-
Develop and test the application using the ORB initiation code appropriate
for the JDK environment.
-
Use the OrbixWeb IDL compiler to compile IDL specification and generate Java
stubs for the OrbixWeb production environment.
-
Replace the ORB initiation code with the code needed for the OrbixWeb production
environment.
Once
this porting procedure is established, delivery of code modification is very
efficient with a little help of code building scripts.
The
other problem with the development of CORBA code was unavailability of the original
CORBA application server. This problem was solved by developing a simple stub
application server that emulates responses of the real application server. The
stub server loads test data from a text file and upon request passes it to the
CORBA client, i.e., to the requesting servlet in this case.
Database Implementation
Portability
of JDBC (Java Database Connection) code is significantly better than CORBA related
code. As long as database operations are restricted to standard SQL (Structured
Query Language) and free of triggers and stored procedures, developed Java code
runs on virtually any database. Porting to a different database type performed
by simply specifying a different database source and driver in a database configuration
textual file such as:
JDBCDriver
= sun.jdbc.odbc.JdbcOdbcDriver
JDBCConnectionURL = jdbc:odbc:DbSource
The
above two lines define database source named DbSource defined in the Windows
ODBC (Open Database Connection) manager and the Sun Microsystems' JDBC-ODBC
bridge database driver. By modifying the two lines in the database configuration
file, one can switch from, e.g., Microsoft Access database at the development
site to Oracle database at the production site. As a matter of fact, this approach
is so convenient that the author used it in many other Java projects that involved
databases. Microsoft Access allows quick prototyping and modification. Once
the database design is finalized, the database can be ported to Oracle using
an Oracle database porting tool. In addition, this approach allows the use of
a laptop computer for demonstration of work in progress at a customer's site.
This
approach was used in the project described in this article to quickly create
the database stub that emulates behavior of the database at the production site.
Since the application used a small subset of tables and fields in the actual
database, replication of their structure at the development site was quick and
easy.
When
it comes to database Internet applications, another trick worth mentioning is
the use of database connection pools. A typical servlet-based Internet application
that uses a database involves three steps when a servlet is invoked: connecting
to the database, accessing data, and disconnecting from the database. Connecting
to the database is a time-consuming operation. For that reason, pools of pre-established
database connections are maintained. Each servlet maintains a connection pool
which consists of a configurable number of pre-established database connections.
Instead of waiting for the connection to be established, a database request
takes an already established connection from the pool, uses it, and later returns
it back to the pool for further reuse. The use of connection pools significantly
improves the application's performance. Oracle's JDeveloper IDE comes with a
library that implements a connection pool manager. However, the author uses
one of many connection pool implementations available for download from the
Internet.
Multi-Lingual Implementation
Software
described in this article had to support four languages, i.e., the user had
to be able to submit queries and receive responses in the selected preferred
language. Figure 2 depicts a general appearance of the user interface displayed
in the user's web browser.
Figure 2. General appearance of the user interface

The
user interface consists of two HTML frames. The upper frame is a static HTML
page, written in the user's language of choice. It contains the language selection
menu on the left side, and the query input form on the right side. The query
form contains a hidden form parameter language that defines the form's language.
For example, language=4 corresponds to English language. This parameter is submitted
together with other query parameters so that the servlet knows it has to respond
in English language.
The
lower frame contains response to user's queries. Responses are dynamically generated
by Java servlets.
Figure
3 shows the organization of Internet directories which contain different file
types and files which correspond to different languages. A good initial organization
of directories allows easy maintenance at a later time.
Figure
3. Organization of the Internet directories

The
root directory contains static HTML files common to all languages such as the
HTML frameset file which holds the two frames shown in Figure 2. The figures
directory contains graphic files common to all languages. The applets directory
contains Java applet classes and JAR files that contain applets.
The
servlets directory is not a physical directory. It is a virtual directory mounted
onto the web server's directory system so a servlet is invoked as it is in a
real directory such as http://www.aaa.ch/servlets/rates?p=a. The rates is a
servlet's external name followed by zero or more query parameters, depending
on the query and the method used to invoke the servlet (POST or GET).
The
four remaining directories, de, fr, it, and en contain static HTML and graphic
files which correspond to German, French, Italian, and English languages respectively.
Names and functions of files they contain are same except that their contents
are written in different languages.
In
order to make software internally independent of any particular language, all
language-dependent strings are referenced using their internal language-independent
symbolic names. To achieve this, we used one instance of java.util.Properties
class for each language known to the application. The Properties class contains
a set of name-value pairs of strings. A method getProperty(String name) and
the string's symbolic name are used to retreive string in a specific language.
An
instance of the Properties class may be loaded from a plain text property file
which contains lines that have a form name=value. In order to improve readability
of property files, we used a convention that property names have a form function.name.
For example, properties
title.RPT_TITLE=Currency
Exchange Rates
label.COUNTRY=Country
code.0119=Yugoslavia
error.DB_ERROR=Database error
define
a report title, a label, a country name internally referenced using country's
ISO (International Standards Organization) currency code, and an error message.
Property files for other languages have the right-hand side of the equality
sign translated to the corresponding language. During the initialization, an
application loads one property file (vocabulary) for each language it supports,
and creates an array of instances of Properties that correspond to supported
languages. Language-specific strings are retrieved using the internal string
name and the language code received from an HTML query form. The following code
may be used to translate internal language-independent string names to language-specific
strings:
private Properties[] vocab[4];
String getString(String name, int lang) {
String r;
if (lang>=1 && lang<=4) {
r=vocab[lang-1].getProperty(name);
if (r!=null) return r;
}
// Return untranslated name if
// undefined language or
// undefined string requested
return name;
}
String getTitle(String name, int lang){
return getString("title."+name, lang);
}
String getLabel(String name, int lang){
return getString("label."+name, lang);
}
String getCountry(String name, int lang){
return getString("code."+name, lang);
}
String getError(String name, int lang){
return getString("error."+name, lang);
}
Using the above code, the
four examples of strings may be translated to English as:
int lang=4;
String t=getTitle( "RPT_TITLE", lang);
String l=getLabel( "COUNTRY", lang);
String c=getCountry( "0119", lang);
String e=getError( "DB_ERROR", lang);
Each of the four methods
invoked above will append an appropriate prefix to the internal string name
and retrieve its translation from the instance of Properties vocabulary which
corresponds to English language code. This approach allows clean and orderly
control of application's multi-lingual behavior. Furthermore, even in case of
single-language applications, fine tuning is easier since strings displayed
in browsers are not hard-coded, thus they are accessible for quick modification
and customization in property files.
The property files may be
stored in and retrieved from the file system. This approach allows customers,
i.e., system administrators of the production site, to edit them and fine-tune
appearance of strings in multiple languages. The other approach is to put property
files in the application's class hierarchy and pack the entire class hierarchy
in a JAR file. Instances of Properties are then loaded as application's resources.
In such a way, all application's classes and property files can be delivered
as a single JAR file that simplifies delivery and installation of the application.
In case of multi-lingual applets, this is the preferred way to deliver applets
to the user's browser.
Conclusions
In
this article we have described the author's experience with the distributed
development of multi-lingual three-tier Java/ CORBA/database applications. The
challenge was to develop applications at a remote development site in a purely
telecommuting fashion, i.e., without any physical access to the production site,
and in some cases without all software and hardware components needed to replicate
the production system at the development site. We believe that tips and tricks
of trade described in this article could be of great use to other software developers.
About
the Author
Dr.
Dragomir D. Dimitrijevic (http://solair.eunet.yu/~ddimitri)
received BS and MS degrees in EE from the School of Electrical Engineering,
University of Belgrade, and a Ph.D. in CS from Polytechnic
University, Brooklyn, NY. His extensive experience in software development
includes working for a number of research and/or development companies/universities
in the US and Yugoslavia. He developed various types of software ranging from
low-level assembly language software to high level applications on the Internet.
Currently, he works as an independent consultant. Among other things, he has
developed the first Yugoslav system for real-time processing of Internet payments
and the first e-commerce applications in Yugoslavia.
The
author can be contacted through
E-mail: ddimitri@Eunet.yu
www: http://solair.eunet.yu/~ddimitri