Web publishing using PL/SQL and Java

advertisement
WEB PUBLISHING USING PL/SQL AND JAVA
Eric Grancher, Eric.Grancher@cern.ch
CERN (European Organization for Nuclear Research),
http://www.cern.ch/, Switzerland
1. Summary
At CERN, as increasingly elsewhere, server based applications using the PL/SQL cartridge and Java are
preferred as they make minimum demands on the client and ease maintenance. The PL/SQL cartridge, the
original method offered by Oracle, has proved reliable and effective. We have used it to build web
applications for more than four years. Newer applications are using Servlets together with the application
server. This paper presents the different techniques that we designed and the pitfalls that we encountered
in diverse projects such as a technology transfer database, a product management tool and a system to
keep track of physics events. Important considerations are security, ease of maintenance, transaction
handling and modularity. Most of the experience has been gained using the PL/SQL cartridge and this
will be contrasted and compared with the newer Java techniques…
2. Introduction
The Oracle Application Server PL/SQL cartridge is one of the techniques provided by Oracle to publish
database-oriented content on the Web. It is based on PL/SQL, Oracle’s proprietary procedural language.
First versions have been released in 1995 and it has since had a lot of success.
A few years ago, Sun Microsystems introduced Java as a language with the following main
characteristics: object orientation, no pointer arithmetic, and compilation into a machine independent
bytecode that is executed in a virtual machine. The Java Servlet technology is a standard Java Application
Programming Interface defined by Sun for creating dynamic content and for extending the functionality
of a web server.
In this paper, we will describe the foundations of these two techniques and compare some of the key
features for dynamic content oriented sites: security, transaction mechanism and manageability. We will
also present some various features only available in the Servlet technology and give some advice,
including presentation of some tools.
This paper is by no mean a guide to PL/SQL nor to Java/JDBC/Servlet programming, many sites and
books are available for this purpose: for the PL/SQL cartridge, I would especially recommend PL/SQL
programming (Steven Feuerstein, 1995)1; for Servlet programming, I would advise Professional Java
Server Programming (Danny Ayers and al, 1999)2.
2.1. How the PL/SQL cartridge works
The PL/SQL cartridge has been the building block for the Oracle Application Server, it was the only
“cartridge” in the Oracle Web Server version 2, which has evolved in Oracle Web Application Server
version 3 and that we finally know as Oracle Application Server version 4. The main idea with the
PL/SQL cartridge is that the request is mapped into a connection to a database where a procedure is
called, the output of the procedure is returned to the navigator. The key component in the PL/SQL
cartridge is the Database Access Descriptor, which is the reference of the Oracle account to be called. In
the OAS configuration, a virtual path is mapped to a DAD. Default is that a commit operation is issued
after the successful execution of the procedure.
The PL/SQL Web toolkit is made of a set of packages which provide procedures and functions to
generate most of the HTML tags. For example htp.headOpen would generate <HEAD> and
htp.title(‘Hello’) would generate <TITLE> Hello </TITLE>. All of these procedures
write into a PL/SQL table that is transferred to the client at the end of the call.
The following is a simple example of a package with a procedure that multiplies the salaries of the
employees in the EMP table and then lists the employee identifiers, names and salaries.
Eric Grancher, CERN
Web Publishing using PL/SQL and Java, EOUG 2000
2/13
PACKAGE basic IS
PROCEDURE update_and_display(p_factor_num IN NUMBER DEFAULT 1);
-- default is to not change the salaries
END basic;
PACKAGE BODY basic IS
CURSOR cur_emp IS select empno,ename,sal from emp;
PROCEDURE update_and_display(p_factor_num IN NUMBER DEFAULT 1) IS
BEGIN
htp.htmlOpen;
-- typical HTML element
htp.headOpen;
htp.title('Employees');
htp.headClose;
htp.bodyOpen;
UPDATE emp SET sal=p_factor_num*sal;
-- multiply the salaries
FOR emp_rec IN cur_emp LOOP
-- loop on the cursor
htp.print('['||emp_rec.empno||']'||emp_rec.ename||'=>'||emp_rec.sal);
htp.br;
END LOOP;
htp.bodyClose;
htp.htmlOpen;
EXCEPTION
-- catch exception and
WHEN OTHERS THEN
-- and return an error page
rollback;
htp.print('Err update_and_display, '||p_factor_num);
htp.bodyClose;
htp.htmlClose;
END update_and_display;
END basic;
A call to http://host:port/basic.update_and_display?p_factor_num=1.1 would raise the salaries by 10%
and lists the employees with their salaries.
2.2. How the Servlet cartridge works
The main idea with the Servlet API is to extend the web server so that a request, once identified to be a
call to a Servlet application, is transformed into the execution of a Java class, which writes the data to be
returned to the browser into a stream. The HttpServlet class has several methods that can be
overridden: init which is called when the Servlet is started, destroy which is called to stop the
Servlet (these two methods can be used to initialize and free objects which are time consuming to work
with); the doGet and doPost functions handle the calls from the HTTP GET and POST, the
service method is a “catchall” method that will be invoked for both GET and POST calls. Here is a
simple example that just returns a fixed reply to the requests.
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class BasicServlet extends HttpServlet {
// implement the Servlet class
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
// set the content as web page
PrintWriter out = new PrintWriter (response.getOutputStream());
// get a writer stream
out.println("<html>");
// directly write onto the stream
out.println("<head><title>Title</title></head>");
out.println("<body>some text in the body");
out.println("</body></html>");
out.flush();
// flush the ouput to the browser
}
}
In addition to the Java2 Enterprise Edition platform facilities, Oracle provides a toolkit similar to the
one used for years with PL/SQL: the idea is to have a set of classes that will generate HTML tags. The
good point with this package is that one can hope that a simple upgrade and a recompilation would make
your application compliant with the next version of HTML (current toolkit is HTML 3.2 compliant). Here
is a simple example that uses the oracle.html classes and produces a page with a simple fixed
content; note that this page is HTML 3.2 compliant (as you can check for example using
Eric Grancher, CERN
Web Publishing using PL/SQL and Java, EOUG 2000
3/13
http://validator.w3.org/), whereas our two previous examples are not fully compliant, as they would need
a DOCTYPE that is produced by default with the Oracle classes. These oracle.html classes also help
performance, as explained later.
import
import
import
import
javax.servlet.*;
javax.servlet.http.*;
java.io.*;
oracle.html.*;
public class BasicOracle extends HttpServlet {
// implement the Servlet class
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
ServletOutputStream out_str = response.getOutputStream();
// retrieve an output stream
out_str.println("Content-type: text/html");
// indicate the MIME type
out_str.println();
HtmlHead head = new HtmlHead("Title !");
// generation of an HTML tag
HtmlBody body = new HtmlBody();
HtmlPage page = new HtmlPage(head, body);
// page is the head plus the body
body.addItem(new SimpleItem("Some body text")); // add items to the body
page.print(out_str);
out_str.flush();
}
// print the page
// flush output to the browser
}
2.3. Similarities and differences
These two techniques look very similar on first approach: they both produce data when being called
from HTTP and are both handled as cartridges in the OAS. We’ll see how different they are, in the way
they handle transactions and sessions, generate non-HTML data, how well they scale…
3. Beyond HTML documents
Today different types of information can be moved across the Internet or the Intranet via the HTTP
protocol which is everywhere. There are several reasons for this, the first is for sure the interoperability:
HTTP is seen as the protocol that can handle communication in LAN or WAN and all of the software
components are increasingly supporting it. Another reason is that HTTP protocol, albeit very simple, can
handle complex features if necessary such as connection persistence. It can support textual or binary data.
3.1. Non-HTML text
HTTP is mainly used for HTML files, but increasingly, it is also the common protocol to exchange
other types of documents such as XML. Thanks to the MIME idea, it can be used in a very wide field
where text is enough to describe the data such as simple charts based on resizing small images or Coma
Separated Value files to be read with an Office suite.
3.2. Non-text
It also happens that one needs to send binary information across WAN such as images, sounds, videos,
compressed files, etc. This has been possible as of Oracle Web Application Server version 3 thanks to the
cartridge extensibility framework, but it is almost impossible with the PL/SQL cartridge as it is
unpractical to handle binary data due to PL/SQL limitations. With Servlets, it is very easy, as we just need
to change the way we retrieve the writer to obtain a binary-capable one and then to use the large number
of available libraries to produce the binary data to be transmitted.
For example, to send a simple image with a few words as a GIF, one can extend the following piece of
code. It makes use of a GifEncoder, a class from ACME Laboratories 3. Note that these image
manipulations are usually built with AWT (Abstract Window Toolkit), which currently needs access to a
graphical display to work; it may be a problem for the Unix type servers.
Eric Grancher, CERN
Web Publishing using PL/SQL and Java, EOUG 2000
res.setContentType("image/gif");
ServletOutputStream out = res.getOutputStream();
Frame frame = new Frame();
Image image = frame.createImage(400, 60);
Graphics g = image.getGraphics();
g.setFont(new Font("Serif", Font.ITALIC, 48));
g.drawString("Hello world!", 10, 50);
new GifEncoder(image, out).encode();
4/13
// set MIME as GIF
// binary stream
// create an image
// draw a string using AWT
// encode the image
// and send it to the stream
One can also use all of the TCP based features of Java to do what was difficult to achieve with PL/SQL.
Sending mails (using for example JavaMail), accessing HTTP URLs (for example to retrieve some XSL
file -Extensible Stylesheet Language, a way to transform XML documents-), JNDI services (-Java
Naming and Directory Interface-, a common interface to various directories like LDAP -Lightweight
Directory Access Protocol- or NDS -Netware Directory Service-), FTP (File Transfer Protocol) can be
made with Java. One can even use the futurist JINI (connection technology to let devices register on the
network and talk with one another) techniques.
3.3. JavaServer Pages
JavaServer Pages (sometimes called JSP which should not be confused with Java Stored Procedure,
another currently very active topic) is a way to combine markup language (HTML or XML) with pieces
of Java code to produce web pages. Each page is automatically compiled as a Servlet by the JavaServer
Page engine the first time it is requested and then executed as a Servlet until it changes. The logic part of
the page can be written as a call to a Java Bean or be in scriptlets, a block of code between <% and %>
tags. Follows a simple example that just includes the date via a scriptlet.
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> A simple JSP </TITLE>
</HEAD>
<BODY>
<H3> Welcome! </H3>
<P><B> Today is
<%= new java.util.Date() %>
</B></P>
</BODY>
</HTML>
<! to be HTML 4.0 compliant >
<! standard tags >
<! Java scriptlet >
In essence, one can see that JSP code, in the end, is no more than a Java Servlet and thus one cannot do
more or better than with direct Servlet programming. JSP is a very handy way to avoid long and errorprone Java programming and to concentrate on the logic (that we advise to implement as Java Beans) and
on the presentation, letting the JavaServer Page engine glue both of them with automatic generation of
Java code.
4. Security
The security features are some of the most important requirements for web applications as soon as
confidential data are made available on the web. Access control is also a necessity as soon as data
modification is allowed through the web. In this chapter, I will describe the functionalities offered by
OAS and the PL/SQL cartridge.
4.1. Confidentiality
In the OAS, all of the requests come from the listener; the various listeners that can be plugged in OAS
(namely Spyglass, the default one, but also Apache and IIS) support Secure Socket Layer. As this
encryption mechanism is done at the listener level, it is completely independent from the cartridges that
will then process the requests and thus is the same for both PL/SQL and the Servlet cartridges.
To me, an important feature is missing in the Oracle Application Server releases that we have available
for production (up to 4.0.8.1): the ability to restrict an application (in the OAS sense) to a specific port. It
would be very handy and secure to be able to define a SSL encrypted listener and to indicate that requests
to a sensitive application have to go through the SSL port -currently requests may come to the
Eric Grancher, CERN
Web Publishing using PL/SQL and Java, EOUG 2000
5/13
applications via any of the listener’s ports-. We have read that such an enhancement has been made in
4.0.9.
4.2. OAS access control model
The basic access control model is common to all cartridges: the requests are passed from the listener to
the dispatcher; there the authorization broker handles the security on a URL pattern-matching basis. For
example, if you define that /shop/plsql/private* has to be protected from a set of users, the
incoming requests will be compared to the pattern and the user prompted for a login / password if
necessary.
4.2.1. Source of users
Up to version 4.0.8.1, users had to be defined in the Web Request Broker configuration file; they were
defined as Users, Groups (made of Users) and Realms (made of Groups).
[Basic]
Realm.Admin Server =
Group.Administrators
User.admin
=
[AppProt]
/shop/owa/
=
Administrators
= admin
1d0258c2440a8d19e716292b231e3190
;
;
;
;
;
static users section
realm definition
group definition
user definition
protection section
Basic(Admin Server)
With 4.0.8.1, one can use a LDAP (Lightweight Directory Access Protocol) server, as the source of the
users to define a Realm, the LDAP server can be an Oracle Internet Directory, but may also be another
corporate LDAP server. As described in OAS Security Guide (Oracle Corp, 1999)4, such Access Control
Lists may be used and allow much more flexibility than the previously described fixed set of users. This
also avoids having to reload the configuration file at each change. The following example would define a
Realm for users who are in the finance or marketing groups in myCompany in the US.
(group=ou=finance,o=myCompany,c=US) | (group=ou=marketing,o=myCompany, c=US)
4.2.2. Order of security hints
The order in which security hints are defined is important: later defined security hints take precedence
of previously defined ones. In the following example, even if access is written to be restricted to a Realm
with the Shop Administrators, later defined protection hint relaxes this restriction for public* matching
calls.
/shop/plsql/* = Basic(Shop_Admin) ; protect everything
/shop/plsql/public_* = IP(all_ip) ; release protection for public*
4.3. PL/SQL specificities
4.3.1. Special schemes
For historical reasons and linked to the way it works (it directly connects to the database), the PL/SQL
cartridge offers two security features in addition to the OAS standard ones: the custom and the Oracle
server based. The custom authorization scheme is based on a user-defined function to authorize or not
access to a specific URL. The Oracle server based authorization is based on the Oracle logins: instead of
connecting with a pair (login/password) to the Oracle server and then executing the requested procedure,
it first asks for an oracle account’s login and password.
4.3.2. Pitfall
The common security pitfall that I have seen in projects using the PL/SQL cartridge is due to the fact
that PL/SQL procedure names are case insensitive and thus a protection on
/shop/plsql/private_delete
would
not
prevent
a
user
from
accessing
/shop/plsql/PriVate_DeLeTe. To workaround this problem, I suggest to protect applications at
the root level and then unprotect (indicating, for example, a restriction to all IP addresses) the public parts
of the application.
5. Transaction handling
5.1. Introduction
The web as handled by the HTTP protocol is basically stateless, a request for a web page does not make
reference to the previous one and a connection to the web server is created for each request (the
Eric Grancher, CERN
Web Publishing using PL/SQL and Java, EOUG 2000
6/13
connection can be kept with HTTP 1.1, but it does not change the underlying stateless mechanism). This
has been one of the biggest problems to solve when creating a web application (or porting to the web an
older application) for which the concepts of locking, transaction and session context are important. We
have used these concepts with Graphical User Interface tools for years (Oracle Forms automatically puts a
lock on a record when you start to edit it). But how is it possible to do the same on the web? We are now
all used to the shopping basket that we can see in the electronic commerce applications. In order to build
such applications, we need to tackle these different issues.
We will look at a few of the facilities offered by the PL/SQL cartridge: cookies, optimistic locking and
transaction handling. We will then compare them with the new facilities provided with the Servlet
technology: session tracking, session and application contexts and how to handle transactions in this
environment.
5.2. Session management
We are talking in this paragraph of web sessions and not Oracle sessions, the purpose is to be able to
track a user across his or her different operations on the site and to maintain a context for the different
operations.
As the PL/SQL cartridge is strictly stateless (i.e. no information is kept on the server side for the
application between the different requests), it is impossible to follow the user apart from sending him the
necessary information and to retrieve it later on. We will have a quick look at these methods: cookies and
hidden fields.
As the Servlet system is based on Java classes that keep running across the requests, it is possible to
keep track on the server side of the sessions and variables associated with them. We will have a look at
how these facilities are supported in the Java Servlet API.
5.2.1. Hidden fields
The simplest but very limited way to transmit information across requests is to hide fields in the HTML
form and then use the fact that the values placed in this field will be transmitted to the next call (they can,
if necessary be placed in a hidden field and thus again transmitted, etc.).
This mechanism, albeit available with all CGI techniques, is very limited and prone to errors; for
example, if one wants to build a list of items to buy, the final action would need to analyze the values
passed and concatenate the list of items.
Another drawback of such a method is that it is non-persistent: if a user visits another site and goes
back to the shopping site previously mentioned, the shopping basket list will be lost, this is in clear
contradiction with the web idea where users are not captive to one application like in the GUI model. It
shows that this method can only be used to transmit information between simple actions.
5.2.2. Cookies
A more sophisticated method that solves the previously mentioned problem is based on a technique
called cookies; the main idea is to transmit to the browser information that can later be queried by the
application. It is the basis of almost every Internet application that we currently use. The PL/SQL
cartridge can handle cookies in an easy way thanks to the OWA_COOKIE package. The storage and
handling of information has to be handled in a programmatic way.
5.2.3. Servlet only features
The Servlet API introduces new features to simplify the development of web application as most of the
code previously needed to implement much of the functionality has been transferred to the Servlet
implementation itself.
5.2.3.1. Session tracking
Session tracking is difficult to handle: creation, expiration, transmission of object are difficult problems
to solve in the CGI and PL/SQL environments. The Servlet API comes with a facility to retrieve (or
create for the first access) a session that will then be tracked across the connections. This session can then
be used to attach information. Sessions are implemented using cookies when the navigator supports them.
In the following example, we just attach an integer to the session, retrieve and increment it at each
connection, the value being specific to the client (the client is the navigator running on a specific machine
for a user).
Eric Grancher, CERN
Web Publishing using PL/SQL and Java, EOUG 2000
7/13
HttpSession session = request.getSession(true);
// get session reference
Integer ItemCount = (Integer) session.getValue("itemcount");
// retrieve the value from session’s context
if (ItemCount == null) {ItemCount=new Integer(0);}
else {ItemCount = new Integer(ItemCount.intValue()+1);}
session.putValue("itemcount",ItemCount);
// put value in session’s context
5.2.3.2. Application context
Application context is a feature that allows applications to share data across all of the clients connected
to the application. This is impossible to implement with normal CGI or PL/SQL applications without
using an external storage mechanism (like a database or a file, but the application then needs to manage
and clean up these temporary data, which is not an easy task).
By referring to the Servlet context, one can retrieve attributes and then work with these references
(retrieve information, but also modify it).
This kind of mechanism is available with other techniques like mod_perl but while it is very errorprone with mod_perl, see mod_perl Coding Guidelines (Stas Bekman, 2000)5, the context mechanism is
very safe in the Java API; one still needs to remember that these data may be modified by several threads
so synchronization has to be implemented.
T ItemCount = (T) getServletContext().getAttribute("itemcount");
// get reference from the session
if (ItemCount==null) {
getServletContext().setAttribute("itemcount",new T(0));
}
else {
ItemCount.increment();
// operate on the reference
}
5.3. Transaction and Locking
All of the interactive web applications are going to manipulate and not only query information. This is
especially true for the database applications. Two common problems have to be faced when changing the
data: the first one is locking, one needs to avoid other people changing the same data at the same time, the
second one is transactions so that several changes can be done in an atomic way, all or nothing.
Although these two features are implemented in the Oracle RDBMS, the stateless web interface causes
us to loose the gain of the database management system features as the connection is not kept from the
client (browser) to the database. One also has to take into account that GUI clients are more or less
captive and have to cleanly exit the application at some stage whereas web clients have the possibility to
go and look at another site and may never come back.
5.3.1. PL/SQL owa_opt_lock
The owa_opt_lock package can help the programmer by checking that no other user has updated
the record he was also modifying. It works with the already mentioned hidden fields technique and a
checksum. Although it is not hundred percent sure (a checksum is just a hash function and thus may be
the same for different values), it is a very simple way of providing basic check to prevent two persons
from modifying the same data.
5.3.2. PL/SQL real transaction
For the PL/SQL cartridge, it is possible to enable “real” transactions, a transaction being a collection of
operations that exist as a unit. The transaction service begins, commits, rollbacks, and keeps track of
operations that are within the scope of the transaction. These transactions are maintained in a declarative
way: one needs to define in the configuration that the transaction will begin, commit and rollback with a
set of predefined URLs and also to indicate (with the help of wildcards) the scope of the transaction.
Oracle Application Server contains a Transaction Service and one can configure a PL/SQL cartridge to
use it, in which case the automatic commit (in case of success) or rollback (for any failure) is not issued at
the end of the call to the procedure; the transaction is kept by the application server. Before using this
technology, one has to check that no code has been written with auto commit in mind and that neither
commit nor rollback is done explicitly in the code. One can even use this to do real locking on the web,
just issuing some SELECT … FOR UPDATE NOWAIT, trapping the exceptions which will indicate that
another client has already locked the entry.
Eric Grancher, CERN
Web Publishing using PL/SQL and Java, EOUG 2000
8/13
This technology resolves big problems that would have had to be solved programmatically otherwise.
But the impossibility to join a transaction (for example in the case where the “begin transaction” has not
been called and thus the transaction is not initiated) has to be programmatically managed and there is no
documentation on how to do it with the current API.
5.3.3. JDBC/JTS
Java DataBase Connectivity is the way to access databases from Servlets; Oracle JDBC drivers provide
extended facilities like LOB access, batch loads, and calls to PL/SQL stored objects. One of these
extended functionalities is the compliance with the Java Transaction Service. It uses the same transaction
service as the PL/SQL cartridge but in a programmatic way.
With the JTS API, one needs to connect to the resource manager, and then to connect to the database
using a special JDBC driver, to do some operations on the connection (being direct JDBC calls or calls to
PL/SQL stored units) and finally to commit on the resource manager.
The advantage over the PL/SQL access to the transaction service is that it is a programmatic approach
and thus allows easy catching of problems linked with the resource manager transaction.
6. Manageability
When it comes to developing and maintaining large applications, the amount of effort dedicated to plan
and document how the application will grow is essential. Some techniques can be used to help the teams
in this work: N-accounts architecture, API based interfaces, packaging and coding convention. These
techniques can be implemented in different ways depending on the choices made for the language and the
architecture.
6.1. Packages
In large applications with tens or hundreds of different actions, it is very important to define a hierarchy
of sub-programs which can be developed by different persons or teams. Both PL/SQL and Java provide
ways to define packages: in Java, they are simply the classes themselves, in PL/SQL, they are defined as
packages; one can have both public and private methods in Java and with PL/SQL.
To call these packages with the PL/SQL cartridge, one has no choice but to call them in the URL. A
fully dynamic alias mechanism could be implemented using the “dynamic SQL” facilities (DBMS_SQL in
Oracle7 and execute immediate in Oracle8i), but this would slow down the processing of the
requests and reduce the benefits of dependencies.
With the Servlet system, the idea suggested in Developing Scalable, Reliable, Business Applications
with Servlets (Oz Lubling and Leonardo Malave, 1999)6 is to call a main Servlet and pass an argument to
it that will help to redirect the call to another class. This mechanism can be used to alias and cache the
complexity of the design into simple names of modules. The concept is to have a main entry point that
will then dynamically instantiate the requested module and pass to it the different arguments
(authentication, values given by the user in a form, request and response). URLs have to be sent in a form
like http://host:port/servlet/MyServlet?module=mymodule&.... The main Servlet has to implement the
doGet and doPost methods, all of the modules have to inherit from the same class (called mModule
in the example) which has a method to receive the arguments and another to process and create the
output. Here is a skeleton of the technique.
mModule mm = null;
try {
// declare an object to host
Class c = Class.forName( "mypackage."
+ (String)appModules.get(module) );
mm = (mModule) c.newInstance();
// instantiate an object of the requested module
} catch (IllegalArgumentException iaex) {
printError(res, "Module not found");
return;
}
mm.setParams(request, response, user_id, database_connection, log_file);
// pass request parameters to the appropriate module
mm.process();
// and run the request
Eric Grancher, CERN
Web Publishing using PL/SQL and Java, EOUG 2000
9/13
6.2. Coding conventions
Coding convention is the key point to help maintenance of the code; indeed clear and well-observed
coding conventions will ease the understanding of the program for a newcomer to the code, during the
development process or in the evolution of the code several years later.
Coding convention may include how to structure different actions made by the program; the way
comments are placed (with some automatic extraction of comments, like Javadoc), how arguments are
passed, how errors are handled (exception mechanism, error codes) and even how the code is written
(indentation, choice of the variable names…).
For Java, Sun is providing some coding conventions as described in Code Conventions for the JavaTM
Programming Language (Sun Microsystems, 1999)7.
For PL/SQL, I am not aware of a well-defined coding convention that is authoritative in the PL/SQL
developer community. In Developer’s Guide: PL/SQL and ODBC Applications (Oracle Corp, 1999) 8, the
conventions for parameter names in the PL/SQL toolkit are briefly described. One can also find very
useful tips to define a coding convention in Oracle PL/SQL Tips and Techniques (Joseph C. Trezzo,
1999)9.
6.3. N-accounts architecture
Within the database, several schemas can be used to help developers define APIs: a schema can be used
for each abstraction. As an example, one schema may contain the tables, another the views which will be
used on top of these tables (accessing the tables always using the same SQL statements would help to
keep a clean statement cache and thus speed up the application), a third schema would contain the
business logic, a fourth one the presentation layer. For the PL/SQL cartridge, I would also recommend to
add another layer to only present the interface callable from the web.
6.4. N-tier architecture
The well-known N-tier architecture may also help to create a more maintainable application. Using the
best appropriate programming languages and tiers does not only improve performance, but also helps to
split the parts that can be separated and eases the maintenance.
With the PL/SQL cartridge, we have very little control over the way calls are made: the browser usually
directly calls the application server, which –after access control– automatically connects to the database
(in the simplest case). Even in a simple schema like the PL/SQL one, one can split the presentation and
documentation levels by using different techniques like having as static pages all of the information that
is not related to the database or having the PL/SQL cartridge to produce XML code and then use XSL to
generate HTML from the XML (note that it requires an XML aware browser like Internet Explorer 5 to
use such a facility). In a system to manage the results of the Aleph experiment, see
http://alephwww.cern.ch/scanbook/scanbook.html, the PL/SQL cartridge has been used to produce nonHTML results that are transmitted to a Java application (or an applet) which handles the user interface.
As Servlets generate any text just like PL/SQL cartridge does, the methods mentioned before can be
used. But Java also enables more complex architectures; for example, Enterprise Java Beans (a technique
based on Remote Method Invocation part of the Java2 Enterprise Edition platform) can be used to
implement the business logic while having the presentation layer based on Servlets.
Oracle is providing Business Component for Java (BC4J) to simplify building reusable server-side
modules with JDeveloper 3.0; Building Java applications for the Oracle Internet platform with Oracle
JDeveloper (Oracle Corporation, 1999)10 is a good introduction to this technique. This tool allows rapid
development of database oriented business logic modules which can then be deployed as Enterprise Java
Beans or CORBA distributed objects.
6.5. PL/SQL dependencies
In the Oracle world, PL/SQL has been used for years as the procedural language as it has been available
since version 6 of the RDBMS and is well integrated with the other schema objects. Indeed, the
mechanism of dependencies (check USER_DEPENDENCIES) keeps tracks of how the different objects
depend on others. This is very useful for the developers during the development phase to check if the
dependency diagrams are observed, but it is even more useful in the maintenance phase to find out why a
program stops working.
Eric Grancher, CERN
Web Publishing using PL/SQL and Java, EOUG 2000
10/13
If the structure of an object is changed (column added, modified, dropped –in Oracle8i– on a table,
view changed, source changed for a procedure, a function or a package header), the objects that depend
on it will be automatically marked as invalid and will then need a recompilation to be again stated as
valid. It means that mainly if the dependencies are satisfied, all of the requested objects will be found
during the processing. This functionality will, in an ideal world, help to have the application fully
functional or not functional at all (but unresolved dependencies are easily visible, all objects should be in
valid state).
This is a very interesting functionality of PL/SQL, especially when making programs available to a
large community which has no idea about the internals of the application. The web is a place where you
would rather have your application either completely broken or fully functional. It helped us a lot for
various projects to find out that an object (typically a table) had been changed and that the code had to be
adapted.
A point to mention about the PL/SQL dependencies and the PL/SQL cartridge is that most of the Oracle
tools try to re-compile an object when it is invalid whereas the PL/SQL cartridge will only fail to execute
an invalid procedure or package. It means, for example, that when upgrading or applying an RDBMS
patch, one has to carefully execute a script that will recompile all of the objects in the RDBMS (or at least
the ones called by the PL/SQL cartridge). Oracle provides such facilities in the DBMS_UTILITY
package, but we have seen sub-optimal behaviour of this package and thus have developed a script that
does this job.
6.6. Tools
Availability of tools has an impact on the choice of one or another technology and is essential to the
success of a project. Several types of tools can be seen as important for a technology: syntax highlighting,
debugger, impact analysis study, version management, migration assistants, automatic generation
wizards, and associated case tools…
PL/SQL has always been a language with very few tools to help developing and debugging. PL/SQL
dependencies help developers to have an idea of the impact of the changes they make on tables or stored
objects. Tools are now coming with several debuggers; browsing tools, high end Integrated Development
Environments. Development of non-windows based tools is on going, some of them being in the Open
Source movement. Oracle has published the non-supported WebAlchemy tool that helps to migrate static
web pages to PL/SQL stored units. Unfortunately the Oracle tool to help debugging PL/SQL cartridge
application, see http://www.olab.com/, is no longer accessible.
For Java, lots of tools are available and many of them include support for Servlets. Oracle is providing
JDeveloper that has some database-oriented features, it includes a local Servlet server that can be used in
the debugging environment.
7. Performance
Sooner or later, one has to cope with the performance problem. Some projects target performance in the
early phases and make choices accordingly. Other, often smaller, projects look at tuning when userwaiting times become unacceptable.
7.1. Database design and SQL
Servlet and PL/SQL cartridge performance problems often come from the lower layer, namely bad
database design and poorly written SQL. Most of the problems I had to work on were related to database
links, dynamic SQL, missing indexes or programmatic operations that can be done from SQL and thus
avoid data transfers, see Oracle Performance Tuning (Richard J. Niemic, 1999)11.
A special point has to be checked with Java: as there is no question of static versus dynamic SQL with
JDBC database access, programmers should maximize the use of prepared statements to avoid polluting
the statement cache. I have experienced that a very good way of handling database processing in Java is
to do it in PL/SQL inside the database and then return the data to Java that will take care of the
presentation part. A one hundred percent Java based solution could be made from Java stored procedures
to handle the data processing and a Servlet for the presentation. Although feasible, I would still think that
PL/SQL is more mature and efficient for heavy database access, see Java or PL/SQL? (Guildo Schmutz,
2000)12 for a study on server-side Java transfer versus PL/SQL.
Eric Grancher, CERN
Web Publishing using PL/SQL and Java, EOUG 2000
11/13
7.2. Initialization, connection pool and threading model
With Servlets, one can declare class member objects and initialize them in the init procedure
including opening database connections and taking care of a pool of database connections. All of this
logic is implemented in the application server for the PL/SQL cartridge. If an application is using
Enterprise Java Beans, stateless beans will improve performance as they will be easily pooled and reused.
The choice of threading model is an option offered by the Servlet implementation on Oracle
Application Server: one can choose to implement or not the SingleThreadModel interface. The
difference is that threads in single threaded model Servlets will be one to one mapped with instances of
the Servlet; whereas, if not implementing the single threaded model, one instance will be created for each
cartridge server process and several threads assigned to the same instance of the Servlet.
For the Servlet cartridge, the Oracle classes (oracle.html) may help to avoid managing
StringBuffer for performance reasons that are explained in StringBuffer versus String (Reggie
Hutcherson, 2000)13 and in the OAS 4.0.8.1 release notes; at the same time, it may also help to follow
HTML version specifications.
8. PL/SQL versus Servlet
As there is a great chance that you are more familiar with PL/SQL than with Java and Servlets, this
might introduce a bias. Now is the time to summarize the advantages of both technologies and to show
how to mix them to interact in the best way with your Oracle data from the web.
8.1. PL/SQL pros
PL/SQL has been the procedural language for Oracle databases for years and is specifically targeted at
interacting in a fast and reliable way. Here are, in short, the pluses from PL/SQL over Java and from
PL/SQL cartridge over Servlet.
8.1.1. Simpler
Servlet programming is much more complex than with the PL/SQL cartridge; in particular, PL/SQL is
much better integrated with the Oracle database than Java binding (JDBC): just figure out the number of
lines to open a cursor and loop around it with both technologies, including exception handling.
Database connection is the basis for the PL/SQL cartridge as code gets executed in the database,
whereas the programmer has to take care of database connection in the Java Servlet model. For example,
even if the connection has been opened in the init procedure, one always needs to check (trapping
SQLException) that the connection is still valid and working, reopening it if necessary.
8.1.2. Easily maintainable
PL/SQL dependencies are, I think, a very valuable asset for PL/SQL. They assist development as the
compilation checks for the availability and the format of the other stored objects (tables, views or other
PL/SQL programs). They also facilitate finding if a program might stop working with a change and, if a
change breaks an application, to find out why. Of course, part of a Java based application may continue to
work when another part is broken, but for interactive applications like web ones, it is usually better to
have the whole application broken rather than having it behave in some unpredictable way.
PL/SQL code is more compact than its Java equivalent, as all of the underlying web logic is handled by
the application server whereas much more has to be done programmatically with the Servlet. For example
in handling transactions, even taking into account that extended functionalities are only available with the
programmatic Java/JTS binding, it is much simpler to realize a transactional PL/SQL cartridge based
application than the Servlet equivalent.
8.2. Servlet pros
Java2 Enterprise Edition is a major release of the Java API, and it includes technologies specially
created for Servlet applications. Here are in short the gains of this new release that the whole computing
industry embraces today, Oracle being one of the most fervent supporters.
8.2.1. More extendable
After reading this article I hope that you are convinced, if you were not before, that Java and Servlets
are highly extendable and powerful techniques. We have seen that it allows things that cannot be done
Eric Grancher, CERN
Web Publishing using PL/SQL and Java, EOUG 2000
12/13
with the PL/SQL cartridge such as returning a dynamically created image, a compressed file, sending email, connecting to a corporate LDAP server, spawning tasks across the network… there is almost no
limit to such a list: Java opens areas that were not reachable from conventional database programming
applications (or only in tricky ways).
8.2.2. Session and context variables
Another asset of Servlet technology is, to me, the simplicity with which one can manage session and
context variables where it is complex and even impossible in some cases with the PL/SQL cartridge.
Tracking web sessions with such facility is a major evolution in web programming.
Eric Grancher, CERN
Web Publishing using PL/SQL and Java, EOUG 2000
13/13
9. Conclusion: the best of both worlds
Some of the PL/SQL pros should also profit Servlets with a later release of Oracle8i as it will integrate
a Servlet server. This would add some of the advantages of the PL/SQL cartridge (like an easy
management of stored modules and an already authenticated connection) to the facilities and the
extensibility of the Java/Servlet solution. Some questions remain on the architectural point. Will it be fast
and scalable enough to run direct user interaction and Servlet on the database side, breaking the idea of Ntier architecture? Will you open direct access to your database host through the firewall?
Communication between Java and PL/SQL in both directions is possible. It can be used to build and
choose the most appropriate building blocks for new projects. One needs to be very careful as the internal
complexity and difficulty of tuning increase when mixing several methods. It also means that developers
have to be familiar with both technologies. One can easily use the advanced features of Servlet, and
access the data via an API in PL/SQL: it provides the dependencies system and the advanced
functionalities of Servlets to track sessions, handle application context or return various types of data. The
other solution being to keep web access through the PL/SQL cartridge and publish Java Stored Procedure
in SQL so that they can be used to extend PL/SQL.
Servlets and JavaServer Pages open new fields for web applications related to databases and it is still
evolving quickly. In this transition phase, Java and PL/SQL may coexist and complement each other for
the development of new web projects.
BIBLIOGRAPHY
1
Oracle PL/SQL Programming by Steven Feuerstein, 1995, O’Reilly and Associates,
ISBN 1-56592-142-9
2
Professional Java Server Programming by Danny Ayers and al, 1999, Wrox Press,
ISBN 1-861002-77-7
3
GifEncoder, ACME Laboratories http://www.acme.com/java/software/
4
Oracle Application Server 4.0.8.1 Security Guide by Oracle Corporation, 1999
5
mod_perl Coding Guidelines by Stas Bekman, 2000,
http://www.perlmonth.com/columns/perl_apache/perl_apache.html?issue=10
6
Developing Scalable, Reliable, Business Applications with Servlets by Oz Lubling and Leonardo
Malave, http://developer.java.sun.com/developer/technicalArticles/Servlets/Razor/index.html
7
Code Conventions for the JavaTM Programming Language by Sun Microsystems, 1999,
http://java.sun.com/docs/codeconv/index.html
8
Oracle Application Server 4.0.8.1 Developer’s Guide: PL/SQL and ODBC Applications
by Oracle Corporation, 1999
9
Oracle PL/SQL Tips and Techniques by Joseph C. Trezzo, 1999, Osborne McGraw-Hill;
ISBN 0-07882-438-9
10
Building java applications for the Oracle internet platform with Oracle JDeveloper, an Oracle white
paper, 1999, http://technet.oracle.com/products/jdev/htdocs/jds_oip.htm
11
Oracle Performance Tuning, by Richard J. Niemic, 1999, Oracle Press, ISBN: 0-07-882434-6
12
Java or PL/SQL? (French and German), by Guido Schmutz Trivadis SA, 2000,
http://www.trivadis.ch/
13
StringBuffer versus String, by Reggie Hutcherson, 2000,
http://www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html
Download