Thursday, 8 January 2009

Explore your Windows Processes

Many consultants that use Windows find that the Taskmanager of windows is pretty rudimentary. Also you might have encountered that files are locked by processes that you're not aware of. Or process that you can't manage to kill using Taskmanager. Then the Process explorer tool of Sysinternals is very usefull. Sysinternals is now part of Microsoft (already since a few years) but the tool is still available for free. It is such a great tool that I recommend to replace the taskmanager by it.

You can download the tool at http://download.sysinternals.com/Files/ProcessExplorer.zip

For our dutch readers I have an article on Process Explorer that I wrote a few years ago. You can download it here.

Wednesday, 7 January 2009

Xpath error in BPEL assign after transform step

Recently I ran into an xpath error in an assign step in BPEL. The error denoted that the xpath expression is in error because of a node not found. Unfortunately it does not quite clearly state if it is about the "from"-xpath expresssion or the "to"-expression. And strangely enough the copy-rule-wizard lets you select the proper element, so the xpath-expression is clearly correct!

I found out that in this case I had a xslt-transform-step somewhere before the assign step. In this step I initialized the variable, but in the later assign step I assigned some other elements that I could not determine during the transform, because these values came from other variables.
In the XSLT I did not explicitly fill the elements that I assigned later. Apparently the transform step creates only those elements that are explicitly named in the XSLT. Those that are not defaulted or filled, are thus not created.

I solved it by adding the node element to the xslt, filling it with a simple xsl:text element with a space or something.

So I conclude that an non-existing node is apparently not the same as an empty element!

Monday, 5 January 2009

Xpath expressions with namespaces on XMLType

I used to use XMLTypes with xml where I tend to prevent the usage of namespaces. Namespaces make things difficult where they are often unneeded. That is I experienced that it is hard. An expression like '/level1/level2/level3' is much simpeler then '/ns1:level1/ns2:level2/ns3:level3'. Especially if you don't know how to give in the particular namespaces.

Lately I wanted to store the results of a BPEL Process in the database to be able to query parts from that in a later process. Actually I processed several files in the one process and wanted to query the statuses in the later process again. If you work with BPEL you cannot avoid using namespaces. I also wanted to put the results in an XMLtype as is, since it prevented me to create a complete datamodel. A simple xmltype-table suffices.

I then created a pl/sql function with the filename as a parameter that fetched the right row in the results table and gave back the xmltype column in which the status of that file was stored. But then, how to query it with XPath?

I knew the xmltype.extract() function. But what next? You can avoid namespaces by using the local-name() xpath function, but then it is a little hard to get the value of the particular file.

Luckily the extract() function has another parameter, the namespace string:

extract(XMLType_instance IN XMLType,
XPath_string IN VARCHAR2,
namespace_string In VARCHAR2 := NULL) RETURN XMLType;

This namespace string can contain the namespace declarations to be used in an xpath expression. The namespace declarations look like:
namespace-shortage=uri
for example
ns1="http://www.example.org/namespace1"
You can have multiple declarations separated by white space.

An example is as follows:
declare
xp_no_data_found exception;
pragma exception_init(xp_no_data_found, -30625);
l_xpath varchar2(32767) := '/ns1:level1/ns2:level2/ns3:level3';
l_nsmap varchar2(32767) := 'ns1="http://www.example.org/namespace1" ns2="http://www.example.org/namespace2" ns3="http://www.example.org/namespace3"';
l_xml xmltype;
l_clob clob;
begin
l_xml := function_that_gets_an_xmltype_value();
l_clob := l_xml.extract(l_xpath, l_nsmap).getclobval();
end;

Read more about it on page 4.6 of: http://download-uk.oracle.com/docs/cd/B19306_01/appdev.102/b14259.pdf.

Mark also that there are actually two functions: extract() and extractvalue(). Extract() returns an xmltype, that can be 'sub-queried'. The extractvalue() function returns the datatype of the variable that the value is assigned to. With the xmltype functions getstringval(), getclobval(), etc. you can also get the particular value of a node of the xmltype. However, there is a slight difference between the result of the getstringval() and correspondingfunctions and Extractvalue. And that is that the Extractvalue returns the unescaped value of the node (the encoding entities are unescaped), while getstringval() returns the value with the entity encodings intact .

Friday, 2 January 2009

Free your debug Session

