|Oracle8i SQLJ Developer's Guide and Reference
Release 3 (8.1.7)
Part Number A83723-01
By default, running the
sqlj script on a SQLJ source file includes an automatic customization process, where each profile created during the translator's code generation phase is customized for use with your particular database. The default customizer is the Oracle customizer,
oracle.sqlj.runtime.OraCustomizer, which optimizes your profiles to use type extensions and performance enhancements specific to Oracle8i databases.
You can also run the
sqlj script to customize profiles created previously. On the SQLJ command line, you can specify
.ser files individually,
.jar files containing
.ser files, or both.
Regardless of whether you use the Oracle customizer or an alternative customizer, SQLJ uses a front-end customization utility known as the customizer harness in accomplishing your customizations.
When you run SQLJ, you can specify customization options for the customizer harness (for general customization settings that apply to any customizer you use) and for your customizer (for settings used by the particular customizer). In either case, you can specify these option either on the command line or in a properties file. This is discussed in "Customization Options and Choosing a Customizer".
The following paragraphs detail how Oracle implements the customizer harness and the Oracle customizer. This information is not necessary for most SQLJ developers.
The customizer harness is a command-line tool that is an instance of the class
CustomizerHarness object is created and invoked each time you run the SQLJ translator. During the customization phase, the harness creates and invokes an object of the customizer class you are using (such as the default Oracle customizer), and loads your profiles.
The Oracle customizer is defined in the
oracle.sqlj.runtime.OraCustomizer class. All customizers must be JavaBeans components that adhere to the JavaBeans API to expose their properties and must implement the
sqlj.runtime.profile.util.ProfileCustomizer interface, which specifies a
customize() method. It is the implementation of this method in a particular customizer that does the work of customizing profiles.
For each profile to be customized, the customizer harness calls the
customize() method of the customizer object.
The SQLJ customization process during translation consists of the following steps, as applicable, either during the customization stage of an end-to-end SQLJ run, or when you run SQLJ to customize existing profiles only:
.jarfiles (applicable when you run SQLJ for customization only, specifying one or more
.jarfiles on the command line).
.serfiles automatically created during an end-to-end SQLJ run,
.serfiles specified on the command line for customization only, or
.serfiles extracted from
.jarfiles specified on the command line for customization only).
customize()method of the customizer object instantiated in step 2 (customizers used with Oracle SQLJ must have a
customize()method typically creates and registers a profile customization within the profile. (This depends on the intended functionality of the customizer, however. Some might have a specialized purpose that does not require a customization to be created and registered in this way.)
.jarcontents, inserting each customized
.serfile to replace the original corresponding uncustomized
.serfile (applicable when you run SQLJ for customization only, specifying one or more
.jarfiles on the command line).
.ser file is not replaced.
.jar file, the original
.jar file is not replaced.
When the harness calls the
customize() method to customize a profile, it passes in the profile object, a JDBC
Connection object (if you are using a customizer that requires a connection), and an error log object (which is used in logging error messages during the customization).
The same error log object is used for all customizations throughout a single running of SQLJ, but its use is transparent. The customizer harness reads messages written to the error log object and reports them in real-time to the standard output device (whatever SQLJ uses, typically your screen).
Recall that each profile has a set of entries, where each entry corresponds to a SQL operation. (These would be the SQL operations in your application that use instances of the connection context class associated with this profile.)
customize() method implements special processing on these entries. It could be as simple as checking each entry to verify its syntax, or it could be more complicated, such as creating new entries that are equivalent to the original entries but are modified to use features of your particular database.
The following paragraphs detail how Oracle implements the customization process. This information is not necessary for most SQLJ developers.
In the case of the Oracle customizer, the
customize() method creates a data structure that has one entry for each entry in the original profile. The original entries are never changed, but the new entries are customized to take advantage of features of Oracle8i. For example, if you are using BLOBs, a generic
getObject() call used to retrieve a BLOB in the original entry is replaced by a
These new entries are encapsulated in an object of a customization class that implements the
sqlj.runtime.profile.Customization interface, and this customization object is installed into the profile object. (Customization objects, like profile objects, are serializable.)
The customizer harness then registers the customization, which is accomplished through functionality of the profile object. Registration allows a profile to keep track of the customizations that it contains.
Any errors encountered during customization are posted to the error log and reported by the customizer harness as appropriate.
Customization object has an
acceptsConnection() method called at runtime to determine if the customization can create a connected profile object for a given JDBC
Connection object. A connected profile object--an instance of a class that implements the
sqlj.runtime.profile.ConnectedProfile interface--represents a mapping between a profile object and a JDBC connection. It is equivalent to a JDBC
Connection object, with the ability to create statements, but supports additional vendor-specific functionality.
The customizer harness outputs error and status messages in much the same way as the SQLJ translator, outputting them to the same output device. None of the warnings regarding customization are suppressable, however. (See "Translator Error, Warning, and Information Messages".)
Error messages reported by the customizer harness fall into four categories:
Status messages reported by the customizer harness during customization allow you to determine whether a profile was successfully customized. They fall into three categories:
.jarfile modification status
backupoption is enabled)
Additional customizer-specific errors and warnings might be reported by the
customize() method of the particular customizer.
During customization, the profile customizer writes messages to its error log, and the customizer harness reads the log contents in real-time and outputs these messages to the SQLJ output device, along with any other harness output. You never need to access error log contents directly.
A customized profile is a static member of the connection context class with which it is associated. For each SQLJ statement in your application, the SQLJ runtime determines the connection context class and instance associated with that statement, then uses the customized profile of the connection context class, together with the underlying JDBC connection of the particular connection context instance, to create a connected profile. This connected profile is the vehicle that the SQLJ runtime uses in applying vendor-specific features to the execution of your SQLJ application.
The following paragraphs details how the Oracle SQLJ runtime uses customized profiles. This information is not necessary for most SQLJ developers.
In executing a SQLJ statement, the SQLJ runtime uses methods of the connection context object associated with the statement, and the profile object associated with the connection context class, as follows:
getConnectedProfile()method calls the
getConnectedProfile()method of the profile object associated with the connection context class, passing it a connection. (This is the connection instance underlying the connection context instance used for the SQL operation.)
getConnectedProfile()method calls the
acceptsConnection()method of each
Customizationobject registered in the profile. The first
Customizationobject that accepts the connection creates the connected profile that is passed back to the runtime.