# Java Enhancements - Oracle 11g

The Oracle Database 11g JVM now supports J2SE 1.5.See html for a full list of all the features and enhancements.Quite possibly the biggest new feature is the introduction of generics in 1.5.Generics allow you to specify what classes are expected in generic collection classes. Generics are like a compiler hint.

Just-in-Time (JIT) Compiler and Native Compilation

Oracle has included a just-in-time compiler with Oracle Database 11g.This tool detects Java methods that would benefit from being compiled into native code and automatically performs the compilation.

Behind the scenes,it runs as a slave process under the MMON background process.The DBMS_JAVA package has been enhanced with a collection of procedures to compile classes and methods.A helpful set of uncompile procedures will allow you to undo the compilation and allow you to mark the method or class as permanently uncompilable.

JIT compilation is automatically enabled by default and does not need any configuration.To turn off JIT compilation, you can use the ALTER SYSTEM command:

SQL> alter system set java_jit_enabled=FALSE; System altered.

This initialization parameter is dynamically adjustable,so you can reenable JIT using the TRUE flag.There are advantages of using JIT with the database.First, JIT recompiles Java methods when they become invalid. Second, Oracle persists compiled Java methods across database sessions, calls, and instances.

JAR Support

Oracle supports the loading of JAR files into the database as database objects.What this means is although the loadjava program still needs to extract all the classes from the JAR file and create database objects for them,you can specify, via the -jarsasdbobjects option, that the JAR will be loaded as well and that the linkage between the classes and their JAR files will be retained.

In cases where two JARs have the same class name,loadjava also provides the –prependjarnames option to prepend the JAR name to the Java class objects created. In the example, a simple Java program is created, loaded into the database as a JAR,and executed using the DBMS_JAVA.runjava() function:

package hellooracle;
public class Main {
public static void main(String[] args) {
System.out.println("Hello, world");
}
}

Hello, world, of course.This Java class was then compiled, and a JAR named HelloOracle.jar was created. To load it into Oracle,the following command was executed:

The following anonymous block was then executed in SQL*Plus:

set serverouput on
declare
ret varchar2(32000);
begin
dbms_java.set_output(20000);
ret:=dbms_java.runjava(
'-classpath JSERVER_CP/JAR/PRIVATE/SCHEMA/demo/HelloOracle.jar
hellooracle.Main');
DBMS_OUTPUT.PUT_LINE('return: '||ret);
end;

Executing this yields the following:

Hello world return:

The backslash () character is not part of the program; it’s just used to indicate that the argument to runjava() is on a single line.

In the first line of the code, a call to dbms_java.set_output() is called to direct that output from System.out.println() be sent to the dbms_output package.The second line is the actual call to the Java class.

The classpath has a very specific format, which we’ll cover in a bit, but apart from that, the call is just like you would make in a command-line call to java.As you can see from the resulting text, the class was executed as expected.

The JSERVER_CP prefix to the classpath is replaced with the literal text jserver:/CP when the classpath entry is evaluated.The character immediately following the JSERVER_CP is used as the delimiter for the rest of the string. By convention, the / is typically used. There is another prefix string you should be aware of,JSERVER_SCHEMA.This one is replaced by jserver: /CP/ SCHEMA. Table explains what the arguments to these URLs are.

jserver:/CP/<type>/#2/#3/#4/#5

In addition to the ability to load JARs as database objects, the loadjava tool can now load JARs, classes,or resources from an HTTP URL.In the place of a file name, you specify a URL. Table lists the new options to the loadjava program.

Improvements to the dropjava Tool

The dropjava tool has been enhanced to support dropping JARs that were previously loaded with the -jarasresource or -jarsasdbobject option, and you can now specify a list of objects to drop, with loadjava not failing if one or more of the listed objects do not exist. Table lists the new options to dropjava.

Improvements to the ojvmjava Tool

A new option and command, -runjava, and a new command, connect, have been added to the ojvmjava tool.With the new connect command, you can connect to other database users.This is similar to SQL*Plus’s connect command.runjava allows the user to specify whether the database’s JVM or the ojvmjava tool should execute the Java, as the location of the classpath.This is how to use the command-line option -runjava:

ojvmjava ... -runjava [server_file_system]

Within the ojvmjava shell, the usage for the runjava command is as follows:

runjava [on|off|server_file_system]

In the following examples, the “Hello, world” program written earlier will be called from the ojvmjava shell.First,run ojvmjava without a -runjava option.This executes classes from the database.

r11b > ojvmjava -u demo/demo
--OJVMJAVA--
--type "help" at the command line for help message
$java hellooracle.Main Hello, world In this case, the class helloracle.Main was run from the database. Second,run with the -runjava option and Main.class present in the current directory: r11b > ojvmjava -u demo/demo -runjava --OJVMJAVA-- --type "help" at the command line for help message$ java -classpath . hellooracle.Main
Hello, world
runjava call succeeded

The class was run from the file system, and runjava reported that it ran successfully. Third, run with the server_file_system option:

r11b > ojvmjava -u demo/demo -runjava server_file_system
--OJVMJAVA--
--type "help" at the command line for help message
$java -classpath /home/oracle/Java hellooracle.Main Hello, world runjava call succeeded The ojvmtc Tool ojvmtc is a very nice tool that,given a list of classes and a classpath, will resolve all class references.If a class cannot be resolved, ojvmtc can either report the unresolved references or create a JAR containing stub versions of the unresolved classes.These stub versions throw a java.lang.ClassNotfoundException if they are called at runtime.In the following example, ojvmtc is called on a class as follows,where packB.SwingThings is not found in the classpath: The program returns the following message: The following classes could not be found: packB/SwingThings Execute ojvmtc again, but specify a JAR file to hold all classes in this closure set. The closure set is composed of all the classes specified on the command line and all classes generated as stubs by ojvmtc: ojvmtc -jar rep.jar -server thin:demo/demo@localhost:1521:r11b Main.class The set is not closed 1 classes are missing generating stub classes generating: packB/SwingThings Checking out the contents of the newly created rep.jar shows the following: r11b > jar tf rep.jar packA/Main.class packB/SwingThings.class nov12.novara-labs.com:/home/oracle/Java/ojvmtc/run The program added all referenced classes and JARs (packA/Main.class) as well as created a stub class (packB/SwingThings.class).rep.jar is loaded to the database using loadjava: r11b > loadjava -u demo/demo -jarsasdbobjects rep.jar nov12.novara-labs.com:/home/oracle/Java/ojvmtc/run r11b > ojvmjava -u demo/demo --OJVMJAVA-- --type "help" at the command line for help message Invoking Main results in the following error:$ java packA/Main
Hello
java.lang.NoClassDefFoundError: !!!ERROR!!! generated by genmissing
at packB.SwingThings.<clinit>(Unknown Source)
at packA.Main.main(Main.java:6)

The last three lines show the exception that’s thrown when one of the stub classes is referenced.The generated stub classes are useful in cases where you are loading a class library that makes references to other libraries that are not needed and will not be loaded in the database.

An example would be a statistics package that includes a graphics subsystem.In your usage of this library, you are interested only in time-series calculations, and you have no use for the graphics portion of the library.The generated stub routines allow you to load the statistics library and avoid having to write the stubs yourself.