You are on page 1of 62

Developing and Deploying Java

Applications within the Oracle 8i JVM


Best Practices for Productivity
and Performance
Hal Hildebrand
Consulting MTS
Hal.Hildebrand@oracle.com

Whos Afraid of the 8.i JVM?


An irreverent introduction to the Oracle 8i Java Server
Architecture

Overview
 To write applications for a server, you must
understand the way the server is architected.
 Like PL/SQL, Java code that runs in the Oracle8i
JVM is running in a database session.
 The Oracle Oracle8i JVM has two major modes of
operation: Java stored procedures and Presentations.

Java is a Portable Language and


the Oracle8i JVM is a Server
Platform
 Java is designed to be a portable language.
 Countless product managers have performed blood
rituals and have made dark pacts with beings too
terrible to mention to ensure that Java runs on their
top tier platforms for their products.
 The Oracle8i JVM is first and foremost, a Java server
architecture. It is a deployment server platform.

Java Runs In Every Tier


 At the 10,000-foot level, the story is that you can
write your entire application in Java, and component
architectures allow you to choose where to run each
piece of the application.
 Naturally, partitioning of the application is critical to
the performance of the application. Poorly
partitioned applications tend to run poorly.
Applications that are sensitive to the partitioning
architecture tend to run faster, be more reliable, and
in general, are easier to maintain.

Java in the Client


 This tier was the first to run Java. Besides the
occasional animated elves, this tier has been ceded to
the web browser, and to the multi-media plugins in
those web browsers. JavaScript is still useful to
accomplish the odd verification task, and to make up
for dynamic programming holes in HTML. But
other than that

Java in the Middle Tier


 This tier quickly became the focus of all who would
tap into the fire hydrants of money that the Internet
has unleashed - at least those of the WORA religion.
 But, Java alone does not a server make. Java is a
general-purpose language, and like the Swiss army
knife, pretty much good for any programming
problem you may find yourself in. As more and
more Java middle tier servers came on line (and Sun
saw the open source server market slipping away
without their mark), a locust-like swarm of server
component architectures appeared on the scene.

Java in the Database Server


 One of the sub-architectures of the Oracle8i JVM is
the Java stored procedure. Like PL/SQL, Java can
be used as a stored procedure language.
 With the inclusion of Java as a stored procedure
implementation language, one of the last holes in
the WORA architecture is closed, allowing
application developers the flexibility of partitioning
their applications (within reason) to run on
anywhere on the landscape consisting of the
multitude of tiers that constitute todays application
environment.

No More Tiers
 The Oracle RDBMS environment includes a
Transaction Processor (TP)monitor environment,
which is quite useful. This environment is the MultiThreaded Server (MTS) architecture of Oracle8i. TP
monitors, the Holy Grail that cleansed all sin in the
1980s, are the model for todays server component
architectures. Regardless of what they say in public,
server vendors benchmark using TP monitors.

Data Drives Location


 Anyone who has ever developed a Model View
Controller application, which requires an unholy
quantity of getter and setter methods, is painfully
aware of this law.
 Thus, any non-trivial application is partitioned into
multiple address spaces (which are what Java VMs
represent). Because of this, all non-trivial application
architectures will want to minimize communication
content between Java VMs especially the
communication that crosses machine boundaries.

Clusters of SMPs are Easier to Manage


than Clusters of Single Processor
Machines
 Clusters of Symmetric Multi-Processors (SMPs) provide
provably better access in architectures that have many clients
accessing a transactional store of slow data.
 Coordinating amongst friends to whom you can talk directly
is always easier than talking to friends via the U.S. Mail.
Theres a non-negligible time lag that cannot be ignored in
distributed communication architectures, a time lag that
significantly dominates the semantics of any distributed
architecture.

SMPs vs. Single Processors


 Multiple processes on multiple machines are
inherently harder to manage than multiple processes
on a single machine. Multiple processes on a single
machine can use shared memory semantics and use
simple semaphores for synchronization. They are
relatively easy to manage because they share a
common context, which can be shared between
them.

SMPs vs. Single Processors


 Mapping processes to machines raises the
architecture to the massively parallel level. No
longer do large grained processes dominant the
architecture. A multitude of fine-grained processes
dominate the system communication becomes
king.

