Oracle9i SQLJ Developer's Guide and Reference
Release 1 (9.0.1)

Part Number A90212-01
Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

11
SQLJ in the Server

SQLJ applications can be stored and run directly in the server. You have the option of either translating and compiling them on a client and loading the generated classes and resources into the server, or loading SQLJ source code into the server and having it translated and compiled by the server's embedded translator.

This chapter discusses features and usage of SQLJ in the server, including additional considerations such as multithreading and recursive SQLJ calls.

Most of this chapter assumes you are writing stored procedures or stored functions, but additional vehicles such as Enterprise JavaBeans or CORBA objects are supported as well.

The following topics are discussed:

Introduction to Server-Side SQLJ

SQLJ code, as with any Java code, can run in Oracle9i in stored procedures, stored functions, triggers, Enterprise JavaBeans, or CORBA objects. Data access is through a server-side implementation of the SQLJ runtime (with all SQLJ runtime packages automatically available) in combination with the Oracle JDBC server-side internal driver. (You will sometimes hear this referred to as the "KPRB driver".)

In addition, an embedded SQLJ translator in Oracle9i is available to translate SQLJ source files directly in the server.

Considerations for running SQLJ in the server include several server-side coding issues as well as decisions about where to translate your code and how to load it into the server. You must also be aware of how the server determines the names of generated output. You can either translate and compile on a client and load the class and resource files into the server, or you can load .sqlj source files into the server and have the files automatically translated by the embedded SQLJ translator.

The embedded translator has a different user interface than the client-side translator. Supported options can be specified using a database table, and error output is to a database table. Output files from the translator (.java and .ser) are transparent to the developer.

Creating SQLJ Code for Use within the Server

With few exceptions, writing SQLJ code for use within the target Oracle9i database or middle-tier database cache is identical to writing SQLJ code for client-side use. The few differences are due to Oracle JDBC characteristics or general Java characteristics in the server, rather than being specific to SQLJ. There are a few things to be aware of, however:

Database Connections within the Server

The concept of connecting to a server is different when your SQLJ code is running within this server itself--there is no explicit database connection. By default, an implicit channel to the database is employed for any Java program running in the server. You do not have to initialize this "connection"--it is automatically initialized for SQLJ programs. You do not have to register or specify a driver, create a connection instance, specify a default connection context, specify any connection objects for any of your #sql statements, or close the connection.


Note:

In the server, setting the default connection context to null, as follows, will reinstall the default connection context (the implicit connection to the server):

DefaultContext.setDefaultContext(null);
 

Coding Issues within the Server

There are a few coding issues to consider when your code will run within the target server using the server-side internal driver. Note the following:

For more information about server-side JDBC and the server-side internal and Thin drivers, see the Oracle9i JDBC Developer's Guide and Reference.

Default Output Device in the Server

The default standard output device in the Oracle Java virtual machine (JVM) is the current trace file.

If you want to reroute all standard output from a program executing in the server (output from any System.out.println() calls, for example) to a user screen, then you can execute the SET_OUTPUT() procedure of the DBMS_JAVA package, as follows (inputting the buffer size in bytes):

sqlplus> execute dbms_java.set_output(10000);

(Output exceeding the buffer size will be lost.)

If you want your code executing in the server to expressly output to the user screen, you can also use the PL/SQL DBMS_OUTPUT.PUT_LINE() procedure instead of the Java System.out.println() method.

The PUT_LINE() procedure is overloaded, accepting either VARCHAR2, NUMBER, or DATE as input to specify what is printed.

For more information about the DBMS_OUTPUT package, see the Oracle9i Supplied PL/SQL Packages and Types Reference.

Name Resolution in the Server

Class loading and name resolution in the server follow a very different paradigm than on a client, because the environments themselves are very different. This section gives only an overview; the topic is discussed in detail in the Oracle9i Java Developer's Guide.

Java name resolution in the Oracle JVM includes the following:

A class schema object is said to be resolved when all of its external references to Java names are bound. In general, all the classes of a Java program should be compiled or loaded before they can be resolved. (This is because Java programs are typically written in multiple source files that can reference each other recursively.)

When all the class schema objects of a Java program in the server are resolved and none of them have been modified since being resolved, the program is effectively pre-linked and ready to run.

