Skip Headers

Oracle9i Java Stored Procedures Developer's Guide
Release 2 (9.2)

Part Number A96659-01
Go To Documentation Library
Go To Product List
Book List
Go To Table Of Contents
Go To Index

Master Index


Go to previous page Go to next page

Loading Java Classes

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.


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.

Java in the Database

To make Java files available to the Oracle JVM, you must load them into the Oracle database as schema objects. As Figure 2-1 illustrates, loadjava can invoke the JVM's Java compiler, which compiles source files into standard class files.

The figure also shows that loadjava can set the values of options stored in a system database table. Among other things, these options affect the processing of Java source files.

Figure 2-1 Loading Java into the Oracle Database

Text description of loading_.gif follows
Text description of the illustration loading_.gif

Each Java class is stored as a schema object. The name of the object is derived from the fully qualified name (full name) of the class, which includes the names of containing packages. For example, the full name of class Handle is:


In the name of a Java schema object, slashes replace dots, so the full name of the class becomes:


The Oracle RDBMS accepts Java names up to 4000 characters long. However, the names of Java schema objects cannot be longer than 30 characters, so if a name is longer than that, the system generates an alias (short name) for the schema object. Otherwise, the full name is used. You can specify the full name in any context that requires it. When needed, name mapping is handled by the RDBMS.

Java Code, Binaries, and Resources Storage

In the Sun Microsystems Java development environment, Java source code, binaries, and resources are stored as files in a file system.

In addition, when you execute Java, you specify a CLASSPATH, which is a set of a file system tree roots containing your files. Java also provides a way to group these files into a single archive form--a ZIP or JAR file.

Both of these concepts are different within the database. The following describes how Oracle9i handles Java classes and locates dependent classes:

Java code, binaries, and resources

In the Oracle JVM environment, source, classes, and resources reside within the Oracle9i database. Because they reside in the database, they are known as Java schema objects, where a schema corresponds to a database user. There are three types of Java objects: source, class, and resource. There are no .java, .class, .sqlj, .properties, or .ser files on the server; instead, these files map to source, class, and resource Java schema objects.

Locating Java classes

Instead of a CLASSPATH, you use a resolver to specify one or more schemas to search for source, class, and resource Java schema objects.

The call and session terms, used during our discussions, are not Java terms; but are server terms that apply to the Oracle JVM platform. The Oracle memory manager preserves Java program state throughout your session (that is, between calls). The JVM uses the Oracle database to hold Java source, classes, and resources within a schema--Java schema objects. You can use a resolver to specify how Java, when executed in the server, locates source code, classes, and resources.

Preparing Java Class Methods for Execution

For your Java methods to be executed, you must do the following:

  1. Decide when your source is going to be compiled.
  2. Decide if you are going to use the default resolver or another resolver for locating supporting Java classes within the database.
  3. Load the classes into the database. If you do not wish to use the default resolver for your classes, you should specify a separate resolver on the load command.
  4. Publish your class or method.

Compiling Java Classes

Compilation of your source can be performed in one of the following ways:

Compiling Source Through javac

You can compile your Java with a conventional Java compiler, such as javac. After compilation, you load the compiled binary into the database, rather than the source itself. This is a better option, because it is normally easier to debug your Java code on your own system, rather than debugging it on the database.

Compiling Source Through loadjava

When you specify the -resolve option on loadjava for a source file, the following occurs:

  1. The source file is loaded as a source schema object.
  2. The source file is compiled.
  3. Class schema objects are created for each class defined in the compiled .java file.
  4. The compiled code is stored in the class schema objects.

Oracle9i logs all compilation errors both to loadjava's logfile and the USER_ERRORS view. For more information on the USER_ERRORS view.

Compiling Source at Runtime

When you load the Java source into the database without the -resolve option, Oracle9i compiles the source automatically when the class is needed during runtime. The source file is loaded into a source schema object.

Oracle9i logs all compilation errors both to loadjava's logfile and the USER_ERRORS view.

Specifying Compiler Options

There are two ways to specify options to the compiler.

The following sections describe your compiler options:

Default Compiler Options

