Skip Headers

Oracle® Database JPublisher User's Guide
10g Release 1 (10.1)

Part Number B10983-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Feedback

Go to previous page
Previous
Go to next page
Next
View PDF

1 Introduction to JPublisher

This chapter provides an introduction and overview of the JPublisher utility, concluding with a summary of JPublisher operations and a sample translation. It covers the following topics:

Overview of JPublisher

JPublisher is a utility, written entirely in Java, that generates Java classes to represent database entities such as SQL objects and PL/SQL packages in your Java client program. It also provides support for publishing from SQL, PL/SQL, or server-side Java to Web services and for enabling invocation of external Web services from inside the database.

JPublisher can create classes to represent the following types of database entities:

JPublisher enables you to specify and customize the mapping of these entities to Java classes in a strongly typed paradigm.


Note:

The term strongly typed is used where a particular Java type is associated with a given user-defined SQL type such as an object type (for example, a Person class for a corresponding PERSON SQL type). Additionally, there is a particular corresponding Java type for each attribute of the SQL object type.

The utility generates getXXX() and setXXX() accessor methods for each attribute of an object type. If your object types have stored procedures, then JPublisher can generate wrapper methods to invoke the stored procedures. In this scenario, a wrapper method is a Java method that invokes a stored procedure that executes in Oracle Database.

JPublisher can also generate classes for PL/SQL packages. These classes have wrapper methods to invoke the stored procedures in a PL/SQL package.

Instead of using JPublisher-generated classes directly, you can:

In addition, JPublisher simplifies access to PL/SQL types from Java. You can employ predefined or user-defined mappings between PL/SQL and SQL types, as well as make use of PL/SQL conversion functions between such types. With these mappings in place, JPublisher can automatically generate all the required Java and PL/SQL code.

Paralleling the functionality of publishing SQL or PL/SQL entities to Java, it is also possible to publish server-side Java to client-side Java, effectively allowing your application to make direct calls to Java classes in the database.

Several features enable exposure of generated Java classes—from publishing either SQL or PL/SQL entities or server-side Java entities—as Web services. See "Summary of JPublisher Support for Web Services" for an overview of these features.

JPublisher Initial Considerations

The following sections provide an overview of JPublisher new features and requirements, and how JPublisher uses SQLJ in its code generation:

New JPublisher Features in Oracle Database 10g

Key new JPublisher features in Oracle Database 10g can be categorized as follows:

New Features for Web Services

JPublisher is used in publishing from SQL or PL/SQL to Java, or in publishing from server-side Java to client-side Java, with new features in place to enable exposure of generated Java classes as Web services for invocation from outside the database. There are two stages to this:

  1. Publishing from SQL or PL/SQL to Java (by JPublisher)

  2. Publishing from Java to Web services (by the Oracle Web services assembler tool)

There are also new features to load and wrap client proxy classes so that external Web services can be invoked from Java or PL/SQL inside the database.

New JPublisher features in Oracle Database 10g include the following. For a more detailed overview, including how these features relate to Web services, see "Summary of JPublisher Support for Web Services".

  • Generation of Java interfaces

  • Style files for Java-to-Java type mappings

  • REF CURSOR returning and result set mapping

  • Additional support for filtering what JPublisher publishes

  • Support for publishing server-side Java classes

  • Support for publishing SQL queries or SQL DML statements

  • Support for Web services call-outs from the database

Also see "Publishing Server-Side Java Classes" and "Publishing SQL Queries or DML Statements".

Awareness of Java Environment Classpath

Prior to Oracle Database 10g, UNIX releases of JPublisher ignored the environment classpath, instead using a classpath provided through the JPublisher command line that included the required JPublisher and JDBC classes. In Oracle Database 10g, the environment classpath is appended to the classpath that is provided through the command line.

On all platforms now, JPublisher picks up the environment classpath. This feature ensures successful execution in circumstances in which JPublisher must be able to load user-provided types, such as for Web services call-outs and the conversion of Java types during publishing. The term Web services call-outs refers to calling Web services from inside the database by loading the Web services client proxies into the database and generating Java and PL/SQL wrappers for these client proxies. For more information, see "Options to Facilitate Web Services Call-Outs" and "Code Generation for Wrapper Class and PL/SQL Wrapper Options". (By contrast, the term Web services call-ins refers to the functionality of having SQL, PL/SQL, and server-side Java classes in Oracle Database that are accessible to Web services clients.)

Awareness of the environment classpath also plays a role in how JPublisher can represent query results. See "Mapping of REF CURSOR Types and Result Sets".

New Features for Usage of SQLJ

In most cases, such as whenever wrapper methods are required, JPublisher generates code that uses the Oracle SQLJ implementation. But in Oracle Database 10g, the use of SQLJ is now transparent to the user by default. The next section, "JPublisher Usage of the Oracle SQLJ Implementation", describes this.

JPublisher Usage of the Oracle SQLJ Implementation

The following sections describe when and how JPublisher uses SQLJ, provide an overview of SQLJ, and discuss backward-compatibility modes that relate to the generation of SQLJ source files:


Note:

The Oracle SQLJ translator and runtime libraries are supplied with the JPublisher product.

Overview of SQLJ Usage

The JPublisher utility uses the Oracle SQLJ ("SQL in Java") implementation, generating SQLJ code as an intermediate step in most circumstances—whenever wrapper methods are created, either for classes representing PL/SQL packages or for classes representing SQL object types that define methods (PL/SQL stored procedures). In these circumstances, JPublisher uses the Oracle SQLJ translator during compilation, and the Oracle SQLJ runtime during program execution.

In Oracle Database 10g, as a convenience, JPublisher usage of SQLJ is transparent by default. SQLJ source files that JPublisher generates are automatically translated and deleted unless you specify JPublisher settings to choose otherwise. This automatic translation saves you the step of explicitly translating the files. The resulting .java files that use SQLJ functionality, and the associated .class files produced by compilation, define what are still referred to as SQLJ classes. These classes use the Oracle SQLJ runtime APIs during execution. Generated classes that do not use the SQLJ runtime are referred to as non-SQLJ classes. Non-SQLJ classes are generated when JPublisher creates classes for SQL types that do not have stored procedures, or when JPublisher is specifically set to not generate wrapper methods.

For those familiar with SQLJ command-line options, it is possible in Oracle Database 10g to pass options to the SQLJ translator through the JPublisher -sqlj option. See "Option to Access SQLJ Functionality".

To support its use of SQLJ, JPublisher includes translator.jar, which contains the JPublisher and SQLJ translator libraries, and runtime12.jar, which is the SQLJ runtime library for JDK 1.2 and higher.

Overview of SQLJ Concepts

A SQLJ program is a Java program containing embedded SQL statements that comply with the ISO standard SQLJ Language Reference syntax. SQLJ source code contains a mixture of standard Java source, SQLJ class declarations, and SQLJ executable statements with embedded SQL operations. The use of SQLJ was chosen because of the simplified code that SQLJ uses for database access, compared to JDBC code. In SQLJ, a SQL statement is embedded in a single #sql statement, while several JDBC statements may be required for the same operation.

Because JPublisher generates code that uses SQLJ features, this document discusses some SQLJ concepts. This section briefly defines some key concepts, for those not already familiar with SQLJ.

  • Connection contexts: A SQLJ connection context object is a strongly typed database connection object. You can use each connection context class for a particular set of interrelated SQL entities, meaning that all the connections you define using a particular connection context class will use tables, views, and stored procedures that share names and datatypes in common. In theory, the advantage in tailoring connection context classes to sets of SQL entities is in the degree of online semantics-checking that this permits during SQLJ translation. JPublisher does not use online semantics-checking when it invokes the SQLJ translator, but you can use this feature if you choose to work with .sqlj files directly.

    The connection context class used by default is sqlj.runtime.ref.DefaultContext. The SQLJ default context is a default connection object and is an instance of this class. The DefaultContext class or any custom connection context class implements the standard sqlj.runtime.ConnectionContext interface. You can use the JPublisher -context option to specify the connection context class that JPublisher will instantiate for database connections. See "SQLJ Connection Context Classes (-context)".

  • Iterators: A SQLJ iterator is a strongly typed version of a JDBC result set and is associated with the underlying database cursor. SQLJ iterators are used first and foremost to take query results from a SELECT statement. The strong typing is based on the datatype of each query column.

  • Execution contexts: A SQLJ execution context is an instance of the standard sqlj.runtime.ExecutionContext class and provides a context in which SQL operations are executed. An execution context instance is associated either implicitly or explicitly with each SQL operation that is executed through SQLJ code.