A class schema object must be resolved before Java objects of the class can be instantiated or methods of the class can be executed.


Note:

The loadjava utility resolves references to classes, but not to resources. If you translated on the client, be careful how you load any resources into resource schema objects in the server, as discussed in "Loaded Class and Resource Schema Objects". (If you enabled the SQLJ -ser2class flag for your client-side translation, then your SQLJ profiles will be in class files, and you will typically not have any resource files. If you did not enable -ser2class, then your profiles will be in .ser resource files.) 


SQL Names Versus Java Names

SQL names (such as names of source, class, and resource schema objects) are not global in the way that Java names are global. The Java Language Specification directs that package names use Internet naming conventions to create globally unique names for Java programs. By contrast, a fully qualified SQL name is interpreted only with respect to the current schema and database. For example, the name SCOTT.FIZZ in one database does not necessarily denote the same program as SCOTT.FIZZ in another database. In fact, SCOTT.FIZZ in one database can even call SCOTT.FIZZ in another database.

Because of this inherent difference, SQL names must be interpreted and processed differently from Java names. SQL names are relative names and are interpreted from the point of view of the schema where a program is executed. This is central to how the program binds local data stored at that schema. Java names are global names, and the classes that they designate can be loaded at any execution site, with reasonable expectation that those classes will be classes that were used to compile the program.

Translating SQLJ Source on a Client and Loading Components

One approach to developing SQLJ code for the server is to first run the SQLJ translator on a client machine to take care of translation, compilation, and profile customization. Then load the resulting class and resource files (including your SQLJ profiles) into the server, typically using a Java archive (.jar) file.

If you are developing your source on a client machine, as is usually the case, and have a SQLJ translator available there, this approach is advisable. It allows the most flexibility in running the translator, because option-setting and error-processing are not as convenient in the server.

It might also be advisable to use the SQLJ -ser2class option during translation when you intend to load an application into the server. This results in SQLJ profiles being converted from .ser serialized resource files to .class files and simplifies their naming. Be aware, however, that profiles converted to .class files cannot be further customized. To further customize, you would have to rerun the translator and regenerate the profiles. For information about the -ser2class option, see "Conversion of .ser File to .class File (-ser2class)".

When you load .class files and .ser resource files into Oracle9i, either directly or using a .jar file, the resulting library units are referred to as Java class schema objects (for Java classes) and Java resource schema objects (for Java resources). Your SQLJ profiles will be in resource schema objects if you load them as .ser files, or in class schema objects if you enabled -ser2class during translation and load them as .class files.

Loading Classes and Resources into the Server

Once you run the translator on the client, use the Oracle loadjava client-side utility to load class and resource files into schema objects in the server. This utility is discussed in detail in the Oracle9i Java Developer's Guide.

Either specify the class and resource files individually on the loadjava command line, or put them into a .jar file and specify the .jar file on the command line. A separate schema object is created for each .class or .ser file in the .jar file or on the command line.

Consider an example where you do the following:

  1. Translate and compile Foo.sqlj, which includes an iterator declaration for MyIter, using standard SQLJ code generation.

  2. Enable the -ser2class option when you translate Foo.sqlj.

  3. Archive the resulting files (Foo.class, MyIter.class, Foo_SJProfileKeys.class, and Foo_SJProfile0.class) into Foo.jar.

Then run loadjava with the following command line (plus any options you want to specify). This examples uses the default OCI driver:

loadjava -user scott/tiger Foo.jar

Or, alternatively, use the original files:

loadjava -user scott/tiger Foo.class MyIter.class Foo_SJProfileKeys.class Foo_SJProfile0.class

or:

loadjava -user scott/tiger Foo*.class MyIter.class

Or, to use the Thin driver for loading (specifying the -thin option and an appropriate URL):

loadjava -thin -user scott/tiger@localhost:1521:ORCL Foo.jar

For information about files generated by the SQLJ translator, see "Code Generation" and "Java Compilation".


Notes:

  • When you load a profile into the server as a .ser file, it is first customized if it was not already customized on the client. If it was already customized, it is loaded as is.

  • You can access the USER_OBJECTS view in your schema to verify that your classes and resources are loaded properly. This is discussed in the Oracle9i Java Developer's Guide.

 