When compiling a source schema object for which there is neither a JAVA$OPTIONS entry nor a command line value for an option, the compiler assumes a default value as follows:

Compiler Options on the Command Line

The loadjava compiler option, encoding, identifies the encoding of the .java file. This option overrides any matching value in the JAVA$OPTIONS table. The values are identical to the javac -encoding option. This option is relevant only when loading a source file.

Compiler Options Specified in a Database Table

Each JAVA$OPTIONS row contains the names of source schema objects to which an option setting applies; you can use multiple rows to set the options differently for different source schema objects.

You can set JAVA$OPTIONS entries by means of the following functions and procedures, which are defined in the database package DBMS_JAVA:

The parameters for these methods are described as follows:


The name parameter is a Java package name, a fully qualified class name, or the empty string. When the compiler searches the JAVA$OPTIONS table for the options to use for compiling a Java source schema object, it uses the row whose name most closely matches the schema object's fully qualified class name. A name whose value is the empty string matches any schema object name.


The option parameter is either 'online', 'encoding' or 'debug'. For the values you can specify for these options, see the Oracle9i SQLJ Developer's Guide and Reference.

A schema does not initially have a JAVA$OPTIONS table. To create a JAVA$OPTIONS table, use the DBMS_JAVA package's java.set_compiler_option procedure to set a value. The procedure will create the table if it does not exist. Specify parameters in single quotes. For example:

SQL> execute dbms_java.set_compiler_option('x.y', 'online', 'false');

Table 2-1 represents a hypothetical JAVA$OPTIONS database table. The pattern match rule is to match as much of the schema name against the table entry as possible. The schema name with a higher resolution for the pattern match is the entry that applies. Because the table has no entry for the encoding option, the compiler uses the default or the value specified on the command line. The online option shown in the table matches schema object names as follows:

Automatic Recompilation

Oracle9i provides a dependency management and automatic build facility that will transparently recompile source programs when you make changes to the source or binary programs upon which they depend. Consider the following cases:

public class A
      B b;
      public void assignB () {b = new B()}
public class B
      C c;
      public void assignC () {c = new C()}
public class C
      A a;
      public void assignA () {a = new A()}

The system tracks dependencies at a class level of granularity. In the preceding example, you can see that classes A, B, and C depend on one another, because A holds an instance of B, B holds an instance of C, and C holds an instance of A. If you change the definition of class A by adding a new field to it, the dependency mechanism in Oracle9i flags classes B and C as invalid. Before you use any of these classes again, Oracle9i attempts to resolve them again and recompile, if necessary. Note that classes can be recompiled only if source is present on the server.

The dependency system enables you to rely on Oracle9i to manage dependencies between classes, to recompile, and to resolve automatically. You must force compilation and resolution yourself only if you are developing and you want to find problems early. The loadjava utility also provides the facilities for forcing compilation and resolution if you do not want to allow the dependency management facilities to perform this for you.

Resolving Class Dependencies

Many Java classes contain references to other classes, which is the essence of reusing code. A conventional Java virtual machine searches for classes, ZIP, and JAR files within the directories specified in the CLASSPATH. In contrast, the Oracle Java virtual machine searches database schemas for class objects. With Oracle, you load all Java classes within the database, so you might need to specify where to find the dependent classes for your Java class within the database.

All classes loaded within the database are referred to as class schema objects and are loaded within certain schemas. All JVM classes, such as java.lang.*, are loaded within PUBLIC. If your classes depend upon other classes you have defined, you will probably load them all within your own schema. For example, if your schema is SCOTT, the database resolver (the database replacement for CLASSPATH) searches the SCOTT schema before PUBLIC. The listing of schemas to search is known as a resolver spec. Resolver specs are for each class, whereas in a classic Java virtual machine, CLASSPATH is global to all classes.

When locating and resolving the interclass dependencies for classes, the resolver marks each class as valid or invalid, depending on whether all interdependent classes are located. If the class that you load contains a reference to a class that is not found within the appropriate schemas, the class is listed as invalid. Unsuccessful resolution at runtime produces a "class not found" exception. Furthermore, runtime resolution can fail for lack of database resources if the tree of classes is very large.


