Friday, May 26, 2006

Creating a PL/SQL Web Service from Oracle XE Database

If you want to use Oracle JDeveloper 10.1.3 to publish Web services from PL/SQL packages you will come across this gotcha'.
Oracle XE (Oracle 10g Express Edition) does not come with SQLJUTL. This is used by JDeveloper to publish the Java wrappers around a PL/SQL package for exposure as a Web service. But the workaround is simple.
In the <jdev_home>\sqlj\lib directory there is a copy of sqljutl.sql
Load the package in sys schema (the script contains 2 packages - you don't need the sqljutl2 package - it will not compile if you try and load it) and grant execute to public and carry on using the great PL/SQL Web Service Generation features that JDeveloper offers.

How to Publish an Oracle ADF Business Component as a Web Service in JDeveloper 10.1.3

It's a question that comes up regularly. You have a custom method in your Business Component Application Module and want to expose it as a web service. The way it's done has changed a little since 10.1.2.

First you want to expose the method to the client interface
  1. Open the Application Module Editor
  2. Select the Client Interface page and shuttle the method to the Selected list


Now you can generate a Web service from the methods in the client interface

  1. In the Application Module Editor, select the Remote page
  2. Select the Client Interface page and shuttle the method to the Selected list
When you click OK to close the application module editor, the Web service is generated using the <appmod name>Server.java class created by making the application module remoteable.

There is a bug in JDeveloper 10.1.3.0 that results in JDeveloper hanging if you re-enter the application module editor to make any changes after you have generated a Web service (it is clicking OK - and therefore trying to regenerate the web service, that causes the hanging). To avoid this, the workaround is to delete the Web service (File -> Erase from Disk with the Web service node selected) and then open the editor to make any application module changes .
I'm expecting this to be fixed in Service Update 4.

You can read more about Web Services and Oracle ADF Business Components in the
Oracle Developer's Guide for Forms/4GL Users.

Monday, May 08, 2006

RPC, Document, Bare, Wrapped, Literal- Get It Straight

It's something it's taken me time to fathom - just when, why and how do you
choose the SOAP Message format for your JAX-RPC web service?
The first choice is Document or RPC? For me, that's an easy one - if I'm using JAX-RPC then I probably care about standards, consistency, portability and interoperability. I'm probably going to use WS-I to check that services I create and use are WS-I Basic Profile compliant. I could use RPC/Literal but my SOAP message can't be entirely described by a schema so I'll discard that and stick to the Document style.
Now the more complicated part - made more so by the web services world changing the terms, finding better ways of expressing itself. Document style services send an XML document over SOAP. It's how they describe the <schema> that is a big differentiator.
Document/Bare (also know as Document/Literal) is considered by many to be the default and best method. It is simple, it takes a single method argument. Document/Wrapped wraps multiple arguments into one argument in the WSDL schema.
So consider the following method that adds a new address to an address book:

public boolean addEntry(Address address)

Using JDeveloper 10g to generate a Doc/Bare WSDL would give a <schema> element of:

<types>
<schema
...
<complexType name="Address">
<sequence>
<element name="streetName" type="string" nillable="true"/>
<element name="streetNum" type="int"/>
<element name="city" type="string" nillable="true"/>
</sequence>
</complexType>
<element name="addEntryElement" type="tns:Address" nillable="true"/>
<element name="addEntryResponseElement" type="boolean"/>
</schema>
</types>

A complexType Address has been created from the object type and is referenced in the addEntryElement. The addEntryResponseElement simply returns the method's boolean with no need to create a complexType to reference to.
Compare that with a Doc/Wrapped WSDL of the same method:

<types>
...
<complexType name="addEntry">
<sequence>
<element name="address" type="tns:Address" nillable="true"/>
</sequence>
</complexType>
<complexType name="Address">
<sequence>
<element name="streetName" type="string" nillable="true"/>
<element name="streetNum" type="int"/>
<element name="city" type="string" nillable="true"/>
</sequence>
</complexType>
<complexType name="addEntryResponse">
<sequence>
<element name="result" type="boolean"/>
</sequence>
</complexType>
<element name="addEntryElement" type="tns:addEntry"/>
<element name="addEntryResponseElement"type="tns:addEntryResponse"/>
</schema>
</types>

In this case there are 3 complexTypes: The complexType Address has been 'wrapped' inside a complexType addEntry. It is addEntry that is now referenced by addEntryElement. Plus a third complexType addEntryReponse has been created to hold the boolean response.
So it appears that the Doc/Wrapped form is more complicated - why do we need it? Well, it may be that you have existing code that you want to publish as a web service and these methods (or PL/SQL etc.) have multiple parameters. It may be that you don't want to go edit existing applications to create methods with a single argument or go to the bother of creating 'wrapper' methods with single arguments but want the web service to take care of that for you. This is a typical 'bottom-up' approach to web service development. Most tools use this as the default setting for creating services bottom-up
So continuing with the address theme, consider this method that creates an address object inside it:

public boolean addAddress(int sNum, String sName, String city)

This method could not be published as a Doc/Bare service but using the Doc/Wrapped approach you would finish up with:

<types>
...
<complexType name="addAddress">
<sequence>
<element name="sNum" type="int"/>
<element name="sName" type="string" nillable="true"/>
<element name="city" type="string" nillable="true"/>
</sequence>
</complexType>
<complexType name="addAddressResponse">
<sequence>
<element name="result" type="boolean"/>
</sequence>
</complexType>
<element name="addAddressElement" type="tns:addAddress"/>
<element name="addAddressResponseElement" type="tns:addAddressResponse"/>
</schema>
</types>

Although it might appear that this is very similar to the original Doc/Bare example (and it is!), except of course that it has a 2nd complexType for the boolean return, consider a method with arguments that were objects - each of those would be 'wrapped' in a complex type so the definition could get quite complicated.

So what's the conclusion? I wouldn't dream of saying that I had the definitive answer. But it certainly seems that Doc/Bare is preferable and simpler where practical. However, if a Java client proxy will be used to call your service then perhaps you might consider a Doc/Wrapped style as you can unpick the document of a doc/wrapped operation to get back the same parameter list easily. Confused? That's standards and choice for you.