All of Computing is an Exercise


in Caching
 Or to put it another way, a pool is so fundamental as
to almost be ignored when designing large-scale
server architectures. The laws of large numbers of
clients tells us (at least empirically) that ninety
percent of the clients are likely quiescent at any given
time. Thus, we can design the system such that, at
any given time, only ten percent of the number of
clients actually requires the host machines processor
time.

Server Components are Resources


to be Managed
 One of the ways of using the Oracle8i JVM is to
treat server component models as resources to be
scheduled like traditional TP monitors would
schedule a traditional client-server application.
 If you can map the concept of a database call to the
server component model, then the underlying TP
monitor of the server can deal with making client
calls scale.

Common Oracle8i JVM


Architecture
 First, well present the architecture of the Oracle8i
JVM that is common to both modes of operation.
This will lay the groundwork for understanding the
specialized operating environments of the Java
stored procedure and Java presentation architectures.

A Session Based Architecture


 The architecture of the JVM in Oracle8i is based on
the RDBMS session model. Sessions are private
address spaces that clients have exclusive access to.
They are not shared with any other client, although
they may be serially re-used between clients (when
used in a pooling model, for example). Sessions are
isolated from each other. This means that the
actions of one client cannot impact any other client.
All interaction between clients is done through the
database itself, using transactional semantics.

8.i Runs Java in the SQL


Process Address Space
 The 8i server does not implement this model by
making callouts from the SQL server process to an
external Java process. In stark contrast, the Oracle8i
JVM model leverages the session itself to create a
virtual Java VM on a session-by-session basis. These
virtual Java VMs run in the same address space as
SQL and PL/SQL i.e. the session itself. This
means that from the client session viewpoint, the
client is the only code running in the Java VM.

Isnt That Expensive?


 Now, your first reaction to this statement is likely to
be gee, if I have a Java VM per client, then isnt that
really expensive?. The answer is a resounding No!
The 8i JVM is a custom written Java VM which is
architected, from the very beginning, using shared
memory architecture. Without getting too technical,
what this means is that all clients share the read only
static portion of the Java VM.

A Shared Memory Architecture


 All the class meta information, including the
constant pool data, method bytecodes, etc., are
shared between all clients in the same database
instance.

Call Based Memory Management


 The Oracle8i JVM uses the call as a fundamental organizing
principal. Like PL/SQL, Java threads are only active during
the duration of the database call. Without going into too
much detail, calls can be recursive; i.e., a call to the database
can result in a recursive call to the same database, in the same
session.
 The database call is easily understood as the
execution of a java.sql.Statement. The SQL
statement may, when talking JDBC to the 8i
server, result in the execution of PL/SQL, or a Java
stored procedure.

The Top Level Call


 The first call to the database is known as the TopLevel call. In the Java stored procedure model, the
top-level call is defined by SQL. The Oracle8i JVM
also sports a model where the top-level call is
defined by Java. These two different modes of
operation are discussed later in the paper.

Schema Based Class Organization


 Java classes in 8i are not stored in the file system like
traditional Java VMs. The actual class and source
bits are stored in the database system the same way
that PL/SQL packages are stored. Although a deep
technical discussion of exactly how this is done is
beyond the scope of this paper, it is sufficient to say
that Java classes, sources, and resources are database
objects, and as such are listed in the Oracle table
USER_OBJECTS.

An Advanced Security
Environment
 As all Java is run inside an 8i server session, there is a strong
notion of identity inherent in the environment
 Login User

As the name implies, it is the user that logs in to the server,


establishing the base identity under which all SQL, PL/SQL and
Java is executed.
Effective User
The effective user of a session is the dynamic identity of a session.
The dynamic identity of a session is changed by running definers
rights code either Java or PL/SQL

Efficient Access to the Underlying


RDBMS
 Because the Java is running directly in the database
session, access to the underlying SQL is available to
the Java code through JDBC, without logging in
the session is already established! This connection to
the SQL engine is a distinguished JDBC connection,
obtained through either a JDBC URL, or through
static methods on the Oracle-specific JDBC driver
classes.

A Sophisticated Run-As Capability


 Java code in the 8.i environment has a run-as capability that