Although the loadjava utility is recommended for loading your SQLJ and Java applications into the server, you can also use Oracle SQL CREATE JAVA commands such as the following:

CREATE OR REPLACE <AND RESOLVE> JAVA CLASS <NAMED name>;

CREATE OR REPLACE JAVA RESOURCE <NAMED name>;

See the Oracle9i SQL Reference for more information about the CREATE JAVA commands.

Loaded Class and Resource Schema Objects

This section discusses how schema objects for classes and profiles are named when you load classes and profiles into the server.


Note:

Any discussion of profiles assumes you translated your code with standard SQLJ code generation. If you use Oracle-specific code generation, through the SQLJ translator -codegen=oracle setting, then SQLJ produces no profile files. 


If the SQLJ -ser2class option was enabled when you translated your application on the client, then profiles were converted to .class files and will be loaded into class schema objects in the server. If -ser2class was not enabled, then profiles were generated as .ser serialized resource files and will be loaded into resource schema objects in the server.

In the following discussion, it is assumed that you use only the default connection context class for any application that will run in the server; therefore, there will be only one profile.


Note:

There are two forms of schema object names in the server: full names and short names.

Full names are fully qualified and are used as the schema object names wherever possible. If any full name is longer than 31 characters, however, or contains characters that are illegal or cannot be converted to characters in the database character set, then Oracle9i 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.

For more information about these and about other file naming considerations, including DBMS_JAVA procedures to retrieve a full name from a short name and the converse, see the Oracle9i Java Developer's Guide


Full Names of Loaded Classes (including profiles if -ser2class enabled)

The full name of the class schema object produced when you load a .class file into the server is determined by the package and class name in the original source code. Any path information you supply on the command line (so that loadjava can find it, for example) or in the .jar file is irrelevant in determining the name of the schema object. For example, if Foo.class consists of a class Foo which was specified in the source code as being in package x.y, then the full name of the resulting class schema object is as follows:

x/y/Foo

Note that ".class" is dropped.

If Foo.sqlj declares an iterator MyIter, then the full name of its class schema object is:

x/y/MyIter

(Unless it is a nested class, in which case it will not have its own schema object.)

The related profile-keys class file, generated by SQLJ when you translate Foo.sqlj, is Foo_SJProfileKeys.class; therefore, the full name of its class schema object is:

x/y/Foo_SJProfileKeys

If the -ser2class option was enabled when you translated your application, then the resulting profile was generated in file Foo_SJProfile0.class; therefore, the full name of the class schema object is:

x/y/Foo_SJProfile0

Full Names of Loaded Resources (including profiles if -ser2class not enabled)

This discussion is relevant only if you did not enable the -ser2class option when you translated your application, or if you use other Java serialized resource (.ser) files in your application.

The naming of resource schema objects is handled differently from class schema objects--their names are not determined from the contents of the resources. Instead, their full names are identical to the names that appear in a .jar file or on the loadjava command line, including path information. Note also that the .ser extension is not dropped.

It is important to note that because resource names are used to locate the resources at runtime, their names must include the correct path information. In the server, the correct full name of a resource is identical to the relative path and file name that Java would use to look it up on a client.

In the case of a SQLJ profile, this is a subdirectory under the directory specified by the translator -d option, according to the package name. If the -d option, used to specify the top-level output directory for generated .class and .ser files, is set to /mydir and the application is in package abc.def, then .class and .ser files generated during translation will be placed in the /mydir/abc/def directory. For more information about the SQLJ -d option, including the default value, see "Output Directory for Generated .ser and .class Files (-d)".

At runtime, /mydir would presumably be in your classpath, and Java will look for your application components in the abc/def directory underneath it.

Therefore, when you load this application into the server, you must run loadjava or jar from the -d directory so that the path you specify on the command line to find the files also indicates the package name, as follows:

cd /mydir
loadjava <...options...> abc/def/*.class abc/def/*.ser

Or, if you use a .jar file:

cd /mydir
jar -cvf myjar.jar abc/def/*.class abc/def/*.ser
loadjava <...options...> myjar.jar

If your application is App and your profile is App_SJProfile0.ser, then either of the above examples will correctly result in the following full name of the created resource schema object:

abc/def/App_SJProfile0.ser

Note that ".ser" is retained.

Note also that if you set -d to a directory whose hierarchy has no other contents (which is advisable), you can simply run jar as follows to recursively get your application components:

cd /mydir
jar -cvf myjar.jar *
loadjava <...options...> myjar.jar

Publishing the Application After Loading Class and Resource Files

Before using your SQLJ code in the server, you must publish the top-level methods, as is true of any Java code you use in the server. Publishing includes writing call descriptors, mapping datatypes, and setting parameter modes. For information, see the Oracle9i Java Stored Procedures Developer's Guide.

Summary: Running a Client Application in the Server

This section summarizes the typical steps of running a client application in the server. As an example, it uses the NamedIterDemo sample application provided in "Named Iterator--NamedIterDemo.sqlj".

  1. Create a .jar file for your application components. For NamedIterDemo, the components include SalesRec.class as well as the application class and profile.

    You can create a .jar file niter-server.jar as follows:

    jar cvf niter-server.jar Named*.class Named*.ser SalesRec.classconnect.properties
    
    
  2. Load the .jar file into the server.

    Use loadjava as follows. This example instructs loadjava to use the OCI driver in loading the files. The -resolve option results in the class files being resolved.

    loadjava -oci -resolve -force -user scott/tiger niter-server.jar
    
    
  3. Create a SQL wrapper in the server for your application.

    For example, run a SQL*Plus script that executes the following:

    set echo on
    set serveroutput on
    set termout on
    set flush on
    
    execute dbms_java.set_output(10000);
    
    create or replace procedure SQLJ_NAMED_ITER_DEMO as language java 
    name 'NamedIterDemo.main (java.lang.String[])';
    /
    
    

    The DBMS_JAVA.SET_OUTPUT() routine reroutes default output to your screen, instead of to a trace file; the input parameter is the buffer size in bytes.

  4. Execute the wrapper.

    For example:

    sqlplus> call SQLJ_NAMED_ITER_DEMO();
    
    

Loading SQLJ Source and Translating in the Server

Another approach to developing SQLJ code for the server is loading the source code into the server and translating it directly in the server. This employs the embedded SQLJ translator in the Oracle JVM. This discussion still assumes you created the source on a client machine.

As a general rule, loading SQLJ source into the server is identical to loading Java source into the server, with translation taking place implicitly when a compilation option is set (such as the loadjava -resolve option, discussed below).

When you load .sqlj source files into Oracle9i, either directly or using a .jar file, the resulting library units containing the source code are referred to as Java source schema objects. A separate schema object is created for each source file.

When translation and compilation take place, the resulting library units for the generated classes and profiles are referred to as Java class schema objects (for classes) and Java resource schema objects (for profiles), just as they are when loaded directly into the server from .class files and .ser files created on a client. A separate schema object is created for each class and for each profile.

Resource schema objects are also used for properties files that you load into the server.


Notes:

  • The server-side SQLJ translator does not currently support Oracle-specific code generation (the -codegen=oracle setting). If you want to use such code in the server, you must translate on a client and load the individual class files into the server, as described in "Translating SQLJ Source on a Client and Loading Components".

  • When you translate your SQLJ application in the server, profiles are always generated as resources, not classes, because there is no -ser2class option in SQLJ server-side translator.

 

Loading SQLJ Source Code into the Server

Use the Oracle loadjava client-side utility on a .sqlj file (instead of on .class and .ser files) to load source into the server. This utility is discussed in detail in the Oracle9i Java Developer's Guide.

If you enable the loadjava -resolve option in loading a .sqlj file, then the server-side embedded translator is run to perform the translation, compilation, and customization of your application as it is loaded. Otherwise, the source is loaded into a source schema object without any translation. In this case, however, the source is implicitly translated, compiled, and customized the first time an attempt is made to use a class defined in the source. Such implicit translation might seem surprising at first, because there is nothing comparable in client-side SQLJ.

For example, run loadjava as follows:

loadjava -user scott/tiger -resolve Foo.sqlj

Or, to use the Thin driver to load (specifying the -thin option and an appropriate URL):

loadjava -thin -user scott/tiger@localhost:1521:ORCL -resolve Foo.sqlj

Either of these will result in appropriate class schema objects and resource schema objects being created in addition to the source schema object. For information, see "Loaded Source and Generated Class and Resource Schema Objects".

Before running loadjava, however, you must set SQLJ options appropriately. For more information, see "Option Support in the Server Embedded Translator". Note that encoding can be set on the loadjava command line, instead of through the server-side SQLJ encoding option, as follows:

loadjava -user scott/tiger -resolve -encoding SJIS Foo.sqlj

The loadjava script, which runs the actual utility, is in the bin subdirectory under your [Oracle Home] directory. This directory should already be in your path once Oracle has been installed.


Notes:

  • You cannot load a .sqlj file along with .class files or .ser files that were generated from processing of the same .sqlj file. This would create an obvious conflict, because the server would be trying to load the same classes and profiles that it would also be trying to generate.

    (In processing a .jar file, loadjava first processes .sqlj, .java, and .class files. It then makes a second pass and processes everything else as Java resource files.)

  • You can put multiple .sqlj files into a .jar file and specify the .jar file to loadjava.

  • You can access the USER_OBJECTS view in your schema to verify that your classes and resources are loaded properly. This is discussed in the Oracle9i Java Developer's Guide.

 

Although the loadjava utility is recommended for loading your SQLJ and Java applications into the server, you can also use Oracle SQL CREATE JAVA commands such as the following:

CREATE OR REPLACE <AND COMPILE> JAVA SOURCE <NAMED srcname> <AS loadname>;

If you specify AND COMPILE for a .sqlj file, then the source is translated, compiled, and customized at that time, creating class schema objects and resource schema objects as appropriate in addition to the source schema object. Otherwise, it is not translated and compiled--in this case only the source schema object is created. In this latter case, however, the source is implicitly translated, compiled, and customized the first time an attempt is made to use a class contained in the source.

See the Oracle9i SQL Reference for more information about the CREATE JAVA commands.


Note:

When you first load a source file, some checking of the source code is performed, such as determining what classes are defined. If any errors are detected at this time, the load fails. 


Option Support in the Server Embedded Translator

The following options are available in the server-side SQLJ translator:

This section includes discussion of the loadjava utility and its -resolve option. For more information, see the Oracle9i Java Developer's Guide.

The encoding Option

This option determines any encoding (for example, SJIS) employed to interpret your source code when it is loaded into the server. The encoding option is used at the time the source is loaded, regardless of whether it is also compiled.

Alternatively, when using loadjava to load your SQLJ application into the server, you can specify encoding on the loadjava command line, as discussed in "Loading SQLJ Source Code into the Server". Any loadjava command-line setting for encoding overrides this encoding option.

See "Encoding for Input and Output Source Files (-encoding)" for general information about this option.


Note:

If no encoding is specified, either through this option or through loadjava, then encoding is performed according to the file.encoding setting of the client from which you run loadjava


The online Option

Setting this option to true (the default value) enables online semantics-checking. Semantics-checking is performed relative to the schema in which the source is loaded. You do not specify an exemplar schema, as you do for online-checking on a client.

If the online option is set to false, offline checking is performed.

In either case, the default checker is oracle.sqlj.checker.OracleChecker, which will choose an appropriate checker according to your JDBC driver version and Oracle version. For information about OracleChecker, see "Semantics-Checkers and the OracleChecker Front End (default checker)".

The online option is used at the time the source is translated and compiled. If you load it with the loadjava -resolve option enabled, this will occur immediately. Otherwise it will occur the first time an attempt is made to use a class defined in the source (resulting in implicit translation and compilation).


Note:

The online option is used differently in the server than on a client. In the server, the online option is only a flag that enables online checking using a default checker. On a client, the -online option specifies which checker to use, but it is the -user option that enables online checking. 


The debug Option

Setting this option to true instructs the server-side Java compiler to output debugging information when a .sqlj or .java source file is compiled in the server. This is equivalent to using the -g option when running the standard javac compiler on a client.

The debug option is used at the time the source is compiled. If you load it with the loadjava -resolve option enabled, this will occur immediately (right after SQLJ translation, in the case of a .sqlj file). Otherwise it will occur the first time an attempt is made to use a class defined in the source (resulting in implicit translation and compilation).

Setting SQLJ Options in the Server

There is no command line and there are no properties files when running the SQLJ translator in the server. Information about translator and compiler options is held in each schema in a table named JAVA$OPTIONS. Manipulate options in this table through the following functions and procedures of the package DBMS_JAVA:

Use set_compiler_option() to specify separate option settings for individual packages or sources. It takes the following as input, with each parameter enclosed by single-quotes:

Execute the DBMS_JAVA routines using SQL*Plus, for example, as follows:

sqlplus> execute dbms_java.set_compiler_option('x.y', 'online', 'true');
sqlplus> execute dbms_java.set_compiler_option('x.y.Create', 'online', 'false');

These two commands enable online checking for all sources in the package x.y, then override that for the Create source by disabling online checking for that particular source.

Similarly, set encoding for package x.y to SJIS as follows:

sqlplus> execute dbms_java.set_compiler_option('x.y', 'encoding', 'SJIS');

Server-Side Option Notes

Be aware of the following:

Loaded Source and Generated Class and Resource Schema Objects

When you use the server-side SQLJ translator, such as when you use loadjava on a .sqlj file with the -resolve option enabled, the output generated by the server-side translator is essentially identical to what would be generated on a client--a compiled class for each class you defined in the source, a compiled class for each iterator and connection context class, a compiled profile-keys class, and one or more customized profiles.

As a result, the following schema objects will be produced when you load a .sqlj file into the server with loadjava and have it translated and compiled:

The full names of these schema objects are determined as described in the following subsections. Use the loadjava -verbose option for a report of schema objects produced and what they are named.

Full Names and Short Names

There are two forms of schema object names in the server: full names and short names.

Full names are fully qualified and are used as the schema object names whenever possible. If any full name is longer than 31 characters, however, or contains characters that are illegal or cannot be converted to characters in the database character set, then Oracle9i 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.

For more information about these and about other file naming considerations, including DBMS_JAVA procedures to retrieve a full name from a short name, and the converse, see the Oracle9i Java Developer's Guide.

Full Name of Source

When you load a source file into the server, regardless of whether it is translated and compiled, a source schema object is produced. The full name of this schema object is determined by the package and class names in the source code. Any path information you supply on the command line (so loadjava can find it) is irrelevant to the determination of the name of the schema object.

For example, if Foo.sqlj defines a class Foo in package x.y and defines or declares no other classes, then the full name of the resulting source schema object is:

x/y/Foo

Note that ".sqlj" is dropped.

If you define additional classes or declare iterator or connection context classes, then the source schema object is named according to the first public class definition or declaration encountered, or, if there are no public classes, the first class definition. (In the server, there can be more than one public class definition in a single source.)

For example, if Foo.sqlj is still in package x.y, defines public class Bar first and then class Foo, and has no public iterator or connection context class declarations preceding the definition of Bar, then the full name of the resulting source schema object is:

x/y/Bar

If, however, the declaration of public iterator class MyIter precedes the Bar and Foo class definitions, then the full name of the resulting source schema object is:

x/y/MyIter

Full Names of Generated Classes

Class schema objects are generated for each class you defined in the source, each iterator you declared, and the profile-keys class. The naming of the class schema objects is based on the class names and the package name from the source code.

This discussion continues the example in "Full Name of Source". Presume your source code specifies package x.y, defines public class Bar then class Foo, then declares public iterator class MyIter. The full names of the class schema objects for the classes you define and declare are as follows:

x/y/Bar
x/y/Foo
x/y/MyIter

Note that ".class" is not appended.

The profile-keys class is named according to the name of the source schema object, appended by:

_SJProfileKeys

If the Bar definition precedes the Foo definition and MyIter declaration, then the class schema object for the profile-keys class is named as follows:

x/y/Bar_SJProfileKeys

If the MyIter declaration precedes either of the class definitions, then the profile-keys class schema object is named as follows:

x/y/MyIter_SJProfileKeys


Note:

It is recommended that the source name always match the first public class defined, or, if there are no public classes, the first class defined. This will avoid possible differences between client-side and server-side behavior. 


The name of the original source file, as well as any path information you specify when loading the source into the server, is irrelevant in determining the names of the generated classes.

If you define inner classes or anonymous classes in your code, then they are named according to the conventions of the standard javac compiler.

Full Names of Generated Profiles

Resource schema objects for generated profiles are named in the same way as the profile-keys class schema object--based on the source schema object name, using package and class information from the source code in the same way. Any directory information specified on the command line (the loadjava command line, for example) or in a .jar file is irrelevant in determining the profile name.

When a source file is loaded and translated, the generated profiles use the source schema object name as a base name, followed by:

_SJProfile0.ser
_SJProfile1.ser
...

Note that ".ser" is included.

This is identical to what is appended to produce a profile name on the client.

Using the examples in "Full Name of Source", where the source schema object was named either x/y/Foo, x/y/Bar, or x/y/MyIter (depending on the situation, as discussed), the name of the profile would be:

x/y/Foo_SJProfile0.ser

or:

x/y/Bar_SJProfile0.ser

or:

x/y/MyIter_SJProfile0.ser 

Error Output from the Server Embedded Translator

SQLJ error processing in the server is similar to general Java error processing in the server. SQLJ errors are directed into the USER_ERRORS table of the user schema. You can SELECT from the TEXT column of this table to get the text of a given error message.

If you use loadjava to load your SQLJ source, however, loadjava also captures and outputs the error messages from the server-side translator.

Informational messages and suppressible warnings are withheld by the server-side translator in a way that is equivalent to the operation of the client-side translator with a -warn=noportable,noverbose setting (which is the default). See "Translator Warnings (-warn)" for more information about the -warn option of the client-side translator.

Publishing the Application After Loading Source Files

Before using your SQLJ code in the server, you must publish the top-level methods, as is true of any Java code you use in the server. Publishing includes writing call descriptors, mapping datatypes, and setting parameter modes. For information, see the Oracle9i Java Stored Procedures Developer's Guide.

Dropping Java Schema Objects

To complement the loadjava utility, Oracle provides the dropjava utility to remove (drop) Java source, class, and resource schema objects. It is recommended that any schema object loaded into the server using loadjava be removed using dropjava only. This section presents only an overview of dropjava; it is discussed in detail in the Oracle9i Java Tools Reference.

The dropjava utility transforms command-line file names and .jar file contents to schema object names, then removes the schema objects. You can enter .sqlj, .java, .class, .ser, and .jar files on the command line in any order.

You should always remove Java schema objects in the same way that you first loaded them. If you load a .sqlj source file and translate it in the server, then run dropjava on the same source file. If you translate on a client and load classes and resources directly, then run dropjava on the same classes and resources.

For example, if you run loadjava on Foo.sqlj, then execute dropjava on the same file name, as follows:

dropjava -user scott/tiger Foo.sqlj

If you translate your program on the client and load it using a .jar file containing the generated components, then use the same .jar file name to remove the program:

dropjava -user scott/tiger Foo.jar

If you translate your program on the client and load the generated components using the loadjava command line, then remove them using the dropjava command line, as follows (presume there were no iterator classes):

dropjava -user scott/tiger Foo*.class dir1/dir2/Foo_SJProfile*.ser

Additional Considerations

This section discusses Java multithreading in the server and recursive SQLJ calls in the server.

Java Multithreading in the Server

Programs that use Java multithreading can execute in Oracle9i without modification; however, while client-side programs use multithreading to improve throughput for users, there are no such benefits when Java-multithreaded code runs in the server. If you are considering porting a multithreaded application into the server, be aware of the following important differences in the functionality of multithreading in the Oracle JVM, as opposed to in client-side JVMs:

Do not confuse Java multithreading in Oracle9i with general Oracle server multithreading. The latter refers to simultaneous Oracle sessions, not Java multithreading. In the server, scalability and throughput are gained by having many individual users, each with his own session, executing simultaneously. The scheduling of Java execution for maximum throughput (such as for each call within a session) is performed by the Oracle server, not by Java.

For general information about Java multithreading in SQLJ, see "Multithreading in SQLJ".

Recursive SQLJ Calls in the Server

As discussed in "Execution Context Synchronization", SQLJ generally does not allow multiple SQLJ statements to use the same execution context instance simultaneously. Specifically, a statement trying to use an execution context instance that is already in use will be blocked until the first statement completes.

This functionality would be less desirable in the Oracle server than on a client, however. This is because different stored procedures or functions, which all typically use the default execution context instance, can inadvertently try to use this same execution context instance simultaneously in recursive situations. For example, one stored procedure might use a SQLJ statement to call another stored procedure that uses SQLJ statements. When these stored procedures are first created, there is probably no way of knowing when such situations might arise, so it is doubtful that particular execution context instances are specified for any of the SQLJ statements.

To address this situation, SQLJ does allow multiple SQLJ statements to use the same execution context instance simultaneously if this results from recursive calls.

Consider an example of a recursive situation to see what happens to status information in the execution context instance. Presume that all statements use the default connection context instance and its default execution context instance. If stored procedure proc1 has a SQLJ statement that calls stored procedure proc2, which also has SQLJ statements, then the statements in proc2 will each be using the execution context instance while the procedure call in proc1 is also using it.

Each SQLJ statement in proc2 results in status information for that statement being written to the execution context instance, with the opportunity to retrieve that information after completion of each statement as desired. The status information from the statement in proc1 that calls proc2 is written to the execution context instance only after proc2 has finished executing, program flow has returned to proc1, and the operation in proc1 that called proc2 has completed.

To avoid confusion about execution context status information in recursive situations, execution context methods are carefully defined to update status information about a SQL operation only after the operation has completed.


Notes:

  • To avoid confusion, use distinct execution context instances as appropriate whenever you plan to use execution context status or control methods in code that will run in the server.

  • Be aware that if the above example does not use distinct execution context instances, and proc2 has any method calls to the execution context instance to change control parameters, then this will affect operations subsequently executed in proc1.

  • Update batching is not supported across recursive calls. By default, only the top-level procedure will perform batching (if enabled). This limitation can be avoided by using explicit execution context instances.

 

For information about ExecutionContext methods, see "ExecutionContext Methods".

Verifying that Code is Running in the Server

A convenient way to verify that your code is actually running in the server is to use the static getProperty() method of the java.lang.System class to retrieve the oracle.server.version Java property. If this property contains a version number, then you are running in the Oracle server. If it is null, then you are not. Here is an example:

...
if (System.getProperty("oracle.server.version") != null 
{
   // (running in server)
}
...


Note:

Do not use the getProperties() method, as this causes a security exception in the server. 


Additional Vehicles for SQLJ in the Server

Most of the discussion in this chapter has presumed that SQLJ is being used for stored procedures or stored functions; there has been no special consideration of any other possibilities. Be aware, though, that you can also use SQLJ in the server in the following ways:

This section introduces the use of Enterprise JavaBeans and CORBA objects. For more information, see the Oracle9i Enterprise JavaBeans Developer's Guide and Reference and the Oracle9i CORBA Developer's Guide and Reference. The EJB manual, in its example code appendix, includes an example of an EJB developed with SQLJ.


Note:

If your EJB or CORBA object uses any XA transactions (UserTransaction in an EJB, or JTS in a CORBA object, for example), then you cannot use explicit SQLJ COMMIT/ROLLBACK statements or JDBC COMMIT/ROLLBACK methods. Any attempt to do so will result in an exception. You must, instead, execute your COMMIT and ROLLBACK operations through the particular XA interface that you are using. See the Oracle9i JDBC Developer's Guide and Reference for general information about XA functionality. 


Enterprise JavaBeans

To use SQLJ in Enterprise JavaBeans (EJBs), develop and translate the SQLJ EJBs on a client and then load all resulting classes and resources into the server. To load and publish EJBs, however, you must use a utility called deployejb (loadjava is not used).

When you run the SQLJ translator for your EJB program, consider the following:

Once you have translated your SQLJ EJB, gather everything into a .jar file. This includes:

After creating the .jar file, use the deployejb utility to load everything into the server, specifying the .jar file as input.

CORBA Server Objects

You can also use SQLJ for developing CORBA objects that have SQL DML statements. As with EJBs, you must be careful to include all classes and resource files that the SQLJ translator generates when you load files into the server. For CORBA objects, load and publish as you would for stored procedures.

Create a .jar file to hold all the SQLJ-generated files, as discussed in "Enterprise JavaBeans", and use this file on the command line when you run the loadjava utility.


Go to previous page Go to next page
Oracle
Copyright © 1996-2001, Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index