Skip Headers

Oracle® Database Java Developer's Guide
10g Release 1 (10.1)

Part Number B12021-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Feedback

Go to previous page
Previous
Go to next page
Next
View PDF

5
Developing Java Stored Procedures

The OracleJVM has all the features you need to build a new generation of enterprise-wide applications at a low cost. Chief among those features are stored procedures, which open the Oracle RDBMS to all Java programmers. With stored procedures, you can implement business logic at the server level, thereby improving application performance, scalability, and security.

This chapter contains the following information:

Stored Procedures and Run-Time Contexts

Stored procedures are Java methods published to SQL and stored in an Oracle database for general use. To publish Java methods, you write call specifications (call specs for short), which map Java method names, parameter types, and return types to their SQL counterparts.

Unlike a wrapper, which adds another layer of execution, a call spec simply publishes the existence of a Java method. So, when you call the method (through its call spec), the run-time system dispatches the call with minimal overhead.

When called by client applications, a stored procedure can accept arguments, reference Java classes, and return Java result values. Figure 5-1 shows a stored procedure being called by various applications.

Figure 5-1 Calling a Stored Procedure

Text description of call_sto.gif follows.

Text description of the illustration call_sto.gif

Except for graphical-user-interface (GUI) methods, OracleJVM can run any Java method as a stored procedure. The run-time contexts are:

The next three sections describe these contexts.

Functions and Procedures

Functions and procedures are named blocks that encapsulate a sequence of statements. They are like building blocks that you can use to construct modular, maintainable applications.

Generally, you use a procedure to perform an action, and a function to compute a value. So, for void Java methods, you use procedure call specs, and for value-returning methods, you use function call specs.

Only top-level and package (not local) PL/SQL functions and procedures can be used as call specs. When you define them using the SQL CREATE FUNCTION, CREATE PROCEDURE, or CREATE PACKAGE statement, they are stored in the database, where they are available for general use.

Java methods published as functions and procedures must be invoked explicitly. They can accept arguments and are callable from:

Database Triggers

A database trigger is a stored procedure associated with a specific table or view. Oracle invokes (fires) the trigger automatically whenever a given DML operation modifies the table or view.

A trigger has three parts: a triggering event (DML operation), an optional trigger constraint, and a trigger action. When the event occurs, the trigger fires and a CALL statement calls a Java method (through its call spec) to perform the action.

Database triggers, which you define using the SQL CREATE TRIGGER statement, let you customize the RDBMS. For example, they can restrict DML operations to regular business hours. Typically, triggers are used to enforce complex business rules, derive column values automatically, prevent invalid transactions, log events transparently, audit transactions, or gather statistics.

Object-Relational Methods

A SQL object type is a user-defined composite data type that encapsulates a set of variables (attributes) with a set of operations (methods), which can be written in Java. The data structure formed by the set of attributes is public (visible to client programs). However, well-behaved programs do not manipulate it directly. Instead, they use the set of methods provided.

When you define an object type using the SQL CREATE ... OBJECT statement, you create an abstract template for some real-world object. The template specifies only those attributes and behaviors the object will need in the application environment. At run time, when you fill the data structure with values, you create an instance of the object type. You can create as many instances (objects) as necessary.

Typically, an object type corresponds to some business entity such as a purchase order. To accommodate a variable number of items, object types can use variable-length arrays (varrays) and nested tables. For example, this feature enables a purchase order object type to contain a variable number of line items.

Advantages of Stored Procedures

Stored procedures offer several advantages including better performance, higher productivity, ease of use, and increased scalability.

Performance

Stored procedures are compiled once and stored in executable form, so procedure calls are quick and efficient. Executable code is automatically cached and shared among users. This lowers memory requirements and invocation overhead.

By grouping SQL statements, a stored procedure allows them to be executed with a single call. This minimizes the use of slow networks, reduces network traffic, and improves round-trip response time. OLTP applications, in particular, benefit because result-set processing eliminates network bottlenecks.

Additionally, stored procedures enable you to take advantage of the computing resources of the server. For example, you can move computation-bound procedures from client to server, where they will execute faster. Likewise, stored functions called from SQL statements enhance performance by executing application logic within the server.

Productivity and Ease of Use

By designing applications around a common set of stored procedures, you can avoid redundant coding and increase your productivity. Moreover, stored procedures let you extend the functionality of the RDBMS. For example, stored functions called from SQL statements enhance the power of SQL.

You can use the Java integrated development environment (IDE) of your choice to create stored procedures. Then, you can deploy them on any tier of the network architecture. Moreover, they can be called by standard Java interfaces, such as JDBC, and by programmatic interfaces and development tools such as the OCI, Pro*C/C++, and JDeveloper.

This broad access to stored procedures lets you share business logic across applications. For example, a stored procedure that implements a business rule can be called from various client-side applications, all of which can share that business rule. In addition, you can leverage the server's Java facilities while continuing to write applications for your favorite programmatic interface.