has no analogy in other Java VMs. Java classes can be
optionally made definers rights or bound. As mentioned
above, definers rights Java classes will change the effective
identity of the session. By executing definers rights classes,
the effective user of the session can be temporarily changed.
For example, suppose class B is definers rights code, where
the defining schema is SYS. When methods in class B are
executed, the identity of the session will become SYS. This
means that all SQL executed by JDBC in this session, using
the default connection, will be executing as SYS all
unqualified object references will be resolved relative to the
SYS schema, and permissions will be checked against the SYS
schema.

Integrated Java 1.2 Security Model


 A new, finer grained security model was introduced
in Java 1.2. This security model defines the notion
of a code base, and permissions, which are granted,
to the code base. Although a complete discussion of
the 1.2 Java security model is outside the scope of
this paper, suffice it to say that the permissions at
any point of execution are the intersection of the
code bases on the threads execution stack. This
means that different code bases can limit the
effective permissions, but never extend them.

Tying Permissions to Class


Schema
 In the 8.i Java VM, the code base of a Java class is
considered to be the defining schema of the Java
class. The 8.i server environment includes a system
that allows administrators and users to grant or
disallow permissions on a schema and role basis.

Effect of Definers Rights Class


 The effective user and login user of the session
interact with the Java permission model in a
straightforward way. When running definers rights
code, it is equivalent to the Java mechanism,
java.security.AccessController.doPrivileged(). This
has the effect of trimming off the permissions stack
at the definers rights code.

Java Stored Procedure


Architecture
 Java stored procedures are very similar to PL/SQL
in their interface with SQL. They are designed to be
callable from SQL, so this is no surprise. The Java
stored procedure has a PL/SQL wrapper, or call
spec, that defines how the external function or
procedure is typed, and which Java static method
implementation is used.

Embedded Java VM
 The Java stored procedure execution environment is
one of an embedded Java VM. This means that the
SQL call to the database is the top-level entry point
in the session, just as it is in PL/SQL execution.
Thus, in the stored procedure world, all Java
execution happens as a result of SQL execution.

Java Stored Procedure Lifecycle







VM Startup
Top Level and Re-entrant Calls
Java State Between Calls
VM Shut Down

VM Startup
 The first time Java is called, either directly as a
PL/SQL wrapped function or procedure, or
indirectly, as a trigger, the Java VM is started up.
Unlike a traditional Java VM, this is not in response
to a top-level call to the main() method. Rather
entry into the Java VM is through any public static
method that is published via a PL/SQL wrapper.

Top Level and Re-entrant Calls


 Because Java stored procedures can perform SQL,
further stored procedures may be called as a result of
executing SQL. This means that Java can be
recursively invoked. When Java is recursively
invoked, the same Java VM is used, and the Java
code run has access to the same Java state as the
originating call. This means that Java state
manipulated in the recursive procedure is visible to
the outer calls.

Java State Between Calls


 The only Java state maintained between calls is the
state that is rooted from the static variables of the
activated classes in the session. If a Java object is
not reachable via some route that is rooted in a static
variable of some class, the object will be garbage
collected.

VM Shut Down
 Java is shut down when the SQL session is shut down. In the
Oracle8i JVM, the method java.lang.System.exit(int) is a noop. Again, because Java is being called from a top-level SQL
call, no JSP should be terminating the session, as this causes
interesting problems with SQL clients. Naturally, there are
ways around this, the Oracle8i JVM environment providing
mechanisms by which Java can shut down the session. These
mechanisms should, of course, be used sparingly and only
when the effects are well understood by the application.

Java Stored Procedure Security


Environment
 Because the Java stored procedure is called from
SQL, the SQL client establishes the login user of the
session. Thus, the security environment is not
established by the Java code, rather inherited from
the SQL environment. However, as mentioned
above, definers rights Java code can change the
effective user of the session. Likewise, PL/SQL
definers rights code that directly, or indirectly runs a
Java stored procedure will determine the effective
user of the session when Java is entered.

SQL and Java Objects


 SQL does not have a notion of an object pointer.
Thus, Java objects cannot be returned as the result
of a Java stored procedure.
 If objects are to be used between stored procedure