As with the Java compiler, loadjava resolves references to classes, but not to resources. Be sure to correctly load the resource files that your classes need.

For each interclass reference in a class, the resolver searches the schemas specified by the resolver spec for a valid class schema object that satisfies the reference. If all references are resolved, the resolver marks the class valid. A class that has never been resolved, or has been resolved unsuccessfully, is marked invalid. A class that depends on a schema object that becomes invalid is also marked invalid.

To make searching for dependent classes easier, Oracle provides a default resolver and resolver spec that searches first the definer's schema and then PUBLIC. This covers most of the classes loaded within the database. However, if you are accessing classes within a schema other than your own or PUBLIC, you must define your own resolver spec.

The -resolver option specifies the objects to search within the schemas defined. In the previous example, all class schema objects are searched within SCOTT, OTHER, and PUBLIC. However, if you wanted to search for only a certain class or group of classes within the schema, you could narrow the scope for the search. For example, to search only for the classes "my/gui/*" within the OTHER schema, you would define the resolver spec as follows:

loadjava -resolve -resolver '((* SCOTT) ("my/gui/*" OTHER) (* PUBLIC))'

The first parameter within the resolver spec is for the class schema object; the second parameter defines the schema within which to search for these class schema objects.

Allowing References to Non-Existent Classes

You can specify a special option within a resolver spec that allows an unresolved reference to a non-existent class. Sometimes, internal classes are never used within a product. For example, some ISVs do not remove all references to internal test classes from the JAR file before shipping. In a normal Java environment, this is not a problem, because as long as the methods are not called, the Sun Microsystems JVM ignores them. However, the Oracle9i resolver tries to resolve all classes referenced within the JAR file--even unused classes. If the reference cannot be validated, the classes within the JAR file are marked as invalid.

To ignore references, you can specify the "-" wildcard within the resolver spec. The following example specifies that any references to classes within "my/gui" are to be allowed, even if it is not present within the resolver spec schema list.

loadjava -resolve -resolver '((* SCOTT) (* PUBLIC) ("my/gui/*" -))'

In addition, you can define that all classes not found are to be ignored. Without the wildcard, if a dependent class is not found within one of the schemas, your class is listed as invalid and cannot be run. However, this is also dangerous, because if there is a dependent class on a used class, you mark a class as valid that can never run without the dependent class. In this case, you will receive an exception at runtime.

To ignore all classes not found within SCOTT or PUBLIC, specify the following resolver spec:

loadjava -resolve -resolver "((* SCOTT) (* PUBLIC) (* -))"


Never use a resolver containing "-" if you later intend to load the classes that were causing you to use such a resolver in the first place. Instead, include all referenced classes in the schema before resolving.

ByteCode Verifier

According to the JVM specification, .class files are subject to verification before the class they define is available in a JVM. In Oracle JVM, the verification process occurs at class resolution. The resolver might find one of the following problems and issue the appropriate Oracle error code:


If the resolver determines that the class is malformed, the resolver does not mark it valid. When the resolver rejects a class, it issues an ORA-29545 error (badly formed class). The loadjava tool reports the error. For example, this error is thrown if the contents of a .class file are not the result of a Java compilation or if the file has been corrupted.


In some situations, the resolver allows a class to be marked valid, but will replace bytecodes in the class to throw an exception at runtime. In these cases, the resolver issues an ORA-29552 (verification warning), which loadjava will report. The loadjava tool issues this warning when the Java Language Specification would require an IncompatibleClassChangeError be thrown. Oracle JVM relies on the resolver to detect these situations, supporting the proper runtime behavior that the JLS requires.

The resolver also issues the following warnings:

For more information on class resolution and loading your classes within the database, see the Oracle9i Java Developer's Guide.

Loading Classes

This section gives an overview of loading your classes into the database using the loadjava tool. You can also execute loadjava within your SQL. See the Oracle9i Java Developer's Guide for complete information on loadjava.

Unlike a conventional Java virtual machine, which compiles and loads from files, the Oracle Java virtual machine compiles and loads from database schema objects.

.java source files or
.sqlj source files

correspond to Java source schema objects

.class compiled Java files

