Chapter Contents

This chapter covers the following three missions:

Introduces the Java language for Oracle database programmers. Oracle PL/SQL developers are accustomed to developing server-side applications that have tight integration with SQL data. You can develop Java server-side applications that take advantage of the scalability and performance of the Oracle database. If you are not familiar with Java, see "Overview of Java".

Provides a roadmap to the Oracle9i Java documentation. Several Java APIs are supported within Oracle9i. Each API is described generally in this book, and more intimately in their own books. "Overview of Oracle9i Java Documentation" shows you which books cover each Java application type in detail.

Upgrading to JDK 1.3

In this release, the system classes are upgraded from JDK 1.2 to JDK 1.3. The JDK 1.3 is compatible with JDK 1.2. Sun Microsystems publishes the list of incompatibilities between the two versions at the following Web site:

http://java.sun.com/products/jdk/1.2/compatibility.html

Desupport of J2EE Technologies in the Oracle Database

With the introduction of Oracle9i Application Server Containers for J2EE (OC4J)--a new, lighter-weight, easier-to-use, faster, and certified J2EE container--Oracle will desupport the Java 2 Enterprise Edition (J2EE) and CORBA stacks from the database, starting with Oracle9i database release 2. However, the database-embedded Java VM (Oracle JVM) will still be present and will continue to be enhanced to offer Java 2 Standard Edition (J2SE) features, Java stored procedures, JDBC, and SQLJ in the database.

As of Oracle9i database release 2 (9.2.0), Oracle will no longer support the following technologies in the database:

the J2EE stack, consisting of:

Enterprise Beans (EJB) container

JavaServer Pages (JSP) container

Oracle9i Servlet Engine (OSE)

the embedded Common Object Request Broker Architecture (CORBA) framework, based on Visibroker for Java

Customers will no longer be able to deploy servlets, JSP pages, EJBs, and CORBA objects in Oracle databases. Oracle9i database release 1 (9.0.1) will be the last database release to support the J2EE and CORBA stack. Oracle is encouraging customers to migrate existing J2EE applications running in the database to OC4J now.

Additions to the loadjava Tool

New options have been added to the loadjava tool. Specifically, the -genmissing option enables you to do the following:

Determines what classes and methods are referred to by the classes that loadjava is asked to process. Any classes not found in the database or file arguments are called "missing" classes. This option generates dummy definitions for missing classes containing all referred to methods. It then loads the generated classes into the database. This processing happens before the class resolution.

Because detecting references from source is more difficult than detecting references from classfiles, and because source is not generally used for distributing libraries, loadjava will not attempt to do this processing for source files.

The schema in which the missing classes are loaded will be the one specified by the -user command-line option, even when referring classes are created in some other schema. The created classes will be flagged as such so that tools can recognize them. In particular, this is needed, so that the verifier can recognize generated classes.

Replacement of the sess_sh tool with ojvmjava

With the removal of the EJB, JSP, and servlet APIs, there is no longer a need for most of the functionality of the sess_sh tool. Instead, a scaled-down version of this tool is made available in the ovjmjava tool. See "ojvmjava" for more information.

Debugger Modifications

Oracle9i furnishes a debugging capability that is useful for developers who use the JDK's jdb debugger. Two interfaces are supported.

The debug Agent protocol that was introduced in Oracle8i, and is supported by JDK 1.2 and later versions of JDB. The class DebugProxy makes remote Java programs appear to be local. It lets any debugger that supports the sun.tools.debug.Agent protocol connect to a program as if the program were local. The proxy forwards requests to the server and returns results to the debugger.