calls, they must be stored in a way reachable from
static class variables. In this way, Java stored
procedures can repeatedly operate on the same Java
object instances.

Java Presentation Architecture


 Java is often billed as network language. A network
language relies, ultimately, on TCP/IP socket
communications with the outside world. In addition
to the Java Stored Procedure model, the Oracle8i
JVM provides an event driven server model for
inbound java.net.Socket interactions with external
clients.

TP Monitor Server Model


 Like the stored procedure model, the Presentation
model is based on the same session oriented Java
VM. However, unlike the stored procedure model,
the Presentation model is based on the use of MTS
(not to be confused with the Microsoft
Transaction Service). While a full discussion of
the 8i MTS server model is beyond the scope of this
paper, suffice it to say that MTS is essentially a builtin TP monitor for the 8i server.

Java is the Top Level Call


 The primary difference between the JSP model and the
Presentation model is that Java, rather than SQL, is defining
the top-level call of the server. Because the Java Presentation
model uses TCP/IP for the inbound socket model, it is more
flexible than the SQL model. For example, the Java
Presentation model allows sessions to have multiple inbound
TCP/IP socket connections, as well as multiple outbound
TCP/IP socket connections. Also, the session lifetime may
be independent of the existence of inbound connections to
the session. By contrast, the SQL session has only one
inbound connection from a single client. The SQL session
lifetime is determined by the client connection lifetime.

Support for Multiple Protocols


 The Java Presentation server architecture uses the
java.net.Socket model for communication and can
therefore support protocols other than SQL*NET
for clients to communicate to the server. Protocols
such as HTTP and CORBA (IIOP) provide access
to the Servlet 2.2 and EJB 1.1 component models.
 The support of advanced Java component models
embedded in a TP monitor server environment
provides a very scalable platform to host server
applications.

Java Presentation Lifecycle


 Sessions running under the Java Presentation model
have a similar lifecycle to normal SQL sessions. The
primary difference being that from birth to death,
they are controlled by Java code, rather than SQL
interaction with the client.
 Because protocols and component models
implemented in Java control the sessions, there is a
chicken and the egg problem. We can only run Java
in a session, so we first need to have a session before
we can execute Java.

Session Establishment
 Unlike SQL*NET, many Internet TCP/IP
protocols, such as HTTP do not have an intrinsic
notion of logging in. Other models, such as
CORBA, have a notion in their security model, but
implement this using the underlying protocol itself.
Because of this, a model must be created which
allows server code to run securely, establishing the
clients identity.

Java Server Component Models


 Key to the TP monitor server architecture is the
notion of a server component. The server side
component is an object that has narrowly defined
boundaries. In essence, the server component
model is cleanly divided into the environment (the
Container) and the actual server object itself (the
Component).

Component Code is Not


General Purpose
 Component code is clearly not general-purpose
code. Component models are designed to take
advantage of certain environments. The container,
by definition, imposes a set of ground rules that the
component must conform to. In essence, the
component is a resource that the container must
manage.

Typical Metrics Which Define


Component Resources







CPU
Object Memory
JDBC Statements
JDBC Connections
JDBC Transactions
Outbound TCP/IP Sockets

Typical Component Security


Notions





Authorization
Run As Identity
Access Control
Security Impersonation

8.i JVM as a Component


Server Platform
 The Oracle8i JVM provides a unique server
environment, being embedded in a highly scalable
RDBMS that already has strong notions of security
and resource management. Thus, its not surprising
to see TP monitor like semantics in the Java server
component models supported by the Oracle8i JVM.

EJB
 The Java Presentation architecture was initially
developed to support EJB on the Oracle8i JVM.
The semantics of session beans are very close to the
semantics of running in the session oriented VM.
Because Java already executes in a secure server
environment, the security aspects of EJBs are easy to
map. The call oriented nature of the JVM maps
quite well to the call-oriented interface of session
beans

Servlets
 In Oracle8i Release 3, the Oracle8i JVM now
contains a Servlet 2.2 compliant container
commonly known as the Oracle Servlet Engine (or
OSE). As the Oracle8i JVM is a session oriented
VM, its no surprise that the OSE is geared for
session-oriented interaction with HTTP clients.
Through the use of an Apache module, mod_ose,
stateless interaction with HTTP clients is efficient as
well.