Recently I had to build, test and debug some Pl/Sql. I use my all time favourite tool Pl/Sql Developer. But it happens when debugging Pl/Sql that for no apparent reason the debug-session hangs. Especially when hitting the Break button in Pl/Sql Developer, it may happen.
When it happens you'll have to kill Pl/Sql Developer the hard way, using Taskmanager. Because it refuses to quit while there is a session running.

Fortunately, there is a pretty simple solution.

When your test script looks like:
-- Created on 1/2/2009 by MAKKER
declare
  -- Local variables here
  i integer;
begin
  -- Test statements here
  :result := sos_log.log_run(p_schedule_id => :p_schedule_id,
  p_status => :p_status);
end;

Then just declare an extra variable l_time_out of data type number. Then set a time of for example 5 seconds. using the dbms_debug.set_timeout:
declare
  l_time_out number;
-- Local variables here
  i integer;
begin
  l_time_out := dbms_debug.set_timeout(5);
  -- Call the function
  :result := sos_log.log_run(p_schedule_id => :p_schedule_id,
  p_status => :p_status);
end;

When Pl/Sql Developer looses the connection to the debug session the debug session will be freed after the timeout. Pl/Sql Developer gets the control back and you can go on with compiling and debugging.

You can add it easily to the default test template. Unfortunately Pl/Sql Developer does not use the template when you do right-click->test on a program-unit.
For that you could create a macro that adds the code to your test script, and connect it to a key-stroke.

Wednesday, 10 December 2008

XPath evaluation in Java using Namespaces

Earlier this year I wrote an article on testing Xpath expressions and XSL transformations in Java. This is no that hard if you know how to do it.

What I did not mention there is how to do xpath-queries on documents with namespaces.
Take for example the following xml:



<?xml version="1.0" encoding="UTF-8" ?>
<XSLBatch xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.darwin-it.nl/XMLTypes/XSLBatch ../xsd/XSLBatch.xsd"
xmlns="http://www.darwin-it.nl/XMLTypes/XSLBatch">
<XSLTransform>
<Order>1</Order>
<SourceXMLFile>/home/makker/Projects/Java/trunk/src/JavaAndXML/XMLTester/workspace/xml/sos_exportjobs.xml</SourceXMLFile>
<XSLFile>/home/makker/Projects/Java/trunk/src/JavaAndXML/XMLTester/workspace/xsl/CreateObjectType_0.2.xsl</XSLFile>
<DestinationFile>/home/makker/Projects/Java/trunk/src/JavaAndXML/XMLTester/workspace/output/sos_exportjobs.tps</DestinationFile>
</XSLTransform>
<XSLTransform>
<Order>2</Order>
<SourceXMLFile>/home/makker/Projects/Java/trunk/src/JavaAndXML/XMLTester/workspace/xml/sos_exportjobs.xml</SourceXMLFile>
<XSLFile>/home/makker/Projects/Java/trunk/src/JavaAndXML/XMLTester/workspace/xsl/CreateObjectTypeBody_0.2.xsl</XSLFile>
<DestinationFile>/home/makker/Projects/Java/trunk/src/JavaAndXML/XMLTester/workspace/output/sos_exportjobs.tpb</DestinationFile>
</XSLTransform>
</XSLBatch>


If you want to do a query on all XSLTransforms, you would probably write an Xpath of the form:
/XSLBatch/XSLTransform

But if you try to do that with the statement:

private XMLDocument xmlDoc;
...
public NodeList selectNodes(String xpath) throws XSLException {
NodeList nl = this.xmlDoc.selectNodes(xpath);
return nl;
}

then you find out that the NodeList nl would not deliver you any nodes.
This is because the XML document is of namespace: "http://www.darwin-it.nl/XMLTypes/XSLBatch" and this is not taken into account in the xpath expression above.
You could use an expression in the form of:
/xbt:XSLBatch/xbt:XSLTransform

But then: how does the parser know to what Namespace the abbreviation xbt resolves?