Scalability

Stored procedures increase scalability by isolating application processing on the server. In addition, automatic dependency tracking for stored procedures aids the development of scalable applications.

The shared memory facilities of the Shared Server enable Oracle Database to support more than 10,000 concurrent users on a single node. For more scalability, you can use the Oracle Net Services Connection Manager to multiplex Oracle Net Services connections.

Maintainability

Once it is validated, you can use a stored procedure with confidence in any number of applications. If its definition changes, only the procedure is affected, not the applications that call it. This simplifies maintenance and enhancement. Also, maintaining a procedure on the server is easier than maintaining copies on different client machines.

Interoperability

Within the RDBMS, Java conforms fully to the Java Language Specification and furnishes all the advantages of a general-purpose, object-oriented programming language. Also, as with PL/SQL, Java provides full access to Oracle data, so any procedure written in PL/SQL can be written in Java.

PL/SQL stored procedures complement Java stored procedures. Typically, SQL programmers who want procedural extensions favor PL/SQL, and Java programmers who want easy access to Oracle data favor Java.

The RDBMS allows a high degree of interoperability between Java and PL/SQL. Java applications can call PL/SQL stored procedures using an embedded JDBC driver; conversely, PL/SQL applications can call Java stored procedures directly.

Replication

With Oracle Advanced Replication, you can replicate (copy) stored procedures from one Oracle Database instance to another. That feature makes them ideal for implementing a central set of business rules. Once you write them, you can replicate and distribute the stored procedures to work groups and branch offices throughout the company. In this way, you can revise policies on a central server rather than on individual servers.

Security

Security is a large arena that includes network security for the connection, access and execution control of operating system resources or of JVM and user-defined classes, and bytecode verification of imported JAR files from an external source.

Oracle Database uses Java 2 security to protect its Java virtual machine. All classes are loaded into a secure database, so they are untrusted. To access classes and operating system resources, a user needs the proper permissions. Likewise, all stored procedures are secured against other users (to whom you can grant the database privilege EXECUTE).

You can restrict access to Oracle data by allowing users to manipulate the data only through stored procedures that execute with their definer's privileges. For example, you can allow access to a procedure that updates a database table, but deny access to the table itself.

For a full discussion of OracleJVM security, see Chapter 9, "Security For Oracle Database Java Applications".

Java Stored Procedure Configuration

To configure the database to run Java stored procedures, you must decide whether you want the database to run in dedicated server mode or shared server mode.

Java, SQL, or PL/SQL clients, which execute Java stored procedures on the server, connect to the database over a Oracle Net Services connection. For a full description of how to configure this connection, see the Oracle Net Services Administrator's Guide.

Java Stored Procedures Steps

You execute Java stored procedures similarly to PL/SQL. Normally, calling a Java stored procedure is a by-product of database manipulation, because it is usually the result of a trigger or SQL DML call. To invoke a Java stored procedure, you must publish it through a call specification.

Before you can call Java stored procedures, you must load them into the Oracle database and publish them to SQL. Loading and publishing are separate tasks. Many Java classes, referenced only by other Java classes, are never published.

To load Java stored procedures automatically, you use the command-line utility loadjava. It uploads Java source, class, and resource files into a system-generated database table, then uses the SQL CREATE JAVA {SOURCE | CLASS | RESOURCE} statement to load the Java files into the Oracle database. You can upload Java files from file systems, popular Java IDEs, intranets, or the Internet.


Note:

To load Java stored procedures manually, you use CREATE JAVA statements. For example, in SQL*Plus, you can use the CREATE JAVA CLASS statement to load Java class files from local BFILEs and LOB columns into the Oracle database.


This section demonstrates how to develop a simple Java stored procedure. For more examples of a Java stored procedures application, see Chapter 8, "Java Stored Procedures Application Example".

Step 1: Create or Reuse the Java Classes

Use your favorite Java IDE to create classes, or simply reuse existing classes that meet your needs. Oracle's Java facilities support many Java development tools and client-side programmatic interfaces. For example, the OracleJVM accepts programs developed in popular Java IDEs such as Oracle JDeveloper, Symantec Visual Café, and Borland JBuilder.

In the following example, you create the public class Oscar. It has a single method named quote(), which returns a quotation from Oscar Wilde.

public class Oscar {
  // return a quotation from Oscar Wilde
  public static String quote() {
    return "I can resist everything except temptation.";
  }
}

In the following example, using Sun Microsystems's JDK Java compiler, you compile class Oscar on your client workstation:

javac Oscar.java

The compiler outputs a Java binary file--in this case, Oscar.class.

Step 2: Load and Resolve the Java Classes

Using the utility loadjava, you can upload Java source, class, and resource files into an Oracle database, where they are stored as Java schema objects. You can run loadjava from the command line or from an application, and you can specify several options including a resolver.

In the following example, loadjava connects to the database using the default JDBC OCI driver. You must specify the user name and password. By default, class Oscar is loaded into the logon schema (in this case, scott).

