onsdag, februari 28, 2007

Recursion in Rules

Long time since I wrote something about Rules, so, here is a small sample for using recursion in Rules. Implementing recursion in Rules is fairly easy, just assert a new fact in the action-block of a rule, that's it. By asserting a new fact to the system, the system will re-evaluate, and recursion has taken place.

Below is an example that will illustrate this, it will find and print all ancestor relationships that are the result of three parent relationships. Andy is a parent of Betty, Betty is a parent of Charlie and Charlie is a parent of Donna. Which are the resulting ancestor relationships?

Running this program will reveal the result...

ruleset main {

class Parent {
String a;
String b;
}

class Ancestor {
String a;
String b;
}

// Convert a Parent relationship to an Ancestor relationship
rule parentToAncestor {
if ( (fact Parent p) ) {
assert(new Ancestor(a: p.a, b: p.b));
}
}

// If A is parent of B and B is an Ancestor of C, then A is an Ancestor of C
rule parentAndAncestorToAncestor {
if (
(fact Parent p) &&
(fact Ancestor a) &&
p.b.equals(a.a)
) {
assert(new Ancestor(a: p.a , b: a.b));
}
}

// Printout all Ancestors relationships
rule printAncestors {
if (fact Ancestor a) {
println(a.a + " is an ancestor of " + a.b);
}
}

// Setup some parent relations...
{
assert(new Parent(a: "Andy" , b: "Betty"));
assert(new Parent(a: "Betty" , b: "Charlie"));
assert(new Parent(a: "Charlie", b: "Donna"));
}

// Evaluate the ruleset
run();
}


below is the result:

Andy is an ancestor of Donna
Betty is an ancestor of Donna
Charlie is an ancestor of Donna
Andy is an ancestor of Charlie
Betty is an ancestor of Charlie
Andy is an ancestor of Betty

fredag, februari 23, 2007

Using the JDeveloper HTTP Analyser to Trace Web Services Calls from the RDBMS

As you know, you can use the HTTP Analyser within JDeveloper to examine the network traffic of a client connecting to a Web Service. Usually one uses the HTTP Analyser from within JDeveloper, but it can also be used to track calls from a Web Services client residing within the RDBMS.

This is the approach to take to do this:

First, you start the HTTP Analyser normally by selecting View Http Analyser within JDeveloper. It then opens in its own window inside JDeveloper, run the HTTP Analyser by clicking > '(the small green button...)'.

Next, you need to tell the RDBMS Web Service client to use this instance of the HTTP Analyser as a proxy, this can be done with the following line:

sys.utl_dbws.set_http_proxy('<host>:<port>');

and here you specify the host where JDeveloper is running as the host, the port is by default 8099, so unless you know that this has been changed, use this.

Now it's time to run the call to the Web Service. The request/response packet pairs will now be listed in the HTTP Analyser. To examine the content of a request/response pair highlight it in the History tab and then click the Data tab.

The should give you further details about the exact request / response sequence taking place.


fredag, februari 16, 2007

Changed the Connection for a JDeveloper Generated PL/SQL Web Service

Have you ever been annoyed that the JDeveloper PL/SQL Wizard is not able to change the Connection? Once you have created the Web Service, the field for the Connection is not editable. At least I have.

Unfortunately doesn't the Wizard support switching the Connection. However, it is possible to do this in another way, this has not been tested to 100%, but I have used on several occasions and it seems to do the trick. So, if you want a 100% safe solution, you should re-create the Web Services. If you do not want to do that, and want to test this approach, you should ensure to have a backup of your project before progressing. Here is how you do it:


1. Close the JDeveloper project.
2. Open the file myProject\src\mypackage\MyWebService.jaxrpc
3. Edit the entry:

<value n="PT_PLSQL_CONNECTION" v="MyConnectionName"/>

and change that to your new Connection and save the file.

4. Open the Project

5. Double click on the Web Service to open the Wizard. The new connection should now appear in the dialog. Click OK, this will re-generate the service to work towards the new connection.

torsdag, februari 01, 2007

Strange ADF Problem, Timepart of a Date Lost

Today I have been working on an issue that has intrigued me for a while. One of our customer has an application (ADF BC - Struts w. JSP) that first inserts some data into an Oracle DB by creating a new row in the corresponding ViewObject, then fetches some additional data from another DB, and updates the newly created ViewObject with this data, however, this process has failed. While debugging this problem I noticed that one of the parts of the Primary Key was a Date column, and in the log files there were entries like:

oracle.jbo.RowAlreadyDeletedException: JBO-25019: Riga entit? della chiave oracle.jbo.Key[1 2006-12-27 aaa] non trovata in MyTable.

I also noticed the following a bit further down in the log:

06/12/27 12:22:31 [515] Original value :2006-12-27 12:22:28.0
06/12/27 12:22:31 [516] Target value :2006-12-27

so, it seems quite obvious why the error occurs, the only question now would be why. Now, I wanted to have the error messages in English, so I then added -Duser.lang=en_US, and restarted the Application. Obviously I expected to get the error messages in English, but instead, it worked fine. Strange... I hope to find some explanation for this...