The Java Debug Wire Protocol supported by JDK 1.3 and later versions of the Sun Microsystems JDB debugger (http://java.sun.com/j2se/1.3/docs/guide/jpda/, http://java.sun.com/j2se/1.4/docs/guide/jpda/.) The use of this interface is documented on OTN. The JDWP protocol supports many new features, including the ability to listen for connections (no more DebugProxy), change the values of variables while debugging, and evaluate arbitrary Java expressions, including method evaluation.

Oracle's JDeveloper provides a user-friendly integration with these debugging features. See the JDeveloper documentation for more information on how to debug your Java application through JDeveloper. Other independent IDE vendors will be able to integrate their own debuggers with Oracle9i.

Overview of Java

Java has emerged as the object-oriented programming language of choice. It includes the following concepts:

a Java virtual machine (JVM), which provides the fundamental basis for platform independence

automated storage management techniques, the most visible of which is garbage collection

language syntax that borrows from C and enforces strong typing

The result is a language that is object-oriented and efficient for application-level programs.

Java and Object-Oriented Programming Terminology

This section covers some basic terminology of Java application development in the Oracle9i environment. The terms should be familiar to experienced Java programmers. A detailed discussion of object-oriented programming or of the Java language is beyond the scope of this book. Many texts, in addition to the complete language specification, are available at your bookstore and on the Internet. See "Java Information Resources" in the Preface, and "Suggested Reading" in the Oracle9i Java Stored Procedures Developer's Guide for pointers to reference materials and for places to find Java-related information on the Internet.

Classes

All object-oriented programming languages support the concept of a class. As with a table definition, a class provides a template for objects that share common characteristics. Each class can contain the following:

Attributes--static or instance variables that each object of a particular class possesses.

Methods--you can invoke methods defined by the class or inherited by any classes extended from the class.

When you create an object from a class, you are creating an instance of that class. The instance contains the fields of an object, which are known as its data, or state. Figure 1-1 shows an example of an Employee class defined with two attributes: last name (lastName) and employee identifier (ID).

Figure 1-1 Classes and Instances

When you create an instance, the attributes store individual and private information relevant only to the employee. That is, the information contained within an employee instance is known only for that single employee. The example in Figure 1-1 shows two instances of employee--Smith and Jones. Each instance contains information relevant to the individual employee.

Attributes

Attributes within an instance are known as fields. Instance fields are analogous to the fields of a relational table row. The class defines the fields, as well as the type of each field. You can declare fields in Java to be static, public, private, protected, or default access.

Public, private, protected, or default access fields are created within each instance.

Static fields are like global variables in that the information is available to all instances of the employee class.

The language specification defines the rules of visibility of data for all fields. Rules of visibility define under what circumstances you can access the data in these fields.

Methods

The class also defines the methods you can invoke on an instance of that class. Methods are written in Java and define the behavior of an object. This bundling of state and behavior is the essence of encapsulation, which is a feature of all object-oriented programming languages. If you define an Employee class, declaring that each employee's id is a private field, other objects can access that private field only if a method returns the field. In this example, an object could retrieve the employee's identifier by invoking the Employee.getId() method.

In addition, with encapsulation, you can declare that the Employee.getId() method is private, or you can decide not to write an Employee.getId() method. Encapsulation helps you write programs that are reusable and not misused. Encapsulation makes public only those features of an object that are declared public; all other fields and methods are private. Private fields and methods can be used for internal object processing.

Class Hierarchy

Java defines classes within a large hierarchy of classes. At the top of the hierarchy is the Object class. All classes in Java inherit from the Object class at some level, as you walk up through the inheritance chain of superclasses. When we say Class B inherits from Class A, each instance of Class B contains all the fields defined in class B, as well as all the fields defined in Class A. For example, in Figure 1-2, the FullTimeEmployee class contains the id and lastName fields defined in the Employee class, because it inherits from the Employee class. In addition, the FullTimeEmployee class adds another field, bonus, which is contained only within FullTimeEmployee.

You can invoke any method on an instance of Class B that was defined in either Class A or B. In our employee example, the FullTimeEmployee instance can invoke methods defined only within its own class, or methods defined within the Employee class.

Figure 1-2 Class Hierarchy

Instances of Class B are substitutable for instances of Class A, which makes inheritance another powerful construct of object-oriented languages for improving code reuse. You can create new classes that define behavior and state where it makes sense in the hierarchy, yet make use of pre-existing functionality in class libraries.

Interfaces

Java supports only single inheritance; that is, each class has one and only one class from which it inherits. If you must inherit from more than one source, Java provides the equivalent of multiple inheritance, without the complications and confusion that usually accompany it, through interfaces. Interfaces are similar to classes; however, interfaces define method signatures, not implementations. The methods are implemented in classes declared to implement an interface. Multiple inheritance occurs when a single class simultaneously supports many interfaces.

Polymorphism

Assume in our Employee example that the different types of employees must be able to respond with their compensation to date. Compensation is computed differently for different kinds of employees.

FullTimeEmployees are eligible for a bonus

NonExemptEmployees get overtime pay

In traditional procedural languages, you would write a long switch statement, with the different possible cases defined.

If you add a new kind of Employee, you must update your switch statement. If you modify your data structure, you must modify all switch statements that use it. In an object-oriented language such as Java, you implement a method, compensationToDate(), for each subclass of Employee class that requires any special treatment beyond what is already defined in Employee class. For example, you could implement the compensationToDate() method of NonExemptEmployee, as follows:

The common usage of the method name compensationToDate() allows you to invoke the identical method on different classes and receive different results, without knowing the type of employee you are using. You do not have to write a special method to handle FullTimeEmployees and PartTimeEmployees. This ability for the different objects to respond to the identical message in different ways is known as polymorphism.

In addition, you could create an entirely new class that does not inherit from Employee at all--Contractor--and implement a compensationToDate() method in it. A program that calculates total payroll to date would iterate over all people on payroll, regardless of whether they were full-time, part-time, or contractors, and add up the values returned from invoking the compensationToDate() method on each. You can safely make changes to the individual compensationToDate() methods with the knowledge that callers of the methods will work correctly. For example, you can safely add new fields to existing classes.

The Java Virtual Machine (JVM)

As with other high-level computer languages, your Java source compiles to low-level machine instructions. In Java, these instructions are known as bytecodes (because their size is uniformly one byte of storage). Most other languages--such as C--compile to machine-specific instructions--such as instructions specific to an Intel or HP processor. Your Java source compiles to a standard, platform-independent set of bytecodes, which interacts with a Java virtual machine (JVM). The JVM is a separate program that is optimized for the specific platform on which you execute your Java code. Figure 1-3 illustrates how Java can maintain platform independence. Your Java source is compiled into bytecodes, which are platform independent. Each platform has installed a JVM that is specific to its operating system. The Java bytecodes from your source get interpreted through the JVM into appropriate platform dependent actions.

Figure 1-3 Java Component Structure

When you develop a Java program, you use predefined core class libraries written in the Java language. The Java core class libraries are logically divided into packages that provide commonly-used functionality, such as basic language support (java.lang), input/output (java.io), and network access (java.net). Together, the JVM and core class libraries provide a platform on which Java programmers can develop with the confidence that any hardware and operating system that supports Java will execute their program. This concept is what drives the "write once, run anywhere" idea of Java.

Figure 1-4 illustrates how Oracle's Java applications sit on top of the Java core class libraries, which in turn sit on top of the JVM. Because Oracle's Java support system is located within the database, the JVM interacts with the Oracle database libraries, instead of directly with the operating system.

Figure 1-4 Oracle9i Java Component Structure

Sun Microsystems furnishes publicly available specifications for both the Java language and the JVM. The Java Language Specification (JLS) defines things such as syntax and semantics; the JVM specification defines the necessary low-level behavior for the "machine" that executes the bytecodes. In addition, Sun Microsystems provides a compatibility test suite for JVM implementors to determine if they have complied with the specifications. This test suite is known as the Java Compatibility Kit (JCK). Oracle's JVM implementation complies fully with JCK. Part of the overall Java strategy is that an openly specified standard, together with a simple way to verify compliance with that standard, allows vendors to offer uniform support for Java across all platforms.

Key Features of the Java Language

The Java language has key features that make it ideal for developing server applications. These features include:

Simplicity--Java is a simpler language than most others used in server applications because of its consistent enforcement of the object model. The large, standard set of class libraries brings powerful tools to Java developers on all platforms.

Portability--Java is portable across platforms. It is possible to write platform-dependent code in Java, but it is also simple to write programs that move seamlessly across machines. Oracle server applications, which do not support graphical user interfaces directly on the platform that hosts them, also tend to avoid the few platform portability issues that Java has.

Automatic Storage Management--The Java virtual machine automatically performs all memory allocation and deallocation during program execution. Java programmers can neither allocate nor free memory explicitly. Instead, they depend on the JVM to perform these bookkeeping operations, allocating memory as they create new objects and deallocating memory when the objects are no longer referenced. The latter operation is known as garbage collection.

Strong Typing--Before you use a Java variable, you must declare the class of the object it will hold. Java's strong typing makes it possible to provide a reasonable and safe solution to inter-language calls between Java and PL/SQL applications, and to integrate Java and SQL calls within the same application.

No Pointers--Although Java retains much of the flavor of C in its syntax, it does not support direct pointers or pointer manipulation. You pass all parameters, except primitive types, by reference (that is, object identity is preserved), not by value. Java does not provide C's low level, direct access to pointers, which eliminates memory corruption and leaks.

Exception Handling--Java exceptions are objects. Java requires developers to declare which exceptions can be thrown by methods in any particular class.

Flexible Namespace--Java defines classes and holds them within a hierarchical structure that mirrors the Internet's domain namespace. You can distribute Java applications and avoid name collisions. Java extensions such as the Java Naming and Directory Interface (JNDI) provide a framework for multiple name services to be federated. Java's namespace approach is flexible enough for Oracle to incorporate the concept of a schema for resolving class names, while fully complying with the language specification.

Security--The design of Java bytecodes and the JVM allow for built-in mechanisms to verify that the Java binary code was not tampered with. Oracle9i is installed with an instance of SecurityManager, which, when combined with Oracle database security, determines who can invoke any Java methods.

Why Use Java in Oracle9i?

The only reason that you are allowed to write and load Java applications within the database is because it is a safe language. Java has been developed to prevent anyone from tampering with the operating system that the Java code resides in. Some languages, such as C, can introduce security problems within the database; Java, because of its design, is a safe language to allow within the database.

Although the Java language presents many advantages to developers, providing an implementation of a JVM that supports Java server applications in a scalable manner is a challenge. This section discusses some of these challenges.

Multithreading

Multithreading support is often cited as one of the key scalability features of the Java language. Certainly, the Java language and class libraries make it simpler to write multithreaded applications in Java than many other languages, but it is still a daunting task in any language to write reliable, scalable multithreaded code.

As a database server, Oracle9i efficiently schedules work for thousands of users. The Oracle9i JVM uses the facilities of the RDBMS server to concurrently schedule Java execution for thousands of users. Although Oracle9i supports Java language level threads required by the JLS and JCK, using threads within the scope of the database will not increase your scalability. Using the embedded scalability of the database eliminates the need for writing multithreaded Java servers. You should use the database's facilities for scheduling users by writing single-threaded Java applications. The database will take care of the scheduling between each application; thus, you achieve scalability without having to manage threads. You can still write multithreaded Java applications, but multiple Java threads will not increase your server's performance.

One difficulty multithreading imposes on Java is the interaction of threads and automated storage management, or garbage collection. The garbage collector executing in a generic JVM has no knowledge of which Java language threads are executing or how the underlying operating system schedules them.

Non-Oracle9i model--A single user maps to a single Java language level thread; the same single garbage collector manages all garbage from all users. Different techniques typically deal with allocation and collection of objects of varying lifetimes and sizes. The result in a heavily multithreaded application is, at best, dependent upon operating system support for native threads, which can be unreliable and limited in scalability. High levels of scalability for such implementations have not been convincingly demonstrated.

Oracle9i JVM model--Even when thousands of users connect to the server and execute the same Java code, each user experiences it as if he is executing his own Java code on his own Java virtual machine. The responsibility of the Oracle9i JVM is to make use of operating system processes and threads, using the scalable approach of the Oracle RDBMS. As a result of this approach, the JVM's garbage collector is more reliable and efficient because it never collects garbage from more than one user at any time. Refer to "Threading in Oracle9i" for more information on the thread model implementation in Oracle9i JVM.

Automated Storage Management

Garbage collection is a major feature of Java's automated storage management, eliminating the need for Java developers to allocate and free memory explicitly. Consequently, this eliminates a large source of memory leaks that commonly plague C and C++ programs. There is a price for such a benefit: garbage collection contributes to the overhead of program execution speed and footprint. Although many papers have been written qualifying and quantifying the trade-off, the overall cost is reasonable, considering the alternatives.

Garbage collection imposes a challenge to the JVM developer seeking to supply a highly scalable and fast Java platform. The Oracle9i JVM meets these challenges in the following ways:

Garbage collection is performs consistently for multiple users because garbage collection is focused on a single user within a single session. The Oracle9i JVM enjoys a huge advantage because the burden and complexity of the memory manager's job does not increase as the number of users increases. The memory manager performs the allocation and collection of objects within a single session--which typically translates to the activity of a single user.

The Oracle9i JVM uses different garbage collection techniques depending on the type of memory used. These techniques provide high efficiency and low overhead.

Footprint

The footprint of an executing Java program is affected by many factors:

Size of the program itself--how many classes and methods and how much code they contain.

Complexity of the program--the amount of core class libraries that the Oracle9i JVM uses as the program executes, as opposed to the program itself.

Amount of state the JVM uses--how many objects the JVM allocates, how large they are, and how many must be retained across calls.

Ability of the garbage collector and memory manager to deal with the demands of the executing program, which is often non-deterministic. The speed with which objects are allocated and the way they are held on to by other objects influences the importance of this factor.

From a scalability perspective, the key to supporting many concurrent clients is a minimum per-user session footprint. The Oracle9i JVM keeps the per-user session footprint to a minimum by placing all read-only data for users, such as Java bytecodes, in shared memory. Appropriate garbage collection algorithms are applied against call and session memories to maintain a small footprint for the user's session. The Oracle9i JVM uses three types of garbage collection algorithms to maintain the user's session memory:

generational scavenging for short-lived objects

mark and lazy sweep collection for objects that exist for the life of a single call

copying collector for long-lived objects--objects that live across calls within a session

Performance

Oracle9i JVM performance is enhanced by implementing a native compiler.

How Native Compilers Improve Performance

Java executes platform-independent bytecodes on top of a JVM, which in turn interacts with the specific hardware platform. Any time you add levels within software, your performance is degraded. Because Java requires going through an intermediary to interpret platform-independent bytecodes, a degree of inefficiency exists for Java applications that does not exists within a platform-dependent language, such as C. To address this issue, several JVM suppliers create native compilers. Native compilers translate Java bytecodes into platform-dependent native code, which eliminates the interpreter step and improves performance.

The following describes two methods for native compilation:

Compiler

Description

Just-In-Time (JIT) Compilation

JIT compilers quickly compile Java bytecodes to native (platform-specific) machine code during runtime. This does not produce an executable to be executed on the platform; instead, it provides platform-dependent code from Java bytecodes that is executed directly after it is translated. This should be used for Java code that is run frequently, which will be executed at speeds closer to languages such as C.

Ahead-of-Time Compilation

Compilation translates Java bytecodes to platform-independent C code before runtime. Then a standard C compiler compiles the C code into an executable for the target platform. This approach is more suitable for Java applications that are modified infrequently. This approach takes advantage of the mature and efficient platform-specific compilation technology found in modern C compilers.

Oracle9i uses Ahead-of-Time compilation to deliver its core Java class libraries: JDBC code in natively compiled form. It is applicable across all the platforms Oracle supports, whereas a JIT approach requires low-level, processor-dependent code to be written and maintained for each platform. You can use this native compilation technology with your own Java code. Refer to "Natively Compiled Code" for more information.

Dynamic Class Loading

Another strong feature of Java is dynamic class loading. The class loader loads classes from the disk (and places them in the JVM-specific memory structures necessary for interpretation) only as they are used during program execution. The class loader locates the classes in the CLASSPATH and loads them during program execution. This approach, which works well for applets, poses the following problems in a server environment:

Problem

Description

Solution

Predictability

The class loading operation places a severe penalty on first-time execution. A simple program can cause the Oracle9i JVM to load many core classes to support its needs. A programmer cannot easily predict or determine the number of classes loaded.

The Oracle9i JVM loads classes dynamically, just as with any other Java virtual machine. The same one-time class loading speed hit is encountered. However, because the classes are loaded into shared memory, no other users of those classes will cause the classes to load again--they will simply use the same pre-loaded classes.

Reliability

A benefit of dynamic class loading is that it supports program updating. For example, you would update classes on a server, and clients who download the program and load it dynamically see the update whenever they next use the program. Server programs tend to emphasize reliability. As a developer, you must know that every client executes a specific program configuration. You do not want clients to inadvertently load some classes that you did not intend them to load.

Oracle9i separates the upload and resolve operation from the class loading operation at runtime. You upload Java code you developed to the server using the loadjava utility. Instead of using CLASSPATH, you specify a resolver at installation time. The resolver is analogous to CLASSPATH, but allows you to specify the schemas in which the classes reside. This separation of resolution from class loading means you always know what program users execute. Refer to Chapter 7, "Schema Object Tools" for details on loadjava and resolvers.

Oracle's Java Application Strategy

One appeal of Java is its ubiquity and the growing number of programmers capable of developing applications using it. Oracle furnishes enterprise application developers with an end-to-end Java solution for creating, deploying, and managing Java applications. The total solution consists of client-side and server-side programmatic interfaces, tools to support Java development, and a Java virtual machine integrated with the Oracle9i database server. All these products are 100 percent compatible with Java standards.

In addition to the Oracle9i JVM, the Java programming environment consists of:

Java stored procedures as the Java equivalent and companion for PL/SQL. Java stored procedures are tightly integrated with PL/SQL. You can call a Java stored procedure from a PL/SQL package; you can call PL/SQL procedures from a Java stored procedure.

SQL data can be accessed through JDBC and SQLJ programming interfaces.

Tools and scripts used in assisting in development, class loading, and class management.

To help you decide which Java APIs to use, examine the following table:

Type of functionality you need

Java API to use

To have a Java procedure invoked from SQL, such as a trigger.

Java Stored Procedures

To invoke a static, simple SQL statement from a known table with known column names from a Java object.

SQLJ

To invoke dynamic, complex SQL statements from a Java object.

JDBC

Java Stored Procedures

If you are a PL/SQL programmer exploring Java, you will be interested in Java stored procedures. A Java stored procedure is a program you write in Java to execute in the server, exactly as a PL/SQL stored procedure. You invoke it directly with products like SQL*Plus, or indirectly with a trigger. You can access it from any Oracle Net client--OCI, PRO*, JDBC or SQLJ. The Oracle9i Java Stored Procedures Developer's Guide explains how to write stored procedures in Java, how to access them from PL/SQL, and how to access PL/SQL functionality from Java.

In addition, you can use Java to develop powerful programs independently of PL/SQL. Oracle9i provides a fully-compliant implementation of the Java programming language and JVM.

PL/SQL Integration and Oracle RDBMS Functionality

You can invoke existing PL/SQL programs from Java and invoke Java programs from PL/SQL. This solution protects and leverages your existing investment while opening up the advantages and opportunities of Java-based Internet computing.

Oracle offers two different application programming interfaces (APIs) for Java developers to access SQL data--JDBC and SQLJ. Both APIs are available on client and server, so you can deploy the same code in either place.

JDBC Drivers

JDBC is a database access protocol that enables you to connect to a database and then prepare and execute SQL statements against the database. Core Java class libraries provide only one JDBC API. JDBC is designed, however, to allow vendors to supply drivers that offer the necessary specialization for a particular database. Oracle delivers the following three distinct JDBC drivers.

Driver

Description

JDBC Thin Driver

You can use the JDBC Thin driver to write 100% pure Java applications and applets that access Oracle SQL data. The JDBC Thin driver is especially well-suited to Web browser-based applications and applets, because you can dynamically download it from a Web page just like any other Java applet.

JDBC Oracle Call Interface Driver

The JDBC Oracle Call Interface (OCI) driver accesses Oracle-specific native code (that is, non-Java) libraries on the client or middle tier, providing a richer set of functionality and some performance boost compared to the JDBC Thin driver, at the cost of significantly larger size and client-side installation.

JDBC Server-side Internal Driver

Oracle9i uses the server-side internal driver when Java code executes on the server. It allows Java applications executing in the server's Java virtual machine to access locally defined data (that is, on the same machine and in the same process) with JDBC. It provides a further performance boost because of its ability to use underlying Oracle RDBMS libraries directly, without the overhead of an intervening network connection between your Java code and SQL data. By supporting the same Java-SQL interface on the server, Oracle9i does not require you to rework code when deploying it.

SQLJ - Embedded SQL in Java

Oracle has worked with other vendors, including IBM, Tandem, Sybase, and Sun Microsystems, to develop a standard way to embed SQL statements in Java programs--SQLJ. This work has resulted in a new standard (ANSI x.3.135.10-1998) for a simpler and more highly productive programming API than JDBC. A user writes applications to this higher-level API and then employs a preprocessor to translate the program to standard Java source with JDBC calls. At runtime, the program can communicate with multi-vendor databases using standard JDBC drivers.

SQLJ provides a simple, but powerful, way to develop both client-side and middle-tier applications that access databases from Java. You can use it in stored procedures, triggers, and methods within the Oracle9i environment. In addition, you can combine SQLJ programs with JDBC.

The SQLJ translator is a Java program that translates embedded SQL in Java source code to pure JDBC-based Java code. Because Oracle9i provides a complete Java environment, you cannot only compile SQLJ programs on a client for execution on the server, but you can compile them directly on the server. The adherence of Oracle9i to Internet standards allows you to choose the development style that fits your needs.

Development Tools

The introduction of Java to the Oracle9i server allows you to use several Java Integrated Development Environments. The adherence of Oracle9i to Java compatibility and open Internet standards and protocols ensures that your 100% pure Java programs work when you deploy them on Oracle9i. Oracle delivers many tools or utilities, all written in Java, that make development and deployment of Java server applications easier. Oracle's JDeveloper has many features designed specifically to make deployment of Java stored procedures and Enterprise JavaBeans easier.

Overview of Oracle9i Java Documentation

This guide is the starting point for Oracle9i Java developers. It outlines some of the unique features of Java programming with Oracle9i, including aspects of the Oracle9i JVM, explaining how to take advantage of these features in your Java programs.

Once you have mastered the basics of Java development within the Oracle9i database, you may need more information for the specific protocol you will use in implementing your Java application. The following list includes other books within the documentation set that will help you in your application development:

Protocol

Description

Book Title

JDBC

Oracle9i Java developers should become familiar with Oracle's Java Database Connectivity (JDBC) product because it provides the basis for accessing SQL data from Java programs, as well as Oracle-specific extensions to this Java standard. JDBC is an industry standard.

You may find it easier to develop Java programs that access SQL data using embedded SQL in Java (SQLJ). SQLJ uses a preprocessor, written in Java, to translate embedded SQL statements to standard JDBC-style programs. SQLJ is an industry standard.

If you are a PL/SQL programmer exploring Java, you will be interested in Java stored procedures. A Java stored procedure is a program you write in Java to execute in the server, exactly as a PL/SQL stored procedure. You invoke it directly with products like SQL*Plus or indirectly with a trigger and can access it from any Oracle Net client--OCI, PRO*, JDBC or SQLJ. The Oracle9i Java Stored Procedures Developer's Guide explains how to write stored procedures in Java, how to access them from PL/SQL, and how to access PL/SQL functionality from Java.

In addition, you can use Java to develop powerful programs independently of PL/SQL. Oracle9i provides a fully compliant implementation of the Java programming language and JVM.