You could avoid the problem above with the expression:
/*[local-name()="XSLBatch"]/*[local-name()="XSLTransform"]
This is especially usefull if you have no means of specifying the namespaces you used.
But it makes the expressions very complex and if you need to query on a specific value of an attribute then you're out.

You can resolve this in Java quite easily with a NameSpace resolver. A what? A NameSpace resolver is a class that implements the oracle.xml.parser.v2.NSResolver interface. That is: using the Oracle XML parser.

A sample implementation of the Namespace Resolver is as follows:
package com.m10.xmlfiles;

import java.util.HashMap;

import oracle.xml.parser.v2.NSResolver;

public class XMLNSResolver implements NSResolver{
  private HashMap nsMap = new HashMap();
  
    public XMLNSResolver() {
    }

   public void addNS(String abbrev, String namespace){
       nsMap.put(abbrev, namespace);
   }
    public String resolveNamespacePrefix(String string) {
        return (String)nsMap.get(string);
    }
}

As you can see this implementation is fairly simple. It has a HashMap in which you can store your namespaces with an abbreviation as a key.
Since it inmplements the NSResolver interface it must implement the resolveNamespacePrefix. And that one does exactly what you might expect: it gives the namespace back that belongs to the abbreviation.

So if you do the following:
XMLNSResolver nsRes = new XMLNSResolver();
nsRes.addNS("xbt", "http://www.darwin-it.nl/XMLTypes/XSLBatch");
Then you can do your xpath query as follows:
NodeList nl = this.xmlDoc.selectNodes("/xbt:XSLBatch/xbt:XSLTransform", nsRes);

And that is how this is done.

Friday, 5 December 2008

EDA the successor of SOA?


Today I read the remarkable article in the Computable that according to Gardner EDA (Event Driven Architecture) will be the successor of SOA (Service Oriented Architecture). That would suggest that EDA and its technology is newer than SOA or that EDA tools will replace the current SOA-tools. Well, I'm not that into the History of ICT. But about three years ago Oracle introduced their Enterprise Service Bus as part of the SoaSuite. You could consider the ESB as the succesor of Oracle's InterConnect in J2EE technology. Remarkable also is that you can find Oracle Workflow's Business Event System parts in the ESB technology. The Business Event System (the name sais it all) is part of Oracle Workflow since version 2.6, that was introduced in 2001 if I'm right.
Oracle Service Bus (fka. BEA's AquaLogic Service Bus) was introduced in 2005. And there are serveral other service busses maybe with an even longer history.

So Busineess Events could be (and should be) part of our applications since a long time. In fact Enterprise Application Integration (another Three Letter Acronym or TLA), is about firing and receiving business events from applications.

I believe that EDA does not succeed SOA. In fact SOA is about Services and Services on their own are not usefull. Services are triggered with an information object. And this infact is an event. Connecting Services in to a business flow (what we call "orchestration") is about passing Business Events between Services folowing a Business Process. Nowadays we tend to do that using BPEL or BPMN.

Therefore I would state that SOA = EDA + BPM. I must confess that I did not make that up on my own. Since I'm a former Oracle Employee, this is what I've learned from the positioning of Oracle's toolstack onto SOA.

Having a Service Bus is not a replacement of your SOA toolstack but a very valuable addition to it. It's a very good idea to have a Service Bus abstract your services from your Business Process. That makes it easier to do things like aggregating services, replacing services, transformations from Enterprise Business Objects to Application Business Objects, etc. But this article is not about the value of an Service Bus. For that I could write a complete separate article.

Read also this previous article.

Monday, 1 December 2008

Unlock SVN Repository for SVN Sync

Lately I've been introduced into the ease of use of subversion. I now use it on my laptop to keep track of my projects. It's surprisingly easy to setup a repository and to use it. Maybe I should do a posting on that in the near future.

I also setup a local synced repository that I use to get a local copy of our central project repository. However, last week I started by accident this repository server twice, and stopped the sync-run by ctrl-c to resolve this. After that I got a:
"Failed to get lock on destination repos, currently held by makker-laptop" message repeatedly.

I got the solution on: http://journal.paul.querna.org/articles/2006/09/14/using-svnsync/.

However the exact command mismatched for me (I don't know how version dependent that is).

What I had to do is to delete the lock by removing a lock-property. The command for this is:

svn propdel svn:sync-lock --revprop -r 0 .

In Pauls blog he suggested the svn-command propdelete, but this should be propdel. And I had to make up that for the repository you have to give in the link to the svnserver that runs the repository.

For example:
svn propdel svn:sync-lock --revprop -r 0 svn://localhost:3904

This worked, and got me syncing my repositories again.