HomeOracle Page 2 - Extending PL/SQL with Java Libraries
Java Architecture in Oracle - Oracle
If you are looking for a way to extend stored programs with Java, look no further. This article, the first of two parts, is excerpted from chapter five of Expert Oracle PL/SQL, written by Ron Hardman and Michael McLaughlin (McGraw-Hill/Osborne, 2005; ISBN: 0072261943).
The Oracle 9i and 10g databases provide a robust architecture for developing server-side or internal Java programming components. Java components are Object-Oriented (OO) structures that fit naturally into Oracle’s Object-Relational model. The component architecture is a library stack that contains
Platform-dependent operating systems, like UNIX, LINUX, and Microsoft Windows
Platform-dependent Oracle database management files and libraries
Oracle database instance Java Virtual Machine, which is platform independent
Java core class libraries, which are ported to various platforms
Oracle-supported Java Application Programming Interfaces (APIs), like SQLJ, JDBC, and JNDI
Oracle PL/SQL stored objects, which provide an interface between SQL and PL/SQL programs, as well as server-side Java classes
The Oracle and Java libraries store and manage application programs like a ubiquitous file system. Together they mask the structures and limitations of operating systems. Oracle libraries make storing, retrieving, and recovering files a standard process across many diverse platforms. The Java Virtual Machine (JVM) provides a standard environment where you can build well-documented OO programs. Oracle PL/SQL enables the development of wrapper packages to access Java libraries from other PL/SQL stored objects and SQL.
The architecture of the Oracle JVM is shown in the following illustration:
Oracle JVM uses two types of namespaces, the long name and short name. The long name is exactly as the class is named in Java. You can call stored Java programs by their native namespace. While the chapter examples are short and not placed into packages, you’ll most likely put your Java programs into packages. The namespace for Java stored code includes the entire package hierarchy. When this is larger than 30 characters, Oracle uses a hashed namespace in the data dictionary views. Use the DBMS_JAVA package and LONGNAME function to get the full namespace. You can also use the DBMS_JAVA package and SHORTNAME function to get the short name.
The JVM enjoys automated storage management, which means you do not need to allocate and free memory explicitly. Also, Java is a strongly typed programming language like PL/SQL. The combination of strong typing and a garbage collector to manage memory provides a scalable and simplified environment like the PL/SQL runtime engine.
Both Java and PL/SQL are interpreted languages and they require Just-In-Time (JIT) compilation. Oracle 9i introduces native compilation for PL/SQL and Java programs. Native compilation enables Ahead-of-Time compilation. It changes PL/SQL and Java byte code into machine-executable programming code.
Native compilation speeds execution by eliminating JIT compilation delay. Unfortunately, it takes time to compile the interpreted languages programs into machine code. If you rarely change your code, the trade-off may be worth using native compilation.
There are three ways to put Oracle into the database instance. Your options are
A two-step process: (a) compiling the Java source file, <file_name> .java, with the javac executable to generate a Java byte code program, and (b) using the Oracle loadjava utility to put the file into the database instance.
A one-step process using the loadjava utility to compile and put the Java class file into the database instance.
A one-step process using Data Definition Language to build and compile the Java source file as a stored Java class.
There are occasionally parser problems in Oracle 9i R1 and using DDL commands to build the Java program can fail. These are fixed in 9i R2 and later versions. Java source files will be compiled and then loaded into the database instance with the loadjava utility in all examples.
If you opt to use the one-steploadjavautility, please note you may encounter an ORA-29533 error for attempting to overwrite the file.The replace option in theloadjava utility does not work in some releases. Use dropjava with the –useroption and the <file_name>.classbefore rerunning theloadjava utility.
This chapter assumes you have a basic familiarity with Java. Basic familiarity means that you can compile and run Java programs. Sample command-line instructions are provided in the chapter examples, but Appendix D provides a basic tutorial as well as Java environment configuration instructions.
Java stored program units are like traditional PL/SQL program units. They are called with either definer’s-rights or invoker’s-rights access from a single session. There are differences between how Java works externally and internally within the Oracle database instance. The differences are qualified in the following:
Execution control differs substantially from native Java. External to the Oracle instance, Java applications contain a main() method, which is invoked to run the program. Java programs internal to the instance do not contain a main() method. Java programs stored in an Oracle instance have two types of behaviors. They are
Java stored programs that serve as packages with functions and procedures are not instantiable classes. All variables and methods for these programs must be static, which means they act as class methods. This fixes their scope as mirrors of PL/SQL packages with functions and procedures. The coding syntax changes as does their accessibility to external Java applications.
Java stored programs that serve as object type body implementations can be instantiable classes. Variables and methods may be static and nonstatic. Unlike external Java classes, they cannot have overriding constructors, only a single default constructor. They are instantiated by implementing the SQLData interface defined in the JDBC2 API, and instantiation involves mapping data types between PL/SQL and Java.
Java classes are stored in clear text, Java byte code, and compressed Java archives externally to the Oracle database instance. Oracle manages these as source, class, and resource Java objects. Schemas contain a JAVA$OPTIONS table, which can be accessed and configured by the DBMS_JAVA package, the SET_COMPILER_OPTION and RESET_ COMPILER_OPTION procedures, or the GET_COMPILER_OPTION function.
User interfaces are not supported for internal Java class files. This means there’s no way to directly display to console or native sound device(s). Sound files can be manipulated from within Oracle, but they do not have access to the native sound devices. Oracle 10g differs slightly from Oracle 9i because it uses Java SDK 1.4.x, which supports Headless AWT.
Internal Oracle Java class names are maintained in two forms. One is the short form that supports standard schema database objects and is limited to 30 characters. When a fully qualified package and class name exceeds the limit, Oracle automatically creates a hashed name as the class short name and stores the long name elsewhere.
The standard Java Class.forName() isn’t supported for internal Oracle Java classes. Oracle 9i and Oracle 10g support the use of multiple resolvers, which locate classes. You can get unexpected results from a search expecting one resolver that runs another.
Operating resources are restricted. You can only alter these as the privileged user SYSDBA. Use the DBMS_JAVA package and GRANT_PERMISSION procedure to open operating resources like file IO.
Java threading works differently for Oracle internal Java classes. The Oracle JVM uses a nonpreemptive threading model. This means that all threads run in a single operating system thread and the Oracle JVM merely switches contexts between threads. Switching context means that the Oracle JVM spawns one thread for a time slice and then another, in a round-robin fashion, until all threads complete.
The version of Oracle that you’re using does dictate which version of the Java Software Development Kit you should use. For simplification, all examples were done using Java SDK 1.3.x, supported in Oracle 9i. They also work in Java SDK 1.4.x.
The Oracle Java Developer’s Guide lists two key error codes, but there are a number of others. Rather than list these error codes, we’ve included a troubleshooting section later in the chapter titled “Troubleshooting Java Class Library Build, Load, Drop, and Use.”
Now that you’ve reviewed the key components of the Oracle Java architecture, in the next section we’ll introduce you to the various JDBC drivers.