4 Additional Features and Considerations

This chapter covers additional features and considerations for your use of JPublisher:

Summary of JPublisher Support for Web Services

The following sections summarize key JPublisher features for Web services. Most features relate to Web services call-ins to the database, covering JPublisher features that make SQL, PL/SQL, and server-side Java classes accessible to Web services clients. There are also features and options to support Web services call-outs from the database.

See Also:

Summary of Support for Web Services Call-Ins to the Database

The following JPublisher features support Web services call-ins to code running in Oracle Database. The generated Java class can then be deployed in Oracle Application Server, using the Java EE container. For example, a Java class representing a PL/SQL package can be deployed as a PL/SQL Web Service.

  • Generation of Java interfaces

    By using extended functionality of the -sql option, JPublisher can generate Java interfaces. This functionality eliminates the necessity to manually generate Java interfaces that represent the application programming interface (API) from which Web Services Description Language (WSDL) content is to be generated. Prior to Oracle Database 10g, JPublisher could generate classes but not interfaces.

  • JPublisher styles and style files

    Style files, along with the related -style option, enable Java-to-Java type mappings that ensure that generated classes can be used in Web services. In particular, Oracle provides the following style files to support Web services:

    /oracle/jpub/mesg/webservices-common.properties
    /oracle/jpub/mesg/webservices10.properties
    /oracle/jpub/mesg/webservices9.properties
    
  • REF CURSOR returning and result set mapping

    The java.sql.ResultSet type is not supported by Web services, which affects stored procedures and functions that return REF CURSOR types. JPublisher supports alternative mappings that allow the use of query results with Web services.

  • Options to filter what JPublisher publishes

    There are several features for specifying or filtering JPublisher output, particularly to ensure that JPublisher-generated code can be exposed as Web services. By using the extended functionality of the -sql option, you can publish a specific subset of stored procedures. Using the -filtertypes and -filtermodes options, you can publish stored procedures based on the modes or types of parameters or return values. Using the -generatebean option, you can specify that generated methods satisfy the JavaBeans specification.

  • Support for calling Java classes in the database

    JPublisher uses the native Java interface for calls directly from a client-side Java stub, generated by JPublisher through the -java option, to the server-side Java code. Prior to Oracle Database 10g, server-side Java code could be called only through a PL/SQL wrapper that had to be created manually. This PL/SQL wrapper was also known as a call spec. Since Oracle Database 10g release 2 (10.2), Web services call-ins of Java classes are supported in two modes, dynamic invocation mode and PL/SQL wrapper mode.

  • Support for publishing SQL queries or DML statements

    JPublisher provides the -sqlstatement option to take a particular SELECT, UPDATE, INSERT, or DELETE statement and publish it as a method on a Java class that can be published as a Web service.

  • Support for unique method names

    To meet Web services requirements, you can instruct JPublisher to disallow overloaded methods and always use unique method names instead.

Support for Web Services Call-Outs from the Database

JPublisher supports Web services call-outs from Oracle Database. The Web services client code is written in SQL, PL/SQL, or Java and it runs on the database and invokes Web services elsewhere. This support is provided through the -proxywsdl and -httpproxy options. In addition, the -proxyopts and -proxyclasses options may possibly be relevant, but typically do not require any special settings for Web services.

Here is a summary of the key options:

  • -proxywsdl=URL

    Use this option to generate Web services client proxy classes, given the WSDL document at the specified URL. This option also generates additional wrapper classes to expose instance methods as static methods and generates PL/SQL wrappers.

  • -httpproxy=proxy_URL

    Where, a WSDL document is accessed through a firewall. Use this option to specify a proxy URL to use in resolving the URL of the WSDL document.

How to Perform Web Services Call-Out using Static Proxy and JPublisher

The Oracle JPublisher command line option -proxywsdl can be used to generate database-side Java and PL/SQL wrappers from the WSDL file of a Web service. To allow JPublisher to generate and load wrappers for Web service clients into the database, the dbwsa.jar and dbwsclient.jar files must be present in the classpath and inside the database respectively.