> loadjava -user scott/tiger Oscar.class

Later, when you call method quote(), the server uses a resolver (in this case, the default resolver) to search for supporting classes such as String. The default resolver searches first in the current schema, then in schema SYS, where all the core Java class libraries reside. If necessary, you can specify different resolvers.

For more information, see Chapter 2, "Java Applications on Oracle Database".

Step 3: Publish the Java Classes

For each Java method callable from SQL, you must write a call spec, which exposes the method's top-level entry point to Oracle. Typically, only a few call specs are needed, but if you like, Oracle JDeveloper can generate them for you.

In the following example, from SQL*Plus, you connect to the database, then define a top-level call spec for method quote():

SQL> connect scott/tiger

SQL> CREATE FUNCTION oscar_quote RETURN VARCHAR2
  2  AS LANGUAGE JAVA
  3  NAME 'Oscar.quote() return java.lang.String';

For more information, see Chapter 6, "Publishing Java Classes With Call Specs".

Step 4: Call the Stored Procedures

You can call Java stored procedures from SQL DML statements, PL/SQL blocks, and PL/SQL subprograms. Using the SQL CALL statement, you can also call them from the top level (from SQL*Plus, for example) and from database triggers.

In the following example, you declare a SQL*Plus host variable:

SQL> VARIABLE theQuote VARCHAR2(50);

Then, you call the function oscar_quote(), as follows:

SQL> CALL oscar_quote() INTO :theQuote;

SQL> PRINT theQuote;

THEQUOTE
--------------------------------------------------
I can resist everything except temptation.

For more information, see Chapter 7, "Calling Stored Procedures".

Step 5: If Necessary, Debug the Stored Procedures

Your Java stored procedures execute remotely on a server, which typically resides on a separate machine. However, the JDK debugger (jdb) cannot debug remote Java programs. For more information, see "Debugging Server Applications".

Another Example

The following example shows how to create, resolve, load, and publish a simple Java stored procedure that echoes "Hello world."

  1. Write the Java class.

    Define a class, Hello, with one method, Hello.world(), that returns the string "Hello world".

    public class Hello
    {
       public static String world ()
       {
          return "Hello world";
       }
    }
    
    
  2. Compile the class on your client system. Using the Sun Microsystems J2SE, for example, invoke the Java compiler, javac, as follows:
    javac Hello.java
    
    
    

    Normally, it is a good idea to specify your CLASSPATH on the javac command line, especially when writing shell scripts or make files. The Java compiler produces a Java binary file--in this case, Hello.class.

    Keep in mind where this Java code will execute. If you execute Hello.class on your client system, it searches the CLASSPATH for all supporting core classes it must execute. This search should result in locating the dependent class in one of the following:

    • as an individual file in a directory, where the directory is specified in the CLASSPATH
    • within a .jar or .zip file, where the directory is specified in the CLASSPATH
  3. Decide on the resolver for your class.

    In this case, you load Hello.class in the server, where it is stored in the database as a Java schema object. When you execute the world() method of the Hello.class on the server, it finds the necessary supporting classes, such as String, using a resolver--in this case, the default resolver. The default resolver looks for classes in the current schema first and then in PUBLIC. All core class libraries, including the java.lang package, are found in PUBLIC. You may need to specify different resolvers, and you can force resolution to occur when you use loadjava, to determine if there are any problems earlier, rather than at runtime. Refer to Chapter 2, "Java Applications on Oracle Database" for more details on resolvers and loadjava.

  4. Load the class on the Oracle Application Server using loadjava. You must specify the user name and password.
    loadjava -user scott/tiger Hello.class
    
    
    
  5. Publish the stored procedure through a call specification.

    To invoke a Java static method with a SQL CALL, you must publish it with a call specification. A call specification defines for SQL which arguments the method takes and the SQL types it returns.

    In SQL*Plus, connect to the database and define a top-level call specification for Hello.world():

    SQL> connect scott/tiger
    connected
    SQL> create or replace function HELLOWORLD return VARCHAR2 as
      2  language java name 'Hello.world () return java.lang.String';
      3  /
    Function created.
    
    
    
  6. Invoke the stored procedure.
    SQL> variable myString varchar2(20)s;
    SQL> call HELLOWORLD() into :myString;
    Call completed.
    SQL> print myString;
    
    MYSTRING
    ---------------------------------------
    Hello world
    
    SQL>
    
    
    

    The call HELLOWORLD() into :myString statement performs a top-level call in Oracle Database. The Oracle-specific select HELLOWORLD from DUAL also works. Note that SQL and PL/SQL see no difference between a stored procedure that is written in Java, PL/SQL, or any other language. The call specification provides a means to tie inter-language calls together in a consistent manner. Call specifications are necessary only for entry points invoked with triggers or SQL and PL/SQL calls. Furthermore, JDeveloper can automate the task of writing call specifications.