Backward Compatibility Modes Affecting SQLJ Source Files

In Oracle8i and Oracle9i, JPublisher produced .sqlj source files as visible output, which you could then translate yourself using the SQLJ command-line interface (the sqlj script in UNIX or the sqlj.exe program in Microsoft Windows).

In Oracle Database 10g, JPublisher supports several backward-compatibility settings, through its -compatible option, that allow you to continue to work with generated .sqlj files in similar fashion:

  • To have JPublisher skip the step of translating .sqlj files, so that you can translate them explicitly, set -compatible=sqlj. Then, to translate the files, you can either run JPublisher again using only the -sqlj option (as described in "Option to Access SQLJ Functionality") or you can run the SQLJ translator directly through its own command-line interface.

  • To have JPublisher use "Oracle9i compatibility mode", set -compatible=9i. This setting results in JPublisher generating .sqlj files with the same code as in Oracle9i versions. Then you can work directly with the .sqlj files.

  • To have JPublisher use "Oracle8i compatibility mode", set -compatible=both8i or -compatible=8i. This setting results in JPublisher generating .sqlj files with the same code as in Oracle8i versions. As with Oracle9i compatibility mode, this mode enables you to work directly with .sqlj files.

Oracle8i and Oracle9i compatibility modes, particularly the former, result in significant differences in the code that JPublisher generates. If your only goal is to work directly with .sqlj files, then use the sqlj setting. For more information, see "Backward Compatibility and Migration" and "Backward Compatibility Option".

JPublisher General Requirements

This section describes the base requirements for JPublisher, then discusses situations with less stringent requirements.

When you use the JPublisher utility, you must also have classes for the Oracle SQLJ implementation, the Oracle JDBC implementation, and a Sun Microsystems Java Developer's Kit (JDK), among other things.

To use all features of JPublisher, you must generally have the following installed and in your classpath, as applicable:

  • Oracle Database 10g or Oracle9i database

  • JPublisher invocation script or executable

    The jpub script (for UNIX) or jpub.exe program (for Microsoft Windows) must be in your file path. They are typically in ORACLE_HOME/bin (or ORACLE_HOME/sqlj/bin for manual downloads). With proper setup, if you type just "jpub" in the command line, you will see information about common JPublisher option and input settings.

  • JPublisher and SQLJ translator classes

    These classes are in the library translator.jar, typically in ORACLE_HOME/sqlj/lib.


    Notes:

    • The translator library is also automatically loaded into the database, intranslator-jserver.jar.

    • The client-side translator library includes JPublisher client-side runtime classes, particularly oracle.jpub.reflect.Client for Java call-ins to the database.

    • The database translator library includes JPublisher server-side runtime classes, particularly oracle.jpub.reflect.Server, also for Java call-ins to the database.


  • SQLJ runtime classes

    The SQLJ runtime library is runtime12.jar, for JDK 1.2 or higher. It is typically located in ORACLE_HOME/sqlj/lib.

  • Oracle Database 10g or Oracle9i JDBC drivers

    The Oracle JDBC library—classes12.jar for JDK 1.2 or higher, or ojdbc14.jar for JDK 1.4 specifically—is typically in ORACLE_HOME/jdbc/lib. See the Oracle Database JDBC Developer's Guide and Reference for more information about the JDBC files.

    Each JDBC library also includes the JPublisher runtime classes in the oracle.jpub.runtime package.

  • Web services classes

    These classes are included in the library utl_dbws.jar, typically located in ORACLE_HOME/sqlj/lib.

  • Additional PL/SQL packages and JAR files in the database, as needed

    There are packages and JAR files that must be in the database if you use JPublisher features for Web services call-ins, Web services call-outs, support for PL/SQL types, or support for invocation of server-side Java classes. Some are preloaded and some must be loaded manually. See the next section, "Required Packages and JAR Files in the Database".

  • JDK version 1.2 or higher (JDK 1.4 or higher for Web services call-outs or to map SYS.XMLType for Web services)

    Note that you must be able to invoke the Java compiler, javac, from the command line. For information about how to specify a JDK version and a compiler version other than the default for the JPublisher environment, see "Java Environment Options".

Required Packages and JAR Files in the Database

Some or all of the following PL/SQL packages and JAR files must be present in the database, depending on what JPublisher features you use. Subsections that follow discuss how to verify the presence of these packages and files, and how to load them if they are not present.

  • SQLJUTL package, to support PL/SQL types

  • SQLJUTL2 package, to support invocation of server-side Java classes

  • UTL_DBWS package, to support Web services call-outs

  • utl_dbws_jserver.jar file, to support JAX-RPC or SOAP client proxy classes for Web services call-outs from Oracle Database 10g

    See "Options to Facilitate Web Services Call-Outs" for information about related JPublisher features.

  • JAR files to support SOAP client proxy classes for Web services call-outs from Oracle9i or Oracle8i databases

    For Web services call-outs from Oracle9i or Oracle8i, there is not yet a convenience JAR file to parallel utl_dbws_jserver.jar. You must load several JAR files instead. Also note that JPublisher does not yet support JAX-RPC client proxy classes in Oracle9i or Oracle8i.

  • sqljutl.jar file or its contents, to support Web services call-ins

    In Oracle Database 10g, support for Web services call-ins is preloaded in the database Java VM, so the sqljutl.jar file is unnecessary. In Oracle9i or Oracle8i, you must load the file manually.


Note:

The UTL_DBWS package and utl_dbws_jserver.jar file are associated with each other, both supporting the same set of features. This is also true of the SQLJUTL2 package and sqljutl.jar file. The SQLJUTL package and sqljutl.jar file, however, are not directly associated with each other; their naming is coincidental.

Verifying or Installing the UTL_DBWS Package

In Oracle Database 10g, the PL/SQL package UTL_DBWS is automatically installed in the database SYS schema. To verify the installation, try to describe the package, as follows:

SQL> describe sys.utl_dbws

If the response indicates that the package is not yet installed, then run the following scripts under SYS:

ORACLE_HOME/sqlj/lib/utl_dbws_decl.sql
ORACLE_HOME/sqlj/lib/utl_dbws_body.sql

Verifying or Installing the SQLJUTL and SQLJUTL2 Packages

In Oracle Database 10g, the PL/SQL packages SQLJUTL and SQLJUTL2 are automatically installed in the database SYS schema. To verify the installation, try to describe the packages, as follows:

SQL> describe sys.sqljutl
SQL> describe sys.sqljutl2

JPublisher output such as the following indicates that the packages are missing:

Warning: Cannot determine what kind of type is <schema>.<type.> You likely need
to install SYS.SQLJUTL. The database returns: ORA-06550: line 1, column 7:
PLS-00201: identifier 'SYS.SQLJUTL' must be declared

To install the SQLJUTL and SQLJUTL2 packages, you must install one of the following files into the SYS schema:

  • ORACLE_HOME/sqlj/lib/sqljutl.sql (for Oracle9i or Oracle Database 10g)

  • ORACLE_HOME/sqlj/lib/sqljutl8.sql (for Oracle8i)

Verifying or Loading the utl_dbws_jserver.jar File

In Oracle Database 10g, the following file must be loaded into the database for Web services call-outs:

  • ORACLE_HOME/sqlj/lib/utl_dbws_jserver.jar

It is not preloaded, but you can verify whether it has already been loaded by running the following query in the SYS schema:

SQL>  select status, object_type from all_objects where
      dbms_java.longname(object_name)='oracle/jpub/runtime/dbws/DbwsProxy$1';

The following result indicates that the file has already been loaded:

STATUS  OBJECT_TYPE
------- -------------------
VALID   JAVA CLASS
VALID   SYNONYM

If it has not already been loaded, you can use the loadjava utility, such as in the following example:

% loadjava -oci8 -u sys/change_on_install -r -v -f -s 
           -grant public utl_dbws_jserver.jar


Note:

Before loading this file, verify that the database java_pool_size parameter has a setting of at least 96 MB, and that the shared_pool_size parameter has a setting of at least 80 MB. If this is not the case, update the database parameter file (such as init.ora) to give these two entries appropriate settings, then restart the database.

See the Oracle Database Java Developer's Guide for information about the loadjava utility and Java initialization parameters.


Loading JAR Files For Web Services Call-outs in Oracle9i or Oracle8i

For Web services call-outs from an Oracle9i or Oracle8i database, use SOAP client proxy classes. For this, you must load a number of JAR files into the database, which you can accomplish with the following command (specifying ORACLE_HOME and J2EE_HOME as appropriate):

% loadjava -u sys/change_on_install -r -v -s -f -grant public 
ORACLE_HOME/soap/lib/soap.jar 
ORACLE_HOME/dms/lib/dms.jar 
J2EE_HOME/lib/servlet.jar 
J2EE_HOME/lib/ejb.jar 
J2EE_HOME/lib/mail.jar

You can obtain these files from an Oracle Application Server installation. (You would presumably run Web services in conjunction with Oracle Application Server Containers for J2EE.)

Note that JAX-RPC client proxy classes are not yet supported in Oracle9i or Oracle8i.

See the Oracle Database Java Developer's Guide for information about the loadjava utility.

Verifying or Loading the sqljutl.jar File

The following file or its contents must be loaded in the database for server-side Java invocation, such as to support Web services call-ins:

  • ORACLE_HOME/sqlj/lib/sqljutl.jar

In Oracle Database 10g, its contents are preloaded in the Java VM. In Oracle9i or Oracle8i, you must load the file manually. To see if it has already been loaded, you can run the following query in the SYS schema:

SQL> select status, object_type from all_objects where
     dbms_java.longname(object_name)='oracle/jpub/reflect/Client';

The following result indicates that the file has already been loaded:

STATUS  OBJECT_TYPE
------- -------------------
VALID   JAVA CLASS
VALID   SYNONYM

If it has not already been loaded, you can use the loadjava utility, such as in the following example:

% loadjava -oci8 -u sys/change_on_install -r -v -f -s 
           -grant public sqlj/lib/sqljutl.jar

Note:

To load this file, as with the file discussed in the previous section, verify that java_pool_size has a setting of at least 96 MB and shared_pool_size has a setting of at least 80 MB.

Situations for Reduced Requirements

If you will not be using certain features of JPublisher, your requirements may be less stringent:

  • If you never generate classes that implement the Oracle-specific oracle.sql.ORAData interface (or the deprecated oracle.sql.CustomDatum interface), you can use a non-Oracle JDBC driver and connect to a non-Oracle database. JPublisher itself, however, must be able to connect to an Oracle database. Be aware that Oracle does not test or support configurations that use non-Oracle components. (See "Representing User-Defined SQL Types Through JPublisher" for an overview of ORAData.)

  • If you instruct JPublisher to not generate wrapper methods (through the setting -methods=false), or if your object types define no methods, then JPublisher will not generate wrapper methods or produce any SQLJ classes. Under these circumstances, there will be no SQLJ translation step, so the SQLJ translator is not required. See "Generation of Package Classes and Wrapper Methods (-methods)" for information about the -methods option.

  • If you use JPublisher to generate custom object classes that implement only the deprecated CustomDatum interface, then you can use the Oracle8i Release 8.1.5 database with the 8.1.5 version of the JDBC driver and with JDK version 1.1 or higher. But it is advisable to upgrade to the ORAData interface, which requires an Oracle9i or higher JDBC implementation.

  • If you do not use JPublisher functionality for invocation of server-side Java classes, then you do not need the sqljutl.jar file to be loaded in the database.

  • If you do not use JPublisher functionality to enable Web services call-outs, then you do not need utl_dbws.jar or utl_dbws_jserver.jar to be loaded in the database.

JPublisher Limitations

Be aware of the following when you use JPublisher:

  • There are limitations to the support for PL/SQL RECORD and indexed-by table types. First, an intermediate wrapper layer is used to map a RECORD or indexed-by-table argument to a SQL type that JDBC supports. In addition, JPublisher cannot fully support the semantics of indexed-by tables. An indexed-by table is similar in structure to a Java Hashtable, but information is lost when JPublisher maps this to a SQL TABLE type (SQL collection). See "Type Mapping Support for PL/SQL RECORD and Indexed-by Table Types" for details about how these types are supported.

  • If you use an INPUT file to specify type mappings, note that some potentially disruptive error conditions do not result in error or warning messages from JPublisher. Additionally, there are reserved terms that you are not permitted to use as SQL or Java identifiers. See "INPUT File Precautions" for details.

  • There is a JPublisher option, -omit_schema_names, that has boolean logic but does not use the same syntax as other boolean options. You can use this option to instruct JPublisher to not use schema names to qualify SQL names that are referenced in wrapper classes. (By default, JPublisher uses schema names to qualify SQL names.) To enable the option (to disable the use of schema names), enter the option name, "-omit_schema_names", on the command line, but do not attempt to set "-omit_schema_names=true" or "-omit_schema_names=false". See "Omission of Schema Name from Name References (-omit_schema_names)" for additional information.

What JPublisher Can Publish

The following sections describe the basic categories of publishing that the JPublisher utility supports:

Publishing SQL User-Defined Types

Using JPublisher to publish SQL objects or collections as Java classes is straightforward. This section provides examples of this for the OE (Order Entry) schema that is part of the Oracle Database sample schema. (See Oracle Database Sample Schemas for detailed information.) If you do not have the sample schema installed, but have your own object types that you would like to publish, then replace the user name, password, and object names with your own.

Assuming that the password for the OE schema is OE, use the following command to publish the SQL object type CATEGORY_TYP (where % is the system prompt):

% jpub -user=OE/OE -sql=CATEGORY_TYP:CategoryTyp


Note:

See "Declaration of Object Types and Packages to Translate (-sql)" for more information about the -sql option.

Use the JPublisher -user option to specify the user name (schema name) and password. The -sql option specifies the types to be published. CATEGORY_TYP is the name of the SQL type and, separated by a colon (":"), CategoryTyp is the name of the corresponding Java class to be generated. JPublisher echoes to the standard output the names of the SQL types that it is publishing:

OE.CATEGORY_TYP

When you list the files in your current directory, notice that in addition to the file CategoryTyp.java, JPublisher has also generated the file CategoryTypeRef.java. This represents a strongly typed wrapper class for SQL object references to OE.CATEGORY_TYP. Both files are ready to be compiled with the Java compiler, javac.

Here is another example, for the type CUSTOMER_TYP, using the shorthand -u (followed by a space) for "-user=" and -s (followed by a space) for "-sql=":

% jpub -u OE/OE -s CUSTOMER_TYP:CustomerTyp

JPublisher reports a list of SQL object types, as follows, because whenever it encounters an object type for the first time (whether through an attribute, an object reference, or a collection that has element types that themselves are objects or collections), it automatically generates a wrapper class for that type as well.

OE.CUSTOMER_TYP
OE.CORPORATE_CUSTOMER_TYP
OE.CUST_ADDRESS_TYP
OE.PHONE_LIST_TYP
OE.ORDER_LIST_TYP
OE.ORDER_TYP
OE.ORDER_ITEM_LIST_TYP
OE.ORDER_ITEM_TYP
OE.PRODUCT_INFORMATION_TYP
OE.INVENTORY_LIST_TYP
OE.INVENTORY_TYP
OE.WAREHOUSE_TYP

Two source files are generated for each object type in this example: 1) source file for a Java class, such as CustomerTyp, to represent instances of the object type; and 2) source file for a reference class, such as CustomerTypeRef, to represent references to the object type. You may also have noticed the naming scheme that JPublisher uses by default: the SQL type OE.PRODUCT_INFORMATION_TYP turns into a Java class ProductInformationTyp, for example.