correspond to Java class schema objects

.properties Java resource files,
.ser SQLJ profile files, or data files

correspond to Java resource schema objects

You must load all classes or resources into the database to be used by other classes within the database. In addition, at loadtime, you define who can execute your classes within the database.

The loadjava tool performs the following for each type of file:

Schema Object loadjava Operations on Object

.java source files

  1. It creates a source schema object within the definer's schema unless another schema is specified.
  2. It loads the contents of the source file into a schema object.
  3. It creates a class schema object for all classes defined in the source file.
  4. If -resolve is requested, it does the following:

    a. It compiles the source schema object.

    b. It resolves the class and its dependencies.

    c. It stores the compiled class into a class schema object.

.sqlj source files

  1. It creates a source schema object within the definer's schema unless another schema is specified.
  2. It loads contents of the source file into the schema object.
  3. It creates a class schema object for all classes and resources defined in the source file.
  4. If -resolve is requested, it does the following:

    a. It translates and compiles the source schema object.

    b. It stores the compiled class into a class schema object.

    c. It stores the profile into a .ser resource schema object and customizes it.

.class compiled Java files

  1. It creates a class schema object within the definer's schema unless another schema is specified.
  2. It loads the class file into the schema object.
  3. It resolves and verifies the class and its dependencies if -resolve is specified.

.properties Java resource files

  1. It creates a resource schema object within the definer's schema unless another schema is specified.
  2. It loads a resource file into a schema object.

.ser SQLJ profile

  1. It creates a resource schema object within the definer's schema unless another schema is specified.
  2. It loads the .ser resource file into a schema object and customizes it.

The dropjava tool performs the reverse of the loadjava tool: it deletes schema objects that correspond to Java files. Always use dropjava to delete a Java schema object created with loadjava. Dropping with SQL DDL commands will not update auxiliary data maintained by loadjava and dropjava. You can also execute dropjava from within SQL commands.


More options for loadjava are available. However, this section discusses only the major options. See the Oracle9i Java Developer's Guide for complete information on loadjava and dropjava.

You must abide by certain rules, which are detailed in the following sections, when loading classes into the database:

After loading, you can access the USER_OBJECTS view in your database schema to verify that your classes and resources loaded properly. For more information, see "Checking Java Uploads".

Defining the Same Class Twice

You cannot have two different definitions for the same class. This rule affects you in two ways:

Designating Database Privileges and JVM Permissions

You must have the following SQL database privileges to load classes:

Loading JAR or ZIP Files

The loadjava tool accepts .class, .java, .properties, .sqlj, .ser, .jar, or .zip files. The JAR or ZIP files can contain source, class, and data files. When you pass loadjava a JAR or ZIP file, loadjava opens the archive and loads its members individually. There is no JAR or ZIP schema object. If the JAR or ZIP content has not changed since the last time it was loaded, it is not reloaded; therefore, there is little performance penalty for loading JAR or ZIP files. In fact, loading JAR or ZIP files is the simplest way to use loadjava.


Oracle does not reload a class if it has not changed since the last load. However, you can force a class to be reloaded through the loadjava -force option.

How to Grant Execute Rights

If you load all classes within your own schema and do not reference any class outside of your schema, you already have execution rights. You have the privileges necessary for your objects to invoke other objects loaded in the same schema. That is, the ability for class A to invoke class B. Class A must be given the right to invoke class B.

The classes that define a Java application are stored within the Oracle9i RDBMS under the SQL schema of their owner. By default, classes that reside in one user's schema are not executable by other users, because of security concerns. You can allow other users (schemas) the right to execute your class through the loadjava -grant option. You can grant execution rights to a certain user or schema. You cannot grant execution rights to a role, which includes the super-user DBA role. The setting of execution rights is the same as used to grant or revoke privileges in SQL DDL statements.

Figure 2-2 Execution Rights

Text description of 02_load2.gif follows
Text description of the illustration 02_load2.gif

Checking Java Uploads

You can query the database view USER_OBJECTS to obtain information about schema objects--including Java sources, classes, and resources--that you own. This allows you, for example, to verify that sources, classes, or resources that you load are properly stored into schema objects.

