Oracle Service Bus : Agility in Action

Yesterday I followed a session regarding OSB given by Jeff Davis, it was an interesting session with a lot of demo’s regarding using business services and proxy services.

Topics that we’re interesting to me during the session and I would like to share with the community:

  • Coherence ships with OSB/Weblogic which gives you the possiblity to cache service results to speed up performance. As Jeff mentioned a case could be that your users need to get the latest financial results each day which is a long running business process. This process can be launched asynchronously when the user is logged on in the background. The result of the process is then put in the service cache so when the user needs the information it’s shown to him without delay. The Service Result Caching functionality is integrated within OSB 11G, Release 1.
  • OSB 11g, Release 1 is also fully integrated with Enterprise Repository which gives you the possiblity to index all your existing services using your metadata such as XML, XSD, WSDL, … Using Enterprise Repository the impact of changes made to individual services is clear which makes your release management process a lot easier! Make sure to check out the features and functionality delivered by the Enterprise Repository to be able to govern your services throughout the enterprise.
  • OSB12C (C stands for Cloud) is the next upcoming release of OSB which holds a lot of new interesting functionality such as templating/prototyping services, development is integrated within Jdeveloper, … The fact that the development will be integrated within Jdeveloper gives your development team the possibility to use one and only one IDE to have E2E development from database to business components, to services such as bpel, osb, external services, business rules untill the end-user interface

During the demo Jeff showed how you can expose functionality of an EJB 3.0/2.1 module as a service using business services and proxy services. You can transform from an EJB 3.0 business service to an EJB 2.1 Proxy Service using XQuery and the JEJB protocol.

Integrating Flex and Data Management Services with a Bpel process – What about Typed Collections?

As you can remember we’re working out a flex application using Data Management Services and Flex for the client-side and Bpel at server side.

During development I ran into a blocking issue regarding using typed collections in my ActionScript objects.

Why would I use Typed Arguments, Typed Collections or Typed Arrays ?
My bpel process is using a Global Business Object (GBO), an XML Schema Definition, that defines the entire structure of the business objects I will need in the dossier management lifecycle. The bpel process will be cut pu into different sub processes which will define the needed process lifecycle for the dossier management system we’re building.

Of course this kind of business functionality will be handling master-detail data, e.g. a dossier has dossier_members and dossier_members have address_information.

If we create a web service proxy client for our bpel process, the different objects used in this process will be defined as Java Objects. The hierarchical structure of the dossier-element or – object will be defined in the following manner:

public class Dossier implements java.io.Serializable {
protected int id;
protected be.ws.proxy.types.DossierMembersCollection dosMembersCollection;

public class DossierMembersCollection implements java.io.Serializable
{
protected be.kg.ws.proxy.types.DossierMembers[] dossierMember;

The ActionScript Objects I defined for these server side objects :

[Managed]
[RemoteClass(alias="be.kg.ws.proxy.types.Dossier")]
public
class Dossier
{
public var id:int;
public var dosMembersCollection:DossierMembersCollection;

[Managed]
[RemoteClass(alias="be.kg.ws.proxy.types.DossierMembersCollection")]
public class DossierMembersCollection
{
public var dossierMembers:ArrayCollection;
}

The exception I run into :

ArgumentError: Error #2004: One of the parameters is invalid. at
flash.net::NetConnection/flash.net:NetConnection::invokeWithArgsArray()

What does this mean?
In order for this to work, you need to serialize, you’d need to override both the readExternal and writeExternal methods on both the client and server to take of the serialization of the typed collections yourself.

Practical Approach:

  • Implement the Externalizable Interface at Client- and Server-side
  • Overwrite the readExternal()- and writeExternal()-method in both your client and server classes which match (i.e. the read methods exactly match the write methods on both client and server). You need to serialize your fields as well as the source field of the ArrayCollection (it is an Array).

Take care of serialization and deserialization at server-side, use Externalizable Interface:

public class DossierMembersCollection implements java.io.Serializable ,
Externalizable { protected be.kg.ws.proxy.types.DossierMembers[] dossierMembers;

public DossierMembersCollection() { }

/*** Deserializes the client state of an instance of dossierMembers. */ public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
System.out.println(“Receiving array ———————–”);
Object[] obj2 = (Object[]) in.readObject();
System.out.println(“Read input array obj2 ———————–”);

if (obj2 != null) {
DossierMembers[] dossierMembers = new DossierMembers[obj2.length];
System.out.println(“Initialized dossierMembers———————–”);
loop over the object array and cast the Object-classes to your custom class.
System.out.println(“Looping over array ———————–”); dossierMembers[i] = (DossierMembers) obj2[i];

System.out.println(“DossierMembers: ” + dossierMembers[i].toString());
}}

System.out.println(“Receiving array DONE ————————”); }

/*** Serializes the server state of an instance of dossierMembers. */

public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(dossierMembers); }

Take care of serialization and deserialization at client-side:

[Managed]

[RemoteClass alias="be.kg.ws.proxy.types.DossierMembersCollection")]

public class DossierMembersCollection implements IExternalizable {

public var dossierMembers:ArrayCollection;

public function readExternal(input:IDataInput):void {
trace(“***********Reading dossierMembers”);
var array:Array = input.readObject() as Array;
if (array!=null) {
trace(“****Array received”);
dossierMembers = new ArrayCollection();
Loop over the array and add the arrayElements as typed objects to your collection in the following way:

dossierMembers.addItem(array.pop() as DossierMembers);

trace(“**Number of dossierMembers : ” + dossierMembers.length); }

public function writeExternal(output:IDataOutput):void {

trace(“Write ArrayCollection dossierMembers to array”);

var array:Array = new Array();

loop over object-array and add array-items to the collection: {

array.push(dossierMembers.getItemAt(i));

trace(dossierMembers.getItemAt(i).toString()); }

output.writeObject(array); trace(“Done”); } }

If you get random errors there will propbably be a mismatch between server- and client-side objects. The two approaches you can use are: print statements or stopping in your read/write external methods in the debugger. Step through actionscript classes and Java classes using Flex Debugging mode, so you can ensure that you are reading exactly what you are writing.

Hopefully this will help a lot of people facing the same issues regarding typed objects in an Adobe Flex Environment.