Even though JPublisher automatically generates wrapper classes for embedded types, it does not do so for subtypes of given object types. In this case, you have to explicitly enumerate all the subtypes that you want to have published. The CATEGORY_TYP type has three subtypes: LEAF_CATEGORY_TYP, COMPOSITE_CATEGORY_TYP, and CATALOG_TYP. The following is a single wraparound JPublisher command line to publish these object types.

% jpub  -u OE/OE  -s COMPOSITE_CATEGORY_TYP:CompositeCategoryTyp
        -s LEAF_CATEGORY_TYP:LeafCategoryTyp,CATALOG_TYP:CatalogTyp

Here is the JPublisher output, listing the processed types:

OE.COMPOSITE_CATEGORY_TYP
OE.SUBCATEGORY_REF_LIST_TYP
OE.LEAF_CATEGORY_TYP
OE.CATALOG_TYP
OE.CATEGORY_TYP
OE.PRODUCT_REF_LIST_TYP

Note the following:

  • If you want to unparse several types, you can list them all together in the -sql (-s) option, separated by commas, or you can supply several -sql options on the command line, or you can do both.

  • Although JPublisher does not automatically generate wrapper classes for all subtypes, it does generate them for all supertypes.

  • For SQL objects with methods (stored procedures), such as CATALOG_TYP, JPublisher uses SQLJ classes, meaning Java classes that use the SQLJ runtime during execution, to implement the wrapper methods. In Oracle Database 10g, the use of SQLJ classes, as opposed to regular Java classes, is invisible to you unless you use one of the backward compatibility modes.


Note:

In Oracle9i or Oracle8i releases, the generation of SQLJ classes results in the creation of visible .sqlj source files. In this example, it results in .sqlj source files corresponding to CATALOG_TYP and its three subtypes. This is also true in Oracle Database 10g if you set the JPublisher -compatible flag to a value of 8i, both8i, 9i, or sqlj.

For any of these modes, you can use the JPublisher -sqlj option to translate .sqlj files, as an alternative to using the sqlj command-line utility directly.

See "Backward Compatibility Option" and "Option to Access SQLJ Functionality" for information about these options.


If the code that JPublisher generates does not give you the functionality or behavior you want, then you can extend generated wrapper classes to override or complement their functionality. Consider the following example:

% jpub -u OE/OE -s WAREHOUSE_TYP:JPubWarehouse:MyWarehouse

Here is the JPublisher output:

OE.WAREHOUSE_TYP

With this command, JPublisher generates both JPubWarehouse.java and MyWarehouse.java. The file JPubWarehouse.java is regenerated every time you rerun this command. The file MyWarehouse.java is created to be customized by you, and will not be overwritten by future runs of this JPublisher invocation. You can add new methods in MyWarehouse.java, override the method implementations from JPubWarehouse.java, or both. The class that is used to materialize WAREHOUSE_TYP instances in Java is the specialized class MyWarehouse. If you want user-specific subclasses for all types in an object type hierarchy, then you must specify "triplets" of the form SQL_TYPE:JPubClass:UserClass, as shown in the preceding JPublisher command, for all members of the hierarchy.

Once you have generated and compiled Java wrapper classes with JPublisher, using them is fairly straightforward. You can use the object wrappers directly.


Note:

The preceding examples using the OE schema are for illustrative purposes only and may not be completely up-to-date regarding the composition of the schema.