The following procedure sets up the environment and the database for Oracle JPublisher-supported Web service call-out. This procedure needs to be performed only once.

  1. Download and install Oracle JPublisher 12c Release 1, if it is not already present on your system. Oracle JPublisher is installed as part of Oracle SQLJ installation. You can install Oracle SQLJ from the Database Client CD or from the Database Client download available at

    http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html

  2. Add the dbwsa.jar to the directory ORACLE_HOME\sqlj\lib (Microsoft Windows) or ORACLE_HOME/sqlj/lib (Solaris).

  3. Set up the appropriate JDK as the Java VM and Java compiler.

    The version of the JDK must be the same as the Java VM in the target database:

    • Use JDK 6 and JDK 7 for Oracle Database 12c

    • Use JDK 1.5 and JDK 6 for Oracle Database 11g

  4. Add dbwsa.jar file to the classpath environment variable.

  5. Load the dbwsclient.jar file either into the SYS schema or into the schema where the Web service client will be invoked.

    For example, the following loadjava command will load the dbwsclient.jar file into the SYS schema.

    %loadjava -u sys -r -v -f -s -grant public -noverify -genmissing dbwsclient.jar
    Password: password
    

    The following loadjava command illustrates how to load the dbwsclient.jar file into a specific schema.

    % loadjava -u hr -r -v -f -noverify -genmissing dbwsclient.jar
    Password: password
    

Example

The following example illustrates how to generate Java and PL/SQL wrappers for a Web service client and then invoke it by using SQL statements. The example follows these general steps:

  1. Identify the Web service you want to invoke.

  2. Call Oracle JPublisher with the appropriate options to generate the client proxy, the PL/SQL and Java wrappers, and load them into the database.

    An Oracle JPublisher command to do this would include the required -proxywsdl and -user options. The command could also include the optional -endpoint, -httpproxy, -sysuser, -dir, and -proxyopts options. For example:

    % jpub -user=username -sysuser=sysuser_name/sysuser_password -proxywsdl=WSDL_URL -endpoint=Web_services_endpoint
    

    It is assumed that the Web service has been previously deployed at http://localhost:8888/javacallout/javacallout

    The following command creates the Web service client and its Java and PL/SQL wrappers in the subdirectory tmp, then loads the wrappers into the database.

    % jpub -user hr -sysuser sys/sys_password -proxywsdl=sample/javacallout.wsdl
       -endpoint=http://localhost:8888/javacallout/javacallout -dir=tmp
    Enter hr password: password
    

    This command produces the following output:

    tmp/HelloServiceEJBJPub.java
    tmp/plsql_wrapper.sql
    tmp/plsql_dropper.sql
    tmp/plsql_grant.sql
    tmp/plsql_revoke.sql
    Executing tmp/plsql_dropper.sql
    Executing tmp/plsql_wrapper.sql
    Executing tmp/plsql_grant.sql
    Loading tmp/plsql_proxy.jar
    
  3. Invoke the Web service from inside the database.

    You can invoke the PL/SQL functions provided in tmp/plsql_wrapper.sql. Each PL/SQL function corresponds to an operation in the Web service. For example, if your Web service is available at the following endpoint:

    http://localhost:8888/javacallout/javacallout
    

    Then you can issue the following SQL command.

    SQL> select jpub_plsql_wrapper.sayhello('hello') from dual;
    

    The command will return the following output.

    JPUB_PLSQL_WRAPPER.SAYHELLO('HELLO')
    -----------------------------------
    HELLO!! You just said :hello
    

Server-Side Java Invocation (Call-in)

The server-side Java call-in functionality allows JPublisher to publish Java classes in the database for client-side invocation. JPublisher generates Java clients to invoke server-side Java.