Servlets Calling EJBs


 Servlets running in the OSE can directly invoke
EJBs bound in the JNDI namespace, vastly
increasing the performance and simplicity of using
EJBs from Servlet code.
 Because the OSE is running in the same advanced
server environment that the EJB container is
running, the OSE can extend the Servlet 2.2 api to
provide advanced security and database interactions
the dream of every middle tier.

Oracle8i JVM Best Practices


 And finally, if youve followed this far, we come to
the distilled wisdom of several years programming
for the Oracle8i JVM. The advice should certainly
seem common sense by now, having slogged
through all the previous information.

Treat Java Stored Procedures Like


PL/SQL
 You wouldnt pop up a modal dialog in a PL/SQL
function, nor should you even consider it in a Java
stored procedure. Because PL/SQL is a procedural
language, not an object oriented language, the Java
stored procedure interface is procedurally oriented as
well. Do not assume that you have an Object type in
SQL the Java stored procedure interface is
implemented via static class methods and is limited
to SQL data types for parameter and return type
definitions.

Understand the Session Model


 Live with it. Although its not the best model for
every piece of code, it is the best model for many kinds
of code. The session model is fundamental to good
Oracle8i JVM architectures. If you understand it,
your code will prosper. Cross it, and youll be
wondering why the performance of your application
doesnt satisfy.

Single Client Per Session


 The essence of the session model is the single client
per session. You should slap yourself silly any time
you find yourself fantasizing about serving multiple
clients with a JVM session. Sessions are serially
accessed by clients, and so are not architected to
efficiently multiplex simultaneous clients.

Sessions Can Be Serially


Reused
 This is not to suggest that you cant make effective stateless
use of the Oracle8i JVM. Like normal SQL sessions, a pool
of 8i Java sessions can be serially reused among a number of
clients. This can be done using fundamentally the same tools
as pools of SQL sessions that run PL/SQL. For Servlets, you
can take advantage of the mod_ose stateless ServletContexts.
For SQL clients, the interface is effectively PL/SQL,
although CORBA connections to the Oracle8i JVM provide
RMI communication interfaces to pools of Enterprise
JavaBeans.

Think Twice Before Spawning


Threads
 Really. Why do you want to do this? Ignore the
little devil on your shoulder and consult a good
friend. Go to dinner. Have a relaxing evening in the
hot tub. Forget all about it when you come back to
work in the morning.

8.i JVM Threads are NonPreemptively Scheduled


 Seriously. Java Threads running in the 8i session are
not preemptively scheduled. This means that unless
the Java code yields - i.e.
java.lang.Thread.yield() another
java.lang.Thread will not run. SQL that
executes in the session as a result of using the default
(i.e. the jdbc:oracle:kprb: URL)
java.sql.Connection is single threaded
anyway. This means you cant ever execute SQL in
parallel from a Java session. This is because the SQL
server is single threaded on the session level.

Leverage Sophisticated Security


 One of the hardest things about middle tier Java
code is efficient security. Take advantage of
definers rights Java classes. They allow you to
securely expose security-sensitive capabilities
through Java APIs. Remember that the default
JDBC connection of the session executes SQL as the
effective schema of the session.

Control Access to Security


Sensitive Java Classes
 Control access to security-sensitive Java classes using the
execute rights associated with the Java classes. Although
these can seem to be a pain at times, the execute rights of the
Java classes can be used to securely control access to sensitive
code. Get in the habit of understanding where functionality
is accessed and layer Java language security structures (private
and protected access, as well as package protected classes and
interfaces) on top of the airtight execute right mechanisms of
the underlying RDBMS server.

In the End, Let Rationality Be


Your Guide
 Certainly, this is the most relevant of any suggestions the
author could provide the intrepid (and certainly patient)
reader. There are only so many ways to boil water, and all of
them require heat.
 When you partition your application, you must understand
the advantages and disadvantages of the servers that run your
code. Choose the tier that runs your Java code wisely. The
Oracle8i JVM provides new flexibility to the WORA religion
by running Java in the database session itself.
 Nothing more. Nothing less.

You might also like