To review, this example shows the JPublisher-generated interface, base class, and user subclass to publish the following PL/SQL package foo_pack, consisting of the stored function foo, using Java types suitable for Web services:

The wrapper method foo() in the user subclass FooPackUser uses the following type transformation functionality and a call to the corresponding _foo() method of the generated base class, which is where the JDBC calls occur to invoke the wrapped stored function foo:

Base Class Code

This is code for the base class that JPublisher generates in FooPackBase.java. The _foo() method is called by the foo() method of the user subclass and uses JDBC to invoke the foo stored function of the foo_pack PL/SQL package that JPublisher is publishing.

User Subclass Code

This is code for the user subclass that JPublisher generates in FooPackUser.java. The foo() method calls the _foo() method of the base class. Java-to-Java transformations are handled in try blocks as indicated in code comments.

This class extends the class FooPackBase and implements the interface FooPack.

Code comments show #sql statements that correspond to the translated code shown.

The getEmpBeans() method, generated because of the -sqlstatement.return=both setting, returns an array of JavaBeans. Each element represents a row of the result set. The GetEmpRow class is defined for this purpose.

JPublisher generates a SQLJ class. The result set is mapped to a SQLJ iterator.

(For UPDATE, INSERT, or DELETE statements, code is generated both with and without batching for array binds.)

Generated Code: Java and PL/SQL Wrappers for Web Services

This section contains code examples for JAX-RPC client proxies and the associated Java and PL/SQL wrappers, generated according to the WSDL document indicated by the -proxywsdl setting. The code in this example is for use with an EJB Web service, and also uses a table function. The following are included:

WSDL document

JPublisher accesses the WSDL document, the content of which determines the JAX-RPC client proxy classes to generate.

These classes and interfaces are generated by the Oracle Database Web services assembler tool, which is invoked by JPublisher. Resulting proxy classes and interfaces are loaded into the database. The client proxy stub class is used for invoking the Web service.

Java wrapper class and PL/SQL wrapper

These wrappers are generated by JPublisher for use in the database. Use the PL/SQL wrapper to access the client proxy class from PL/SQL. The client proxy class, in turn, invokes the Web service. The wrapper class is a required intermediate layer to publish instance methods of the client proxy class as static methods, because PL/SQL supports only static methods.

Associated PL/SQL utility scripts

These scripts are generated by JPublisher. The scripts are to create the PL/SQL wrapper in the database schema, grant permission to execute it, revoke that permission, and drop the PL/SQL wrapper from the database schema.

For this example, assume that a JAX-RPC Web service, called HelloServiceEJB, is deployed to the following endpoint:

http://localhost:8888/javacallout/javacallout

The WSDL document for this Web service is at the following location:

http://localhost:8888/javacallout/javacallout?WSDL

The Web service provides an operation called getProperty that takes a Java string specifying the name of a system property, and returns the value of that property. For example, getProperty("os.name") may return "SunOS".Based on the WSDL description of the Web service, JPublisher can direct the generation of a Web service client proxy, and generate Java and PL/SQL wrappers for the client proxy. Here is the command to perform these functions:

The -proxyopts setting directs the generation of the JAX-RPC client proxy and wrappers, and the use of a table function to wrap the Web service operation. The -url setting indicates the database, and the -user setting indicates the schema, where JPublisher loads the generated Java and PL/SQL wrappers. The -sysuser setting specifies the SYS account that has the privileges to grant permissions to execute the wrapper script.

WSDL Document

This section contains the WSDL document for the Web service. HelloServiceInf in the <message> element is the name of the service bean and determines the name of the interface that is generated and that is implemented by the generated JAX-RPC client proxy stub class. The HelloServiceInf interface has the following signature:

The method getProperty() corresponds to the getProperty operation specified in the WSDL document. It returns the value of a specified system property (prop). For example, specify the property "os.version" to return the operating system version.

JAX-RPC Client Proxy Classes and Interfaces

This section shows the JAX-RPC client proxy stub class, the interface that it implements, a factory class to produce instances of the stub class, and the interface that the factory class implements. These classes and interfaces are all generated by the Oracle Database Web services assembler tool, which is invoked by JPublisher. The stub class is for invoking the Web service, through Java and PL/SQL wrappers that JPublisher produces.

Interface for JAX-RPC Client Proxy Stub Class

Here is code for the interface, HelloServiceInf, implemented by the JAX-RPC client proxy stub class, HelloServiceInf_Stub, which is shown immediately following.

// !DO NOT EDIT THIS FILE!
// This source file is generated by Oracle tools
// Contents may be subject to change
// For reporting problems, use the following
// Version = [failed to localize] wscompile.version(Oracle WebServices, 10i, J1)
package javacallout;
public interface HelloServiceInf extends java.rmi.Remote {
public java.lang.String getProperty(java.lang.String string_1)
throws java.rmi.RemoteException;}

Here is the code for the interface, HelloServiceEJB, implemented by the client proxy factory class, HelloServiceEJB_Impl, which is shown immediately following.