In Oracle Database 10g release 1 (10.1), the JPublisher option for server-side call-in is -java. JPublisher generates a Java client that uses the dynamic invocation interface, oracle.jpub.runtime.Client, that is provided in the JPublisher run time, to invoke the oracle.jpub.runtime.Server server-side class, which in turn calls the desired Java stored procedure. The Client and Server interfaces are a part of the JPublisher run time. Only static methods with serializable parameters and return types are supported. Beginning with Oracle Database 10g release 1 (10.1), oracle.jpub.runtime.Server is located in the database.

In Oracle Database 10g release 2 (10.2), for server-side call-ins, JPublisher generates a PL/SQL wrapper for the stored procedure and the Java client that calls this PL/SQL wrapper. It supports both static and instance methods. The parameter and return types supported are primitive types, Java Beans, Serializable objects, and Oracle Java Database Connectivity (JDBC) types, typically those with the package name oracle.sql.

In Oracle Database 10g release 2 (10.2), the -java option is deprecated and the JPublisher option for server-side call-in is -dbjava. However, the -java option is still supported for backward compatibility. When the -compatible option is set to 10.1, -dbjava acts same as -java.

Features to Filter JPublisher Output

JPublisher provides some options that allow you to filter what JPublisher produces. For example, publishing just a subset of stored procedures from a package, filtering generated code according to parameter modes or parameter types, and ensuring that generated classes follow the JavaBeans specification.

The following sections provide details:

Publishing a Specified Subset of Functions or Procedures

Extended functionality of the -sql option enables you to publish just a subset of the stored functions or procedures from a package or from the SQL top level.

Recall that the following syntax results in publication of all the stored procedures of a package:

-sql=plsql_package

To publish only a subset of the stored procedures of the package, use the following syntax:

-sql=plsql_package(proc1+proc2+proc3+...)

You can also specify the subset according to stored procedure names and argument types. Instead of just specifying proc1, you can specify the following:

proc1(sqltype1, sqltype2, ...)

Publishing Functions or Procedures According to Parameter Modes or Types

In some cases, particularly for code generation for Web services, not all parameter modes or types are supported in method signatures or attributes for the target usage of your code. The -filtermodes and -filtertypes options are introduced to allow you to filter generated code as needed, according to parameter modes, parameter types, or both.

For each option setting, start with a 1 to include all possibilities by default, that is no filtering is done. Then list specific modes or types that you want to exclude each followed by a minus sign (-). For example:

-filtertypes=1,.ORADATA-,.ORACLESQL-

-filtermodes=1,out-,inout-

Alternatively, you can start with a 0 to filter everything out. Then list specific modes or types that you want to allow each followed by a plus sign (+). For example:

-filtertypes=0,.CURSOR+,.INDEXBY+

-filtermodes=0,in+,return+

Ensuring that Generated Methods Adhere to the JavaBeans Specification

The -generatebean option is a flag that you can use to ensure that generated classes follow the JavaBeans specification. The default setting is -generatebean=false.

With the -generatebean=true setting, some generated methods are renamed so that they are not assumed to be JavaBean property getter or setter methods. This is accomplished by prefixing the method names with an underscore (_).

Backward Compatibility and Migration

This section discusses issues of backward compatibility, compatibility between Java Development Kit (JDK) versions, and migration between Oracle8i, Oracle9i, Oracle Database 10g, and Oracle Database 12c releases of the JPublisher utility.

Default option settings and some features of the generated code changed in Oracle9i. If you have created an application using an Oracle8i implementation of JPublisher, you probably will not be able to rerun JPublisher in Oracle Database 10g (or Oracle9i) and have the generated classes still work within your application. In addition, there were changes in JPublisher functionality between Oracle9i and Oracle Database 10g, although to a lesser degree. The main difference is that .sqlj files are no longer visibly generated by default, but you can change this behavior through a JPublisher setting.

The following subsections cover the details:

JPublisher Backward Compatibility