Columns in USER_OBJECTS include those contained in Table 2-2.

Table 2-2 Key USER_OBJECT Columns  
Name Description


name of the object


type of the object (such as JAVA SOURCE, JAVA CLASS, or JAVA RESOURCE)


status of the object (VALID or INVALID) (always VALID for JAVA RESOURCE)

Object Name and Type

An OBJECT_NAME in USER_OBJECTS is the short name. The full name is stored as a short name if it exceeds 31 characters. See "Shortened Class Names" for more information on full and short names.

If the server uses a short name for a schema object, you can use the LONGNAME() routine of the server DBMS_JAVA package to receive it from a query in full name format, without having to know the short name format or the conversion rules.

SQL*Plus> SELECT dbms_java.longname(object_name) FROM user_objects 
          WHERE object_type='JAVA SOURCE';

This routine shows you the Java source schema objects in full name format. Where no short name is used, no conversion occurs, because the short name and full name are identical.

You can use the SHORTNAME() routine of the DBMS_JAVA package to use a full name as a query criterion, without having to know whether it was converted to a short name in the database.

SQL*Plus> SELECT object_type FROM user_objects 
          WHERE object_name=dbms_java.shortname('known_fullname');

This routine shows you the OBJECT_TYPE of the schema object of the specified full name. This presumes that the full name is representable in the database character set.

SVRMGR> select * from javasnm;
SHORT                          LONGNAME
/78e6d350_BinaryExceptionHandl sun/tools/java/BinaryExceptionHandler
/b6c774bb_ClassDeclaration     sun/tools/java/ClassDeclaration
/af5a8ef3_JarVerifierStream1   sun/tools/jar/JarVerifierStream$1


STATUS is a character string that indicates the validity of a Java schema object. A source schema object is VALID if it compiled successfully; a class schema object is VALID if it was resolved successfully. A resource schema object is always VALID, because resources are not resolved.

Example: Accessing USER_OBJECTS

The following SQL*Plus script accesses the USER_OBJECTS view to display information about uploaded Java sources, classes, and resources.

COL object_name format a30
COL object_type format a15
SELECT object_name, object_type, status
   FROM user_objects
   ORDER BY object_type, object_name;

You can optionally use wildcards in querying USER_OBJECTS, as in the following example.

SELECT object_name, object_type, status
   FROM user_objects
   WHERE object_name LIKE '%Alerter';

This routine finds any OBJECT_NAME entries that end with the characters: Alerter.

User Interfaces on the Server

Oracle9i furnishes all core Java class libraries on the server, including those associated with presentation of user interfaces (java.awt and java.applet). It is, however, inappropriate for code executing in the server to attempt to bring up or materialize a user interface in the server. Imagine thousands of users worldwide exercising an Internet application that executes code that requires someone to click a dialog presented on the server hardware. You can write Java programs that reference and use java.awt classes as long as you do not attempt to materialize a user interface.

When building applets, you test them using the java.awt and the Peer implementation, which is a platform-specific set of classes for support of a specific windowing system. When the user downloads an applet, it dynamically loads the proper client Peer libraries, and the user sees a display appropriate for the operating system or windowing system in use on the client side. Oracle9i takes the same approach. We provide an Oracle-specific Peer implementation that throws an exception, oracle.aurora.awt.UnsupportedOperation, if you execute Java code on the Oracle9i server that attempts to materialize a user interface.

Oracle9i's lack of support for materializing user interfaces in the server means that we do not pass the Java 2 Compatibility Kit tests for java.awt, java.awt.manual, and java.applet. In the Oracle RDBMS, all user interfaces are supported only on client applications, although they might be displayed on the same physical hardware that supports the server--for example, in the case of Windows NT. Because it is inappropriate for the server to support user interfaces, we exclude these tests from our complete Java Compatibility Kit testing.

A similar issue exists for vendors of Java-powered embedded devices and in handheld devices (known as Personal Java). Future releases of Java and the Java Compatibility Kit will provide improved factorization of user interface support so that vendors of Java server platforms can better address this issue.

Shortened Class Names