The following SQLJ class calls a PL/SQL stored procedure. Assume that register_warehouse takes a WAREHOUSE_TYP instance as an IN OUT parameter. (A code comment shows the corresponding #sql command. By default, JPublisher generates and translates the SQLJ code automatically.) See the next section, "Publishing PL/SQL Packages", for a discussion of wrapper methods and the problems posed by OUT and IN OUT arguments.

java.math.BigDecimal location = new java.math.BigDecimal(10); 
java.math.BigDecimal warehouseId = new java.math.BigDecimal(10); 
MyWarehouse w = new MyWarehouse(warehouseId,"Industrial Park",location); 
//  ************************************************************
//  #sql { call register_warehouse(:INOUT w) };
//  ************************************************************
//
// declare temps 
oracle.jdbc.OracleCallableStatement __sJT_st = null; 
sqlj.runtime.ref.DefaultContext __sJT_cc =
          sqlj.runtime.ref.DefaultContext.getDefaultContext(); 
if (__sJT_cc==null)
          sqlj.runtime.error.RuntimeRefErrors.raise_NULL_CONN_CTX(); 
sqlj.runtime.ExecutionContext.OracleContext __sJT_ec =
          ((__sJT_cc.getExecutionContext()==null) ?
          sqlj.runtime.ExecutionContext.raiseNullExecCtx() :
          __sJT_cc.getExecutionContext().getOracleContext()); 
try { 
   String theSqlTS = "BEGIN register_warehouse( :1 ) \n; END;"; 
   __sJT_st = __sJT_ec.prepareOracleCall(__sJT_cc,"0RegisterWarehouse",theSqlTS); 
   if (__sJT_ec.isNew()) 
   { 
      __sJT_st.registerOutParameter(1,2002,"OE.WAREHOUSE_TYP"); 
   } 
   // set IN parameters 
   if (w==null) __sJT_st.setNull(1,2002,"OE.WAREHOUSE_TYP"); 
   else __sJT_st.setORAData(1,w); 
   // execute statement 
   __sJT_ec.oracleExecuteUpdate(); 
   // retrieve OUT parameters 
   w = (MyWarehouse)__sJT_st.getORAData(1,MyWarehouse.getORADataFactory()); 
} finally { __sJT_ec.oracleClose(); } 

In JDBC, you typically register the relationship between the SQL type name and the corresponding Java class in the type map for your connection instance. This is required once for each connection, as in the following example:

java.util.Map typeMap = conn.getTypeMap();
typeMap.put("OE.WAREHOUSE_TYP", MyWarehouse.class);
conn.setTypeMap(typeMap);

The following JDBC code is equivalent to the JPublisher output (translated SQLJ code) shown previously:

CallableStatement cs = conn.prepareCall("{call register_warehouse(?)}");
((OracleCallableStatement)cs).registerOutParameter
                 (1, Oracle.jdbc.OracleTypes.STRUCT,"OE.WAREHOUSE_TYP");
cs.setObject(w);
cs.executeUpdate();
w = cs.getObject(1);

Publishing PL/SQL Packages

In addition to mapping SQL objects, you may want to encapsulate entire PL/SQL packages as Java classes. JPublisher offers functionality to create Java wrapper methods for the stored procedures of a PL/SQL package.

The concept of representing PL/SQL stored procedures as Java methods presents a problem, however. Arguments to such functions or procedures may use the PL/SQL mode OUT or IN OUT, but there are no equivalent modes for passing arguments in Java. A method that takes an int argument, for example, is not able to modify this argument in such a way that its callers can receive a new value for it. As a workaround, JPublisher can generate single-element arrays for OUT and IN OUT arguments. For an array int[] abc, for example, the input value is provided in abc[0], and the modified output value is also returned in abc[0]. JPublisher also uses a similar pattern when generating code for SQL object type methods.

For additional information about the array mechanism and other mechanisms for handling OUT or IN OUT parameters, see "JPublisher Treatment of Output Parameters".


Note:

If your stored procedures use types that are specific to PL/SQL and are not supported by JDBC, special steps are required to map these arguments to SQL and then to Java. See "Support for PL/SQL Datatypes".

The following command line publishes the SYS.DBMS_LOB package into Java:

% jpub  -u SCOTT/TIGER  -s SYS.DBMS_LOB:DbmsLob

Here is the JPublisher output:

SYS.DBMS_LOB

Because DBMS_LOB is publicly visible, you can access it from a different schema, such as SCOTT. Note that this JPublisher invocation creates a SQLJ class in DbmsLob.java that contains the calls to the PL/SQL package. The generated Java methods are actually all instance methods. The idea is that you create an instance of the package using a JDBC connection or a SQLJ connection context and then call the methods on that instance.

Use of Object Types Instead of Java Primitive Numbers

When you examine the generated code, notice that JPublisher has generated java.lang.Integer as arguments to various methods. Using Java object types such as Integer instead of Java primitive types such as int permits you to represent SQL NULL values directly as Java nulls, and JPublisher generates these by default. However, for the DBMS_LOB package, int is preferable over the object type Integer. The following modified JPublisher invocation accomplishes this through the -numbertypes option.

% jpub -numbertypes=jdbc  -u SCOTT/TIGER  -s SYS.DBMS_LOB:DbmsLob

Here is the JPublisher output:

SYS.DBMS_LOB

See "Mappings For Numeric Types (-numbertypes)" for information about that option.

Wrapper Class for Procedures at the SQL Top Level

JPublisher also enables you to generate a wrapper class for the functions and procedures at the SQL top level. Use the special package name TOPLEVEL, as in the following example:

% jpub  -u SCOTT/TIGER  -s TOPLEVEL:SQLTopLevel

Here is the JPublisher output:

SCOTT.top-level_scope

A warning appears if there are no stored functions or procedures in the SQL top-level scope.

Publishing Server-Side Java Classes

Oracle Database 10g introduces the native Java interface—new features for calls to server-side Java code. Previously, calling Java stored procedures and functions from a database client required JDBC calls to associated PL/SQL wrappers. Each PL/SQL wrapper had to be manually published with a SQL signature and a Java implementation. This process had the following disadvantages:

  • The signatures permitted only Java types that had direct SQL equivalents.

  • Exceptions issued in Java were not properly returned.

The JPublisher -java option provides functionality to avoid these disadvantages.

To remedy the deficiencies of JDBC calls to associated PL/SQL wrappers, the -java option makes convenient use of an API for direct invocation of static Java methods. This functionality is also useful for Web services.

The functionality of the -java option mirrors that of the -sql option, creating a client-side Java stub class to access a server-side Java class, in contrast to creating a client-side Java class to access a server-side SQL object or PL/SQL package. The client-side stub class mirrors the server-side class and includes the following features:

  • Methods corresponding to the public static methods of the server class

  • Two constructors: one that takes a JDBC connection and one that takes the SQLJ default connection context instance

At runtime, the stub class is instantiated with a JDBC connection. Calls to its methods result in calls to the corresponding methods of the server-side class. Any Java types used in these published methods must be primitive or serializable.

As an example, assume that you want to call the following method in the server:

public String oracle.sqlj.checker.JdbcVersion.to_string();

Use the -java setting in the following JPublisher command:

% jpub -u scott/tiger -url=jdbc:oracle:oci:@ -java=oracle.sqlj.checker.JdbcVersion

Note that for invocation of server-side Java, you must provide information for the database connection.

See "Declaration of Server-Side Java Classes to Translate (-java)" for information about -java option syntax.

Publishing SQL Queries or DML Statements

The JPublisher -sqlstatement option enables you to publish SQL queries (SELECT statements) or DML statements (INSERT, UPDATE, or DELETE statements) as Java methods. This functionality is of potential use for Web services, but is more generally useful as well.

Specify the following through -sqlstatement settings:

  • Java class in which the method will be published (-sqlstatement.class=classname)

  • SQL statement and desired corresponding Java method name (-sqlstatement.methodname=sqlstatement)

  • Whether JPublisher should generate a method that returns a generic java.sql.ResultSet instance, a method that returns an array of JavaBeans, or both methods (-sqlstatement.return=resultset|beans|both)

Consider the following -sqlstatement settings:

-sqlstatement.class=SqlStatement 
-sqlstatement.getEmp="select ename from emp where empno=:{myno NUMBER}"

JPublisher generates a class named SqlStatement with the following method:

public static GetEmpRow[] getEmpBeans(int myno) 
{...}

See "Declaration of SQL Statements to Translate (-sqlstatement)" for syntax information and a complete example.

Publishing Proxy Classes and Wrappers for Web Services Call-Outs

Given a Web Services Description Language (WSDL) document at a specified URL, JPublisher directs the generation of Web services client proxy classes and generates appropriate Java and PL/SQL wrappers for Web services call-outs from the database. Classes to generate and process are determined from the WSDL document. JPublisher executes the following steps:

  1. Invokes the Oracle Database Web services assembler tool to produce Web services client proxy classes based on the WSDL document.

  2. As appropriate or necessary, creates Java wrapper classes for the Web services client proxy classes. For each proxy class that has instance methods (as is typical), a wrapper class is necessary to expose the instance methods as static methods.

  3. Creates PL/SQL wrappers (call specs) for the generated classes, to make them accessible from PL/SQL.

  4. Loads generated code into the database, unless you specify otherwise, and assuming you specify a database to connect to.

See "Options to Facilitate Web Services Call-Outs" for details.

JPublisher Mappings and Mapping Categories

The following sections offer a basic overview of JPublisher mappings and mapping categories:

JPublisher Mappings for User-Defined Types and PL/SQL Types

JPublisher provides mappings from the following to Java classes:

  • User-defined SQL types (objects, collections, and OPAQUE types)

  • PL/SQL types

Representing User-Defined SQL Types Through JPublisher

You can use an Oracle-specific implementation, a standard implementation, or a generic implementation in representing user-defined SQL types—such as objects, collections, object references, and OPAQUE types—in your Java program.

Here is a summary of these three approaches:

  • Use classes that implement the Oracle-specific ORAData interface.

    JPublisher generates classes that implement the oracle.sql.ORAData interface. (You can also write them by hand, but this is generally not recommended.)

    The ORAData interface supports SQL objects, object references, collections, and OPAQUE types in a strongly typed way. That is, for each specific object, object reference, collection, or OPAQUE type in the database, there is a corresponding Java type.

    See the next section, "Using Strongly Typed Object References for ORAData Implementations", for details about strongly typed object reference representations through the ORAData interface.


    Note:

    JPublisher generates classes for object reference, collection, and OPAQUE types only if it is generating ORAData classes.

  • Use classes that implement the standard SQLData interface, as described in the JDBC specification.

    JPublisher generates classes for SQL object types that implement the java.sql.SQLData interface. (You can also write them by hand, but this is generally not recommended. Note that if you write them by hand, or if you generate classes for an inheritance hierarchy of object types, your classes must be registered using a type map.)

    When you use the SQLData interface, all object reference types are represented generically as java.sql.Ref, and all collection types are represented generically as java.sql.Array. In addition, when using SQLData, there is no mechanism for representing OPAQUE types.

  • Use oracle.sql.* classes.

    You can use the oracle.sql.* classes to represent user-defined types generically. The class oracle.sql.STRUCT represents all object types, the class oracle.sql.ARRAY represents all VARRAY and nested table types, the class oracle.sql.REF represents all object reference types, and the class oracle.sql.OPAQUE represents all OPAQUE types. These classes are immutable in the same way that java.lang.String is.

    Choose this option for code that processes objects, collections, references, or OPAQUE types in a generic way. Unlike classes implementing ORAData or SQLData, oracle.sql.* classes are not strongly typed.

In addition to strong typing, JPublisher-generated classes that implement ORAData or SQLData have the following advantages:

  • The classes are customized, rather than generic. You access attributes of an object using getXXX() and setXXX() methods named after the particular attributes of the object. Note that you must explicitly update the object in the database if there are any changes to its data.

  • The classes are mutable. You can generally modify attributes of an object or elements of a collection. The exception is that ORAData classes representing object reference types are not mutable, because an object reference does not have any subcomponents that could be sensibly modified. You can, however, use the setValue() method of a reference object to change the database value that the reference points to.

  • You can generate Java wrapper classes that are serializable or that have the toString() method to print out the object together with its attribute values.

Compared to classes that implement SQLData, classes that implement ORAData are fundamentally more efficient, because ORAData classes avoid unnecessary conversions to native Java types. For additional information about the SQLData and ORAData interfaces, including a comparison, see the Oracle Database JDBC Developer's Guide and Reference.

Using Strongly Typed Object References for ORAData Implementations

For Oracle ORAData implementations, JPublisher always generates strongly typed object reference classes in contrast to using the weakly typed oracle.sql.REF class. This is to provide greater type safety and to mirror the behavior in SQL, in which object references are strongly typed. The strongly typed classes (with names such as PersonRef for references to PERSON objects) are essentially wrappers for the oracle.sql.REF class.

In these strongly typed REF wrappers, a getValue() method produces an instance of the SQL object that is referenced, in the form of an instance of the corresponding Java class (or, in the case of inheritance, perhaps as an instance of a subclass of the corresponding Java class). For example, if there is a PERSON object type in the database, with a corresponding Person Java class, there will also be a PersonRef Java class. The getValue() method of the PersonRef class would return a Person instance containing the data for a PERSON object in the database. In addition, JPublisher also generates a static cast() method on the PersonRef class, permitting you to convert other typed references to a PersonRef instance.

Whenever a SQL object type has an attribute that is an object reference, the Java class corresponding to the object type would have an attribute that is an instance of a Java class corresponding to the appropriate reference type. For example, if there is a PERSON object with a MANAGER REF attribute, then the corresponding Person Java class will have a ManagerRef attribute.

Using PL/SQL Types Through JPublisher

JDBC does not support PL/SQL-specific types—such as the BOOLEAN type, PL/SQL RECORD types, and PL/SQL indexed-by table types—that are used in stored procedures or functions. (One exception is scalar PL/SQL indexed-by tables, which are currently supported in the client-side JDBC OCI driver only.) JPublisher provides the following workarounds for PL/SQL types:

  • JPublisher has a "type map" that you can use to specify the mapping for a PL/SQL type unsupported by JDBC.

  • For PL/SQL RECORD types or indexed-by tables types, you also have the choice of JPublisher automatically creating a SQL object type or SQL collection type, respectively, as a middle step in the mapping.

With either mechanism, JPublisher creates PL/SQL conversion functions or uses predefined conversion functions (typically in the SYS.SQLJUTL package) to convert between a PL/SQL type and a corresponding SQL type. The conversion functions can be used in generated Java code that calls a stored procedure directly, or JPublisher can create a wrapper function around the PL/SQL stored procedure, where generated Java code calls the wrapper function, which calls the conversion functions. Either way, only SQL types are exposed to JDBC.

See "JPublisher User Type Map and Default Type Map" and "Support for PL/SQL Datatypes" for additional information.

JPublisher Mapping Categories

JPublisher offers different categories of datatype mappings from SQL to Java. ("Options for Datatype Mappings" describes JPublisher options to specify these mappings.)

Each type mapping option has at least two possible values: jdbc and oracle. The -numbertypes option has two additional alternatives: objectjdbc and bigdecimal.

The following sections describe these categories of mappings. For more information about datatype mappings, see Chapter 2.

JDBC Mapping

In JDBC mapping, most numeric datatypes are mapped to Java primitive types, such as int and float, and DECIMAL and NUMBER are mapped to java.math.BigDecimal. LOB types and other non-numeric built-in types are mapped to standard JDBC types, such as java.sql.Blob and java.sql.Timestamp. For object types, JPublisher generates SQLData classes. Because predefined datatypes that are Oracle extensions (such as BFILE and ROWID) do not have JDBC mappings, only the oracle.sql.* mapping is supported for these types.

The Java primitive types used in the JDBC mapping do not support null values and do not guard against integer overflow or floating-point loss of precision. If you are using the JDBC mapping and you attempt to call an accessor or method to get an attribute of a primitive type (short, int, float, or double) whose value is null, then an exception is thrown. If the primitive type is short or int, then an exception is thrown if the value is too large to fit in a short or int variable.

Object JDBC Mapping

In Object JDBC mapping, most numeric datatypes are mapped to Java wrapper classes, such as java.lang.Integer and java.lang.Float, and DECIMAL and NUMBER are mapped to java.math.BigDecimal. This differs from the JDBC mapping only in that it does not use primitive types.

When you use the Object JDBC mapping, all your returned values are objects. If you attempt to get an attribute whose value is null, then a null object is returned.

The Java wrapper classes used in the Object JDBC mapping do not guard against integer overflow or floating-point loss of precision. If you call an accessor method to get an attribute that maps to java.lang.Integer, then an exception is thrown if the value is too large to fit.

Object JDBC is the default mapping for numeric types.

BigDecimal Mapping

In BigDecimal mapping, all numeric datatypes are mapped to java.math.BigDecimal. This supports null values and large values.

Oracle Mapping

In Oracle mapping, the numeric, LOB, or other built-in types are mapped to classes in the oracle.sql package. For example, the DATE type is mapped to oracle.sql.DATE, and all numeric types are mapped to oracle.sql.NUMBER. For object, collection, and object reference types, JPublisher generates ORAData classes.

Because the Oracle mapping uses no primitive types, it can represent a null value as a Java null in all cases. Because it uses the oracle.sql.NUMBER class for all numeric types, it can represent the largest numeric values that can be stored in the database.

JPublisher Input and Output

To publish database entities, JPublisher connects to the database and retrieves descriptions of SQL types, PL/SQL packages, or server-side Java classes that you specify on the command line or in an INPUT file. By default, JPublisher connects to the database by using the Oracle JDBC OCI driver, which requires an Oracle client installation, including Oracle Net Services and required support files. If you do not have an Oracle client installation, then JPublisher can use the Oracle JDBC Thin driver.

JPublisher generates a Java class for each SQL type or PL/SQL package that it translates, and each server-side Java class that it processes. Generated classes include code required to read objects from and write objects to the database. When you deploy the generated JPublisher classes, your JDBC driver installation includes all the necessary runtime files. If JPublisher generates wrapper methods for stored procedures, then the classes that it produces use the SQLJ runtime during execution. In this case, which is typical, you must additionally have the SQLJ runtime library runtime12.jar.

When you call a wrapper method on an instance of a class that was generated for a SQL object, the SQL value for the corresponding object is sent to the server along with any IN or IN OUT arguments. Then the method (stored procedure or function) is invoked, and the new object value is returned to the client along with any OUT or IN OUT arguments. Note that this results in a database round trip. If the method call only performs a simple state change on the object, there will be better performance if you write and use equivalent Java that affects the state change locally.

The number of classes that JPublisher produces depends on whether you request ORAData classes or SQLData classes.

To publish external Web services for access from inside a database, JPublisher accesses a specified WSDL document, directs the generation of appropriate client proxy classes, then generates wrapper classes, as necessary, and PL/SQL wrappers to allow Web services call-outs from PL/SQL.

The following subsections go into more detail:

In addition, see "Summary of the Publishing Process: Generation and Use of Output" for a graphical representation of the flow of input and output.

Input to JPublisher

You can specify input options on the command line and in a JPublisher properties file. In addition to producing Java classes for the translated entities, JPublisher writes the names of the translated objects and packages to standard output. "JPublisher Options" describes all the JPublisher options.

In addition, you can use a file known as the JPublisher INPUT file to specify the SQL types, PL/SQL packages, or server-side Java classes that JPublisher should publish. It also controls the naming of the generated packages and classes. "INPUT File Structure and Syntax" describes INPUT file syntax.

To use a properties file to specify option settings, specify the name of the properties file on the command line, using the -props option. JPublisher processes a properties file as if its contents were inserted in sequence on the command line at the point of the -props option. For additional flexibility, properties files can also be SQL script files in which the JPublisher directives are embedded in SQL comments. For more information about properties file and their formats, see "Properties File Structure and Syntax".

Output from JPublisher

This section describes JPublisher output for user-defined object types, user-defined collection types, OPAQUE types, PL/SQL packages, server-side Java classes, and SQL queries or DML statements.


Note:

Be aware that when JPublisher publishes a database entity, such as a SQL type or PL/SQL package, it also generates classes for any types that are referenced by the entity. If, for example, a stored procedure in a PL/SQL package being published uses a SQL object type as an argument, a class will be generated to map to that SQL object type.

Java Output for User-Defined Object Types

When you run JPublisher for a user-defined object type and you request ORAData classes, JPublisher creates the following:

  • An object class that represents instances of the Oracle object type in your Java program

    For each object type, JPublisher generates a type.java file for the class code, such as Employee.java for the Oracle object type EMPLOYEE.

  • Optionally, a stub subclass, named as specified in your JPublisher settings, that you can modify as desired for custom functionality

  • Optionally, an interface for the generated class or subclass to implement

  • A related reference (REF) class for object references

    JPublisher generates a typeRef.java file for the code for the REF class associated with the object type, such as EmployeeRef.java for references of the Oracle object type EMPLOYEE.

  • Java classes for any object or collection or OPAQUE attributes nested directly or indirectly within the top-level object

    This is necessary so that attributes can be materialized in Java whenever an instance of the top-level class is materialized. If an attribute type, such as a SQL OPAQUE type or a PL/SQL type, has been pre-mapped, then JPublisher uses the target Java type from the map.


Notes:


If you request SQLData classes instead, JPublisher does not generate the object reference class and does not generate classes for nested collection attributes or for OPAQUE attributes.

Java Output for User-Defined Collection Types

When you run JPublisher for a user-defined collection type, you must request ORAData classes. JPublisher creates the following:

  • A collection class to act as a type definition to correspond to your Oracle collection type

    For each collection type (nested table or VARRAY) it translates, JPublisher generates a type.java file. For nested tables, the generated class has methods to get and set the nested table as an entire array and to get and set individual elements of the table. JPublisher translates collection types when generating ORAData classes, but not when generating SQLData classes.

  • If the elements of the collection are objects, a Java class for the element type, and Java classes for any object or collection attributes nested directly or indirectly within the element type

    This is necessary so object elements can be materialized in Java whenever an instance of the collection is materialized.

  • Optionally, an interface that is implemented by the generated type


Note:

Unlike for object types, you do not have the option of generating user subclasses for collection types.

Java Output for OPAQUE Types

When you run JPublisher for an OPAQUE type, you must request ORAData classes. JPublisher creates a Java class that acts as a wrapper for the OPAQUE type, providing Java versions of the OPAQUE type methods as well as protected APIs to access the representation of the OPAQUE type in a subclass.

Typically, however, Java wrapper classes for SQL OPAQUE types are furnished by the provider of the OPAQUE type, such as, for example, oracle.xdb.XMLType for the SQL OPAQUE type SYS.XMLTYPE. In this case, ensure that the correspondence between the SQL type and the Java type is predefined to JPublisher through the type map.

Java Output for PL/SQL Packages

When you run JPublisher for a PL/SQL package, it creates a Java class with wrapper methods that invoke the stored procedures of the package on the server. IN arguments for the methods are transmitted from the client to the server, and OUT arguments and results are returned from the server to the client.

Java Output for Server-Side Java Classes and Web Services Call-Outs

When you run JPublisher for a general-use server-side Java class, it creates source code, type.java, for a client-side stub class that mirrors the server class. When you call the client-side methods, the corresponding server-side methods are called transparently.

For Web services call-outs, JPublisher typically generates wrapper classes for the server-side client proxy classes, as a bridge to the corresponding PL/SQL wrappers. This is necessary to publish any proxy class instance methods as static methods, because PL/SQL does not support instance methods.

Java Output for SQL Queries or DML Statements

When you run JPublisher for a SQL query or DML statement (SELECT, UPDATE, INSERT, or DELETE), it creates the following:

  • A Java class that implements the method that executes the SQL statement

  • Optionally, a Java stub subclass, named as specified in your JPublisher settings, that you can modify as desired for custom functionality

  • Optionally, a Java interface for the generated class or subclass to implement

PL/SQL Output

Depending on your usage, JPublisher may generate a PL/SQL package and associated PL/SQL scripts.

PL/SQL Package

JPublisher typically generates a PL/SQL package with PL/SQL code for any of the following:

  • PL/SQL call specs for generated Java methods

  • PL/SQL conversion functions and wrapper functions to support PL/SQL types

  • PL/SQL table functions

Conversion functions, and optionally wrapper functions, are employed to map PL/SQL types used in the calling sequences of any stored procedures that JPublisher translates. The functions convert between PL/SQL types and corresponding SQL types, given that JDBC does not generally support PL/SQL types.

PL/SQL Scripts

JPublisher generates PL/SQL scripts as follows:

  • A "wrapper script" to create the PL/SQL package and any necessary SQL types

  • A script to grant permission to execute the wrapper script

  • A script to revoke permission to execute the wrapper script

  • A script to drop the package and types created by the wrapper script

JPublisher Operation

This section discusses the basic steps in using JPublisher, summarizes the command-line syntax, and concludes with a more detailed description of a sample translation. The following topics are covered:

Summary of the Publishing Process: Generation and Use of Output

This section lists the basic steps, illustrated in Figure 1-1 that follows, for publishing specified SQL types, PL/SQL packages, or server-side Java classes.

  1. Run JPublisher with input from the command line, properties file, and INPUT file, as desired.

  2. JPublisher accesses the database to which it is attached to obtain definitions of SQL or PL/SQL entities that you specified for publishing.

  3. JPublisher generates .java or .sqlj source files, as appropriate, depending primarily on whether wrapper methods are created for stored procedures.

  4. By default, JPublisher invokes the SQLJ translator (provided as part of the JPublisher product) to translate .sqlj files into .java files.

  5. By default, the SQLJ translator (or JPublisher, for non-SQLJ classes) invokes the Java compiler to compile .java files into .class files.

  6. JPublisher outputs PL/SQL wrappers and scripts (.sql files), as appropriate, in addition to the .class files. There is a script to create the PL/SQL wrapper package and any necessary SQL types (such as types to map to PL/SQL types), a script to drop these entities, and scripts to grant or revoke required privileges.

  7. In the case of proxy class generation (through the -proxywsdl or -proxyclasses option), JPublisher can load generated PL/SQL wrappers and scripts into the database to which it is connected, for execution in the database PL/SQL engine.

  8. By default, JPublisher loads generated Java classes for Web services call-outs into the database to which it is connected, for execution in the database JVM. JPublisher-generated classes other than those for Web services call-outs typically execute in a client or middle-tier JVM. You may also have your own classes, such as subclasses of JPublisher-generated classes, that would typically execute in a client or middle-tier JVM.

Figure 1-1 Translating and Using JPublisher-Generated Code

Description of O_1094.gif follows
Description of the illustration O_1094.gif

JPublisher Command-Line Syntax

On most operating systems, you invoke JPublisher on the command line, typing jpub followed by a series of options settings, as follows:

% jpub -option1=value1 -option2=value2 ...

JPublisher responds by connecting to the database and obtaining the declarations of the types or packages you specify, then generating one or more custom Java classes (SQLJ classes or non-SQLJ classes, as appropriate) and writing the names of the translated object types or PL/SQL packages to standard output.

Here is an example of a (single wraparound) command that invokes JPublisher:

% jpub -user=scott/tiger -input=demoin -numbertypes=oracle -usertypes=oracle
       -dir=demo -d=demo -package=corp

Enter the command on one command line, allowing it to wrap as necessary. For clarity, this chapter refers to the input file specified by the -input option as the INPUT file (to distinguish it from any other kinds of input files).

This command directs JPublisher to connect to the database with user name SCOTT and password TIGER and to translate datatypes to Java classes, based on instructions in the INPUT file demoin. The -numbertypes=oracle option directs JPublisher to map object attribute types to Java classes supplied by Oracle, and the -usertypes=oracle option directs JPublisher to generate Oracle-specific ORAData classes. JPublisher places the classes that it generates in the package corp under the directory demo.

JPublisher also supports specification of .java files (or .sqlj files, if you are using SQLJ source files directly) on the JPublisher command line. The specified files are translated and compiled in addition to any JPublisher-generated files. For example:

% jpub ...options... Myclass.java


Notes:

  • No spaces are permitted around equals signs (=) in a JPublisher command line.

  • If you execute JPublisher without any command-line input, it displays an option list and then terminates.


Sample JPublisher Translation

This section provides a sample JPublisher translation of a user-defined object type. At this point, do not worry about the details of the code JPublisher generates. You can find more information about JPublisher input and output files, options, datatype mappings, and translation later in this manual.


Note:

For more examples, go to ORACLE_HOME/sqlj/demo/jpub in your Oracle installation.

Create the object type EMPLOYEE:

CREATE TYPE employee AS OBJECT
(
    name       VARCHAR2(30),
    empno      INTEGER,
    deptno     NUMBER,
    hiredate   DATE,
    salary     REAL
);

The INTEGER, NUMBER, and REAL types are all stored in the database as NUMBER types, but after translation they have different representations in the Java program, based on your setting of the -numbertypes option.

Assume JPublisher translates the types according to the following (wraparound) command line:

% jpub -user=scott/tiger -dir=demo -numbertypes=objectjdbc -builtintypes=jdbc
       -package=corp -case=mixed -sql=Employee

"JPublisher Options" describes each of these options in detail.

Note that because the EMPLOYEE object type does not define any methods, JPublisher generates a non-SQLJ class.

Because -dir=demo and -package=corp were specified on the JPublisher command line, the translated class Employee is written to Employee.java in the following location (for a UNIX system):

./demo/corp/Employee.java

The Employee.java class file would contain the code shown in the following example.


Note:

The details of the code JPublisher generates are subject to change. In particular, non-public methods, non-public fields, and all method bodies may be generated differently.

package corp;

import java.sql.SQLException;
import java.sql.Connection;
import oracle.jdbc.OracleTypes;
import oracle.sql.ORAData;
import oracle.sql.ORADataFactory;
import oracle.sql.Datum;
import oracle.sql.STRUCT;
import oracle.jpub.runtime.MutableStruct;

public class Employee implements ORAData, ORADataFactory
{
  public static final String _SQL_NAME = "SCOTT.EMPLOYEE";
  public static final int _SQL_TYPECODE = OracleTypes.STRUCT;

  protected MutableStruct _struct;

  private static int[] _sqlType =  { 12,4,2,91,7 };
  private static ORADataFactory[] _factory = new ORADataFactory[5];
  protected static final Employee _EmployeeFactory = new Employee(false);

  public static ORADataFactory getORADataFactory()
  { return _EmployeeFactory; }

  /* constructor */
  protected Employee(boolean init)
  { if(init) _struct = new MutableStruct(new Object[5], _sqlType, _factory); }
  public Employee()
  { this(true); }
  public Employee(String name, Integer empno, java.math.BigDecimal deptno,
                  java.sql.Timestamp hiredate, Float salary) 
   throws SQLException
  { this(true);
    setName(name);
    setEmpno(empno);
    setDeptno(deptno);
    setHiredate(hiredate);
    setSalary(salary);
  }

  /* ORAData interface */
  public Datum toDatum(Connection c) throws SQLException
  {
    return _struct.toDatum(c, _SQL_NAME);
  }

  /* ORADataFactory interface */
  public ORAData create(Datum d, int sqlType) throws SQLException
  { return create(null, d, sqlType); }
  protected ORAData create(Employee o, Datum d, int sqlType) throws SQLException
  {
    if (d == null) return null; 
    if (o == null) o = new Employee(false);
    o._struct = new MutableStruct((STRUCT) d, _sqlType, _factory);
    return o;
  }
  /* accessor methods */
  public String getName() throws SQLException
  { return (String) _struct.getAttribute(0); }

  public void setName(String name) throws SQLException
  { _struct.setAttribute(0, name); }

  public Integer getEmpno() throws SQLException
  { return (Integer) _struct.getAttribute(1); }

  public void setEmpno(Integer empno) throws SQLException
  { _struct.setAttribute(1, empno); }

  public java.math.BigDecimal getDeptno() throws SQLException
  { return (java.math.BigDecimal) _struct.getAttribute(2); }

  public void setDeptno(java.math.BigDecimal deptno) throws SQLException
  { _struct.setAttribute(2, deptno); }

  public java.sql.Timestamp getHiredate() throws SQLException
  { return (java.sql.Timestamp) _struct.getAttribute(3); }

  public void setHiredate(java.sql.Timestamp hiredate) throws SQLException
  { _struct.setAttribute(3, hiredate); }

  public Float getSalary() throws SQLException
  { return (Float) _struct.getAttribute(4); }

  public void setSalary(Float salary) throws SQLException
  { _struct.setAttribute(4, salary); }

}

Code Generation Notes
  • JPublisher also generates object constructors based on the object attributes.

  • Additional private or public methods may be generated with other option settings. For example, the setting -serializable=true results in the object wrapper class implementing the interface java.io.Serializable and in the generation of private writeObject() and private readObject() methods. The setting -tostring=true results in the additional generation of a public toString() method.

  • There is a protected _struct field in JPublisher-generated code for SQL object types. This is an instance of the internal class oracle.jpub.runtime.MutableStruct; this instance contains the data in original SQL format. In general, you should never reference this field directly. Instead, use the setting -methods=always or -methods=named, as necessary, to ensure that JPublisher produces setFrom() and setValueFrom() methods, then use these methods when extending a class. See "The setFrom(), setValueFrom(), and setContextFrom() Methods".

  • JPublisher generates SQLJ classes instead of non-SQLJ classes in the following circumstances:

    • The SQL object being published has methods, and the setting -methods=false is not specified.

    • A PL/SQL package, stored procedure, query, or DML statement is published, and the setting -methods=false is not specified.

    Additionally:

    • If a SQLJ class is created for a type definition, then a SQLJ class is also created for the corresponding REF definition.

    • If a SQLJ class is created for a base class, then SQLJ classes are also created for any subclasses.

    (In a backward compatibility mode, this means that JPublisher generates .sqlj files instead of .java files.)

  • Note that the JPublisher version provided with Oracle8i generates implementations of the now-deprecated CustomDatum and CustomDatumFactory interfaces, instead of ORAData and ORADataFactory. In fact, it is still possible to do this through the JPublisher -compatible option, and this is required if you are using an Oracle8i JDBC driver.

JPublisher also generates an EmployeeRef.java class. The source code is displayed here:

package corp;

import java.sql.SQLException;
import java.sql.Connection;
import oracle.jdbc.OracleTypes;
import oracle.sql.ORAData;
import oracle.sql.ORADataFactory;
import oracle.sql.Datum;
import oracle.sql.REF;
import oracle.sql.STRUCT;

public class EmployeeRef implements ORAData, ORADataFactory
{
  public static final String _SQL_BASETYPE = "SCOTT.EMPLOYEE";
  public static final int _SQL_TYPECODE = OracleTypes.REF;

  REF _ref;

private static final EmployeeRef _EmployeeRefFactory = new EmployeeRef();

  public static ORADataFactory getORADataFactory()
  { return _EmployeeRefFactory; }
  /* constructor */
  public EmployeeRef()
  {
  }

  /* ORAData interface */
  public Datum toDatum(Connection c) throws SQLException
  {
    return _ref;
  }

  /* ORADataFactory interface */
  public ORAData create(Datum d, int sqlType) throws SQLException
  {
    if (d == null) return null;
    EmployeeRef r = new EmployeeRef();
    r._ref = (REF) d;
    return r;
  }

  public static EmployeeRef cast(ORAData o) throws SQLException
  {
     if (o == null) return null;
     try { return (EmployeeRef) getORADataFactory().create(o.toDatum(null),
           OracleTypes.REF); }
     catch (Exception exn)
     { throw new SQLException("Unable to convert "+o.getClass().getName()+" to
             EmployeeRef: "+exn.toString()); }
  }

  public Employee getValue() throws SQLException
  {
     return (Employee) Employee.getORADataFactory().create(
       _ref.getSTRUCT(), OracleTypes.REF);
  }

  public void setValue(Employee c) throws SQLException
  {
    _ref.setValue((STRUCT) c.toDatum(_ref.getJavaSqlConnection()));
  }
}

Note that JPublisher also generates a public static cast() method to cast from other strongly typed references into a strongly typed reference instance.