The JPublisher run time is packaged with JDBC in the ojdbc14.jar, ojdbc5.8.jar, or ojdbc6*.jar library. Code generated by an earlier version of JPublisher is compatible as follows:

  • It can continue to run with the current release of the JPublisher run time.

  • It can continue to compile against the current release of the JPublisher run time.

If you use an earlier release of the JPublisher run time and Oracle JDBC drivers in generating code, then you can compile the code against that version of the JPublisher run time.

Changes in JPublisher Behavior Between Oracle Database 10g Release 1 and Release 2

Since Oracle Database 10g release 2 (10.2), JPublisher adds the following new APIs for Java classes generated for PL/SQL:

  • <init>(javax.sql.DataSource)

    A constructor that takes a java.sql.DataSource object as argument

  • setDataSource(javax.sql.DataSource)

    A method to set the data source that takes a java.sql.DataSource object as argument

These methods allow the Java wrapper to acquire a JDBC connection from the data source provided as argument.

JPublisher supports the use of SQL URI types that store URLs, referred to as data links. In Oracle Database 10g release 1 (10.1), JPublisher maps the SQL URI type, SYS.URITYPE, and the subtypes, SYS.DBURITYPE, SYS.XDBURITYPE, and SYS.HTTPURITYPE, to java.net.URL. When SQL URI types are used as PL/SQL stored procedures or SQL statement parameter and return types, this mapping works. However, when a SQL URI type is used as an attribute of a SQL type or element of a SQL array type, the mapping raises ClassCastException at run time.

To overcome this issue, in Oracle Database 10g release 2 (10.2), the SQL URI types are mapped to the ORAData subclasses that are generated by JPublisher. This is similar to the mapping used for user-defined SQL object types. You can also force JPublisher to map a SQL URI type to java.net.URL by specifying the following:

-adddefaulttypemap=
SYS.URITYPE:java.net.URL:VARCHAR2:SYS.URIFACTORY.GETURI:SYS.SQLJUTL.URI2VCHAR
-adddefaulttypemap=
SYS.DBURITYPE:java.net.URL:VARCHAR2:SYS.DBURITYPE.CREATEURI:SYS.SQLJUTL.URI2VCHAR
-adddefaulttypemap=
SYS.XDBURITYPE:java.net.URL:VARCHAR2:SYS.XDBURITYPE.CREATEURI:SYS.SQLJUTL.URI2VCHAR
-adddefaulttypemap=
SYS.HTTPURITYPE:java.net.URL:VARCHAR2:SYS.HTTPURITYPE.CREATEURI:SYS.SQLJUTL.URI2VCHAR

This includes the specification of data conversion functions.

Changes in JPublisher Behavior Between Oracle9i Database and Oracle Database 10g

Regarding backward compatibility, a key difference in JPublisher behavior between Oracle9i Database and Oracle Database 10g is that now, by default, SQLJ source code is translated automatically and the .sqlj source files are invisible to the user.

In addition, note the following changes in JPublisher behavior in Oracle Database 10g:

  • In Oracle9i Database, JPublisher generates SQLJ classes with a protected constructor with a boolean argument to specify whether the object must be initialized. For example:

    protected BaseClass(boolean init) { ... }
    

    This constructor is removed in Oracle Database 10g because it conflicts with the constructor generation for a SQL object type with BOOLEAN attributes.

  • In Oracle Database 10g, SMALLINT is mapped to int instead of short in Java.

Changes in JPublisher Behavior Between Oracle8i Database and Oracle9i Database

Note the following changes in JPublisher behavior, beginning with Oracle9i Database:

  • By default, JPublisher does not declare the inner SQLJ connection context class _Ctx for every object type. Instead, it uses the sqlj.runtime.ref.DefaultContext connection context class throughout.

    In addition, user-written code must call the getConnectionContext() method to have a connection context instance, instead of using the _ctx connection context field declared in code generated by Oracle8i versions of JPublisher.

  • Even with the -methods=true setting, non-SQLJ classes are generated if the underlying SQL object type or PL/SQL package does not define any methods. However, a setting of -methods=always always results in SQLJ classes being produced.

  • By default, JPublisher generates code that implements the oracle.sql.ORAData interface instead of the deprecated oracle.sql.CustomDatum interface.

  • By default, JPublisher places generated code into the current directory, rather than into a package/directory hierarchy under the current directory.