// !DO NOT EDIT THIS FILE!
// This source file is generated by Oracle tools
// Contents may be subject to change
// For reporting problems, use the following
// Version = [failed to localize] wscompile.version(Oracle WebServices, 10i, J1)
package javacallout;
import javax.xml.rpc.*;
public interface HelloServiceEJB extends javax.xml.rpc.Service {
public javacallout.HelloServiceInf getHelloServiceInfPort();}

JAX-RPC Client Proxy Factory Class

Here is code for the client proxy factory class, HelloServiceEJB_Impl, used to create instances of the client proxy stub class, HelloServiceInf_Stub, which is shown earlier in this section. The HelloServiceEJB_Impl class implements the HelloServiceEJB interface, shown immediately preceding.

Java Wrapper Class and PL/SQL Wrapper

This section shows code for the Java wrapper class and PL/SQL wrapper that JPublisher generates. These are used to call the proxy client stub class from PL/SQL.

Wrapper Class

Here is the class, HelloServiceEJBJPub, that JPublisher generates as a Java wrapper for the proxy client stub class. The Java wrapper is required to publish instance methods of the stub class as static methods, to allow accessibility from PL/SQL. The Web service endpoint in the code, "http://localhost:8888/javacallout/javacallout", is according to the -endpoint setting in the JPublisher command line.

Here is the PL/SQL wrapper script, plsql_wrapper.sql, that creates the PL/SQL wrapper package, JPUB_PLSQL_WRAPPER. This package is created for invoking the Web service from PL/SQL. Note that it includes the definition of a table function—data from the Web service is returned through a database table, rather than through a normal function return.

An intermediate Java wrapper class, shown immediately preceding, is required to publish instance methods of the JAX-RPC client proxy stub class as static methods, which is required for accessibility from PL/SQL.

Because a -user setting is specified in the JPublisher command line to publish this Web service, JPublisher will load the generated Java code and PL/SQL wrapper into the database. Once everything is loaded, you can use the PL/SQL wrapper to invoke the Web service. The PL/SQL wrapper consists of two functions: getProperty and TO_TABLE_getProperty.

The getProperty function directly wraps the getProperty() method in the generated client proxy class. For example, the following SQL*Plus command uses getProperty to determine the operating system where the Web service is running ("SunOS"):

TO_TABLE_getProperty is a table function based on the getProperty function. It takes a REF CURSOR as input and returns a table. The schema of the table returned is defined by GRAPH_getProperty.

In this example, TO_TABLE_getProperty is called with a REF CURSOR obtained from a one-column table of VARCHAR2 data, where each data item is the name of a system property (such as "os.version"). Then TO_TABLE_getProperty returns a table in which each row contains an item from the input REF CURSOR, and the result of a getProperty call taking that item as input. Following is a sample usage of TO_TABLE_getProperty.

This example creates a one-column table of VARCHAR2, populates it with system property names, and uses TO_TABLE_getProperty to find out the values of those system properties. For example, you see that the operating system is Sun Microsystems Solaris 5.8.

Additional PL/SQL Utility Scripts

This section illustrates PL/SQL utility scripts that JPublisher generates, in addition to the wrapper script, plsql_wrapper.sql, already shown. There are scripts to grant permission for execution of the PL/SQL wrapper, revoke permission, and drop the PL/SQL package from the database schema.

Generated Code: Java and PL/SQL Wrappers for General Use

This section has code examples for Java and PL/SQL wrappers generated for server-side Java classes, according to -proxyclasses and -proxyopts settings. See "Options to Facilitate Web Services Call-Outs" for information about these and related options.

Assume that the Java and PL/SQL wrappers in these examples are for general use, not necessarily associated with Web services.

The following sections show the classes to be wrapped, the wrapper classes and PL/SQL wrappers produced for static methods, and the wrapper classes and PL/SQL wrappers produced for instance methods in the handle scenario.

Java and PL/SQL Wrappers for Static Methods

Assume that class X from the preceding section is processed by JPublisher with the following settings:

% jpub -proxyclasses=X -proxyopts=static

With these settings, JPublisher generates Java (as necessary) and PL/SQL wrappers for static methods only. This always includes a PL/SQL wrapper, and in this example also includes a wrapper class, XJPub, for the class X. A wrapper class is necessary, even when there are no instance methods to wrap, because class X uses the Java type Y for an argument in a method calling sequence. A wrapper class is required whenever types other than Java primitive types are used in method calls. In this case, the wrapper class has a wrapper method for the following:

Java and PL/SQL Wrappers for Instance Methods Using the Handle Mechanism

Given these settings, JPublisher generates wrappers for instance methods, including Java wrapper classes and a PL/SQL wrapper. In this example, JPublisher generates the wrapper classes XJPub and YJPub for X and Y, respectively. Because of the multiple setting, JPublisher uses the handle mechanism to expose instance methods as static methods to allow access from PL/SQL (which supports only static methods). See "Mechanisms Used in Exposing Java to PL/SQL" and "Wrapper Class Generation with Handles" for related information.