Wednesday 1 July 2015

OSB11g what is the scope of the for-each loop variable?

Earlier I wrote an article on the strange behaviour of the OSB11g For-each activity (Osb-11g: for each is index-variable an integer?). Today I found out some other peculiar behaviour.

I had to loop over a sequence of  documents, each refering to an attachment. The first document processed well, but at the second iteration the attachment couldn't be found. At first I used Soap with Attachments and now I changed my service to use MTOM. Anyway, at first I thought it to be a SoapUI problem. But adding debug-alerts (I find alerts more comfortable then logs) showed me that the second attachment is really referred to in the message. So apparently, it's not a SoapUI problem.

What happened? Well, have the following for-each:
So I loop over a bunch of documents and at each iteration I'll get the particular document in the document variable. Then I get the attachment, transfer it into a base64-encoded-string, and replace the content with the base64-encoded-string, ... , in the $document variable!!!!! Is that wrong? Well, I expected that in the next iteration the $document variable would be replaced by the new occurrence. But apparently changing the for-each-variable will change the scope of the variable and makes it a 'normal' variable, instead of the loop variable. And since I replaced the contents, It did not have the reference to the next attachment. The quick fix I did was to copy the loop variable to a seperate variable using an assign and then do the changes on that next variable. Each new iteration the content of that variable is overwritten by the assing of the new iteration-variable.

But better is probably to use the index variable and do the changes directly on the main variable, in my case $documents.

So conclusion? Don't change the loop variable!

UPDATE: Oh, by the way, the reason that I change a seperate variable during the loop was that it apparently is not possible to do a Replace or Insert within a loop upon using the index variable. You'll get an error like: 'XQuery exception: line 34, column 11: {err}XP0008 [{bea-err}XP0008a]: Variable
 "$documentIndex" used but not declared for expression: declare namespace jca =
 'http://www.bea.com/wli/sb/transports/jca';...
'
in the expression. So what I did was to copy the document-array from the body variable to a $documents variable, delete all the documents in the body variable (leaving the documents-element). Then loop over the $documents variable, create a new $documentNew variable from $document with the changed variables and insert that in the body variable again.

No comments :