Each Java source, class, and resource is stored in its own schema object in the server. The name of the schema object is derived from the fully qualified name, which includes relevant path or package information. Dots are replaced by slashes. These fully qualified names (with slashes)--used for loaded sources, loaded classes, loaded resources, generated classes, and generated resources--are referred to in this chapter as schema object full names.

Schema object names, however, have a maximum of only 31 characters, and all characters must be legal and convertible to characters in the database character set. If any full name is longer than 31 characters or contains illegal or non-convertible characters, the Oracle9i server converts the full name to a short name to employ as the name of the schema object, keeping track of both names and how to convert between them. If the full name is 31 characters or less and has no illegal or inconvertible characters, then the full name is used as the schema object name.

Because Java classes and methods can have names exceeding the maximum SQL identifier length, Oracle9i uses abbreviated names internally for SQL access. Oracle9i provides a method within the DBMS_JAVA package for retrieving the original Java class name for any truncated name.


This function returns the longname from a Java schema object. An example is to print the fully qualified name of classes that are invalid for some reason.

select dbms_java.longname (object_name) from user_objects 
   where object_type = 'JAVA CLASS' and status = 'INVALID';

In addition, you can specify a full name to the database by using the shortname() routine of the DBMS_JAVA package, which takes a full name as input and returns the corresponding short name. This is useful when verifying that your classes loaded by querying the USER_OBJECTS view.


Controlling the Current User

During execution of Java or PL/SQL, there is always a current user. Initially, this is the user who creates the session.

Invoker's and definer's rights is a SQL concept that is used dynamically when executing SQL, PL/SQL, or JDBC. The current user controls the interpretation of SQL and determines privileges. For example, if a table is referenced by a simple name, it is assumed that the table belongs in the user's schema. In addition, the privileges that are checked when resources are requested are based on the privileges granted to the current user.

In addition, for Java stored procedures, the call specifications use a PL/SQL wrapper. So, you could specify definer's rights on either the call specification or on the Java class itself. If either is redefined to definer's rights, then the called method executes under the user that deployed the Java class.

By default, Java stored procedures execute without changing the current user--that is, with the privileges of their invoker, not their definer. Invoker-rights procedures are not bound to a particular schema. Their unqualified references to schema objects (such as database tables) are resolved in the schema of the current user, not the definer.

On the other hand, definer-rights procedures are bound to the schema in which they reside. They execute with the privileges of their definer, and their unqualified references to schema objects are resolved in the schema of the definer.

Invoker-rights procedures let you reuse code and centralize application logic. They are especially useful in applications that store data in different schemas. In such cases, multiple users can manage their own data using a single code base.

Consider a company that uses a definer-rights procedure to analyze sales. To provide local sales statistics, the procedure analyze must access sales tables that reside at each regional site. To do so, the procedure must also reside at each regional site. This causes a maintenance problem.

To solve the problem, the company installs an invoker-rights (IR) version of the procedure analyze at headquarters. Now, as Figure 2-3 shows, all regional sites can use the same procedure to query their own sales tables.

Figure 2-3 Invoker-Rights Solution

Text description of invoker_.gif follows
Text description of the illustration invoker_.gif

Occasionally, you might want to override the default invoker-rights behavior. Suppose headquarters would like the procedure analyze to calculate sales commissions and update a central payroll table. That presents a problem because invokers of analyze should not have direct access to the payroll table, which stores employee salaries and other sensitive data. As Figure 2-4 shows, the solution is to have procedure analyze call the definer-rights (DR) procedure calcComm, which, in turn, updates the payroll table.

Figure 2-4 Indirect Access

Text description of controll.gif follows
Text description of the illustration controll.gif

To override the default invoker-rights behavior, specify the loadjava option -definer, which is similar to the UNIX facility setuid, except that -definer applies to individual classes, not whole programs. Alternatively, you can execute the SQL DDL that changes the AUTHID of the current user.

Different definers can have different privileges, and applications can consist of many classes. So, use the option -definer carefully, making sure that classes have only the privileges they need.

Go to previous page Go to next page
Copyright © 2000, 2002 Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Go To Product List
Book List
Go To Table Of Contents
Go To Index

Master Index