Changes in User-Written Subclasses of JPublisher-Generated Classes

If you provided user-written subclasses for classes generated by an Oracle8i version of JPublisher, then you must be aware that several relevant changes were introduced in Oracle9i Database related to JPublisher code generation. You must make changes in any applications that have Oracle8i functionality if you want to use them in Oracle9i Database, Oracle Database 10g, or Oracle Database 12c.

Note:

If you use the -compatible=8i or -compatible=both8i option setting, then you will not see the changes discussed here and your application will continue to build and work as before. For more information, refer to "Backward Compatibility Option".

However, it is advised that you make the transition to Oracle Database 12c or Oracle Database 10g JPublisher functionality, which insulates your user code from implementation details of JPublisher-generated classes.

You must make the following changes to use your code in Oracle9i Database, Oracle Database 10g, or Oracle Database 12c:

  • Replace any use of the declared _ctx connection context field with use of the provided getConnectionContext() method. The _ctx field is no longer supported.

  • Replace the explicit implementation of the create() method with a call to a superclass create() method, and use ORAData instead of CustomDatum as the return type.

    In the example that follows, assume that UserClass extends BaseClass. Instead of writing the following method in UserClass:

    public CustomDatum create(Datum d, int sqlType) throws SQLException
    {
      if (d == null) return null;
      UserClass o = new UserClass();
      o._struct = new MutableStruct((STRUCT) d, _sqlType, _factory);
      o._ctx = new _Ctx(((STRUCT) d).getConnection());
      return o;
    }
    

    Supply the following:

    public ORAData create(Datum d, int sqlType) throws SQLException
    {
      return create(new UserClass(),d,sqlType);
    }
    

    Alternatively, if the class is part of an inheritance hierarchy, then write the following:

    protected ORAData createExact(Datum d, int sqlType) throws SQLException
    {
      return create(new UserClass(),d,sqlType);
    }
    
  • In addition to the getConnectionContext() method, JPublisher provides a getConnection() method that can be used to obtain the JDBC connection instance associated with the object.

JPublisher Backward-Compatibility Modes and Settings

JPublisher supports settings for backward-compatibility modes through the -compatible option. At the most elementary level, this includes a setting to explicitly generate .sqlj files, which are transparent to users in Oracle Database 12c and Oracle Database 10g by default. There are also Oracle9i and Oracle8i compatibility modes, involving differences in the generated code itself as well as the creation of visible .sqlj files. The following topics are discussed:

Explicit Generation of .sqlj Files

In Oracle Database 12c, if you want to avoid automatic SQLJ translation so that JPublisher generates .sqlj files that you can work with directly, then you can use the -compatible=sqlj JPublisher setting.

Note:

In Oracle Database 12c, you do not have to invoke the SQLJ translator directly to explicitly translate .sqlj files. You can use the JPublisher -sqlj option instead.

Oracle9i Compatibility Mode

The -compatible=9i JPublisher option setting enables Oracle9i compatibility mode. In this mode, JPublisher generates code that is compatible with Oracle9i SQLJ and JDBC releases. In addition, JPublisher typically produces .sqlj files that are visible to the user, as is the case with Oracle9i JPublisher.

JPublisher has the following functionality in Oracle9i compatibility mode:

  • In SQLJ classes, JPublisher generates a protected constructor with a boolean argument that specifies whether the object must be initialized, as it does in Oracle9i:

    protected BaseClass(boolean init) { ... }
    

    This constructor has neen removed since Oracle Database 10g

  • The mapping in Java from SMALLINT reverts from int, which is the mapping in Oracle Database 12c, to short.

Oracle8i Compatibility Mode

Either the -compatible=both8i or -compatible=8i JPublisher setting enables Oracle8i compatibility mode. In this mode, JPublisher generates code that is compatible with Oracle8i SQLJ and JDBC releases. In addition, JPublisher typically produces .sqlj files visible to the user, as is the case with Oracle8i JPublisher.

However, for the use of this mode to be permissible, at least one of the following circumstances must hold:

  • You translate JPublisher-generated .sqlj files with the default SQLJ -codegen=oracle setting.

  • The JPublisher-generated code runs under JDK 1.5 or later and uses the SQLJ runtime12.jar library or runs in the Oracle Database 12c release of the server-side Oracle JVM.

  • You run JPublisher with the -methods=false or -methods=none setting.

Note the following functionality in Oracle8i compatibility mode:

  • JPublisher generates code that implements the deprecated CustomDatum and CustomDatumFactory interfaces instead of the ORAData and ORADataFactory interfaces, as with the -compatible=customdatum setting. In addition, if you choose the -compatible=both8i setting, then the generated code also implements the ORAData interface, though not ORADataFactory.

  • With the -methods=true setting, JPublisher always generates a SQLJ class for a SQL object type, even if the object type does not define any methods. This is the same as using the -methods=always setting.

  • JPublisher generates connection context declarations and connection context instances on every object wrapper class, as follows:

    #sql static context _Ctx;
    protected _Ctx _ctx;
    

    This is the same as the -context=generated setting.

  • JPublisher provides a constructor in the wrapper class that takes a generic ConnectionContext instance, which is an instance of any class implementing the standard sqlj.runtime.ConnectionContext interface, as input. In Oracle Database 12c, the constructor accepts only a DefaultContext instance or an instance of the class specified through the -context option when JPublisher was run.

  • JPublisher does not provide an API for releasing a connection context instance that has been created implicitly on a JPublisher object.

    By contrast, the JPublisher utility in Oracle Database 12c provides both a setConnectionContext() method for explicitly setting the connection context instance for an object, and a release() method for releasing an implicitly created connection context instance of an object.

If you must choose Oracle8i compatibility mode, then it is advisable to use the -compatible=both8i setting. This permits your application to work in a middle-tier environment, such as Oracle Application Server, in which JDBC connections are obtained through data sources and will likely be wrapped using oracle.jdbc.OracleXxxx interfaces. CustomDatum implementations do not support such wrapped connections.

Note:

The -compatible=both8i setting requires a JDBC implementation from Oracle9i release 1 (9.0.1) or later.

Oracle8i compatibility mode is now the only way for a _ctx connection context instance to be declared in JPublisher-generated code. No other option setting accomplishes this particular Oracle8i behavior. The _ctx instance may be useful if you have legacy code that depends on it, but otherwise you should obtain connection context instances through the getConnectionContext() method.

Individual Settings to Force Oracle8i JPublisher Behavior

The individual option settings detailed in Table 4-1 will produce results, most of which are similar to those produced when using JPublisher in Oracle8i compatibility mode.

Table 4-1 JPublisher Backward Compatibility Options

Option Setting Behavior

-context=generated

This setting results in the declaration of an inner class, _Ctx, for SQLJ connection contexts. This is used instead of the default DefaultContext class or user-specified connection context classes.

-methods=always

This setting forces generation of SQLJ classes, in contrast to non-SQLJ classes, for all JPublisher-generated classes, whether or not the underlying SQL objects or packages define any methods.

-compatible=customdatum

For Oracle-specific wrapper classes, this setting results in JPublisher implementing the deprecated oracle.sql.CustomDatum and CustomDatumFactory interfaces instead of the oracle.sql.ORAData and ORADataFactory interfaces.

-dir=.

Setting this option to a period (.), results in the generation of output files into a hierarchy under the current directory, as was the default behavior in Oracle8i.


For detailed descriptions of these options, refer to the following: