Oracle8i SQLJ Developer's Guide and Reference Release 3 (8.1.7) Part Number A83723-01 |
Library | Service | Contents | Index

## More About Profile Customization

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.

Notes: Whenever you use the default Oracle customizer during translation, your application will require the Oracle SQLJ runtime and an Oracle JDBC driver when it runs, even if you do not use Oracle extensions in your code. If an application has no customizations, or none suitable for the connection, then the generic SQLJ runtime is used. You can run SQLJ to process `.sqlj` and/or `.java` files (translation, compilation, and customization) or to process `.ser` and/or `.jar` files (customization only), but not both categories at once.

### Overview of the Customizer Harness and Customizers

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".

##### Implementation Details

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 `sqlj.runtime.profile.util.CustomizerHarness`. A `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.

### Steps in the Customization Process

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:

1. SQLJ instantiates and invokes the customizer harness and passes it any general customization options you specified.

2. The customizer harness instantiates the customizer you are using and passes it any customizer-specific options you specified.

3. The customizer harness discovers and extracts the profile files within any `.jar` files (applicable when you run SQLJ for customization only, specifying one or more `.jar` files on the command line).

4. The customizer harness deserializes each profile file into a profile object (`.ser` files automatically created during an end-to-end SQLJ run,`.ser` files specified on the command line for customization only, or `.ser` files extracted from `.jar` files specified on the command line for customization only).

5. If the customizer you use requires a database connection, the customizer harness establishes that connection.

6. For each profile, the harness calls the `customize()` method of the customizer object instantiated in step 2 (customizers used with Oracle SQLJ must have a `customize()` method).

7. For each profile, the `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.)

8. The customizer harness reserializes each profile and puts it back into a `.ser` file.

9. The customizer harness recreates the `.jar` contents, inserting each customized `.ser` file to replace the original corresponding uncustomized `.ser` file (applicable when you run SQLJ for customization only, specifying one or more `.jar` files on the command line).

   Notes: If an error occurs during customization of a profile, the original `.ser` file is not replaced. If an error occurs during customization of any profile in a `.jar` file, the original `.jar` file is not replaced. SQLJ can run only one customizer at a time. If you want to accomplish multiple customizations on a single profile, you must run SQLJ multiple times. For the additional customizations, enter the profile name directly on the SQLJ command line.

### Creation and Registration of a Profile Customization

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.)

A `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.

Notes: Any `customize()` processing of profile entries does not alter the original entries. Customizing your profiles for use in a particular environment does not prevent your application from running in a different environment. You can customize a profile multiple times for use in multiple environments, and these customizations will not interfere with each other.

##### Implementation Details

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 `getBLOB()` call.

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.

A `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.

### Customization Error and Status Messages

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:

- unrecognized or illegal option

- connection instantiation error

- profile instantiation error

- customizer instantiation error

Status messages reported by the customizer harness during customization allow you to determine whether a profile was successfully customized. They fall into three categories:

- profile modification status

- `.jar` file modification status

- name of backup file created (if the customizer harness `backup` option 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.

### Functionality of a Customized Profile at Runtime

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.

##### Implementation Details

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:

1. When an end user is running your application and a SQL operation is to be executed, the SQLJ runtime calls the connection context `getConnectedProfile()` method.

2. The connection context `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.)

3. The profile object `getConnectedProfile()` method calls the `acceptsConnection()` method of each `Customization` object registered in the profile. The first `Customization` object that accepts the connection creates the connected profile that is passed back to the runtime.

4. In executing the SQL operation, the connected profile is used like a JDBC connection--creating statements to be executed--but implements special functionality of the customization.

| Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
Library | Service | Contents | Index