Error handling in Java services?

Here’s an entertaining example from wmSamples (“errorHandling”):

[LEFT]
// If strSucceed value is set to true, then throw an exception. This exception will
// be caught in the SEQUENCE or in the catch block depending on which approach
// you are using.
if (!strSucceed.equals(“true”))
{
throw new ServiceException("Service failed because ‘succeed’ was set to " + strSucceed);
}
else
{
// This bit of code is deleting the status element from the IData object and
// replacing it with the new status value.[COLOR=#3f7f5f]
[/LEFT]
[/color]

[SIZE=2][/size]idcPipeline.first(

“status”);

idcPipeline.delete();
[SIZE=2]idcPipeline.insertAfter(

[/size]

“status”, strStatus + " Service succeeded.");

}

// Always destroy your cursors!!!
idcPipeline.destroy();

Look carefully at the above. Apart from the appallingly bad manners in the code (please do not shout, exclamation points are not necessary), the plea to “destroy your cursors” is rather ironic given the exception being thrown 12 lines above. Ouch…there’s a nice little leak to track down at 0200 some fine Saturday morning.

As somewhat of a safe-code freak, I’m curious to see just how real-world practitioners approach WM error handling. The above approach (which presumably represents some unfortunate soul’s idea of a Best Practice) is woefully inadequate.

It’s never been clear to me what exactly the danger of not destroying a cursor is. I’ve never encountered a problem of any sort that was attributed to not closing a cursor. I suspect the orphaned cursor is simply garbage collected at some point without fanfare after the service has completed (and the pipeline tossed away).

The code sample is woefully outdated. The use of first, delete, insertAfter, etc. have been more or less replaced by IDataUtil methods.

For me, when a Java service ends up needing to handle exceptions and there are pipeline cursors open, I use a finally block to destroy them. Easy peasy.

Code-safe freaks will change if(!strSucceed.equals(“true”)) to if(!“true”.equals(strSucceed)) to avoid the NPE when strSucceed is null.

Rob, thanks for the fast reply. It has been quite interesting to work through the wmSamples I downloaded from the Vantage Yahoo group, remediate obviously flawed code such as below, and research and update deprecated API usage. Great way to learn the product from the inside out!

I’m working through wmSamples as a good way to learn the e nvironment from a hands-on approach. Is there a better set of tutorials / use cases? I attended a softwareAG one-day event, but that barely scratched the surface and certainly didn’t discuss anything other than drag’n’drop. As far as best-practices / security / safe coding – not even mentioned. I suppose I’m taking my cue from that.

I must be misunderstanding how to integrate my own POJOs into flow services. For example, I might abstract your excellent if(“x”.operation) pattern into a set of safe-code related operations. To add my own POJOs to WM took a while for me to figure out and appears to require the import of existing sources (to retain the package structure) using Package Manager view as well as manual update (copying) of .java or .class files on the IS itself. This is difficult to keep synchronized when the source files change; I have to remember to do the local compile in Eclipse (which compiles the changed external files, but then may popup the IS compile error message in Eclipse depending on the changes made), then copy my updated external compiled .class files to the server classes folder, then modify my flow service to force another recompile.

On the try / finally pattern, I fully agree with you. The issue is the human error factor (that is, forgetting to put in the “destroy” in the finally clause). Some of the examples I’ve seen have multiple cursors all opened at different points in the execution path (some opened perhaps conditionally) and try / finally can be difficult to keep synchronized. Remember the problems we had with Office automation objects in Windoze? You end up having to put all of your disposable objects outside your try block, initializing them to null, then in the finally block checking each one and optionally calling the appropriate disposal call (“destroy” in this case). Would be nice to have a “using” clause…

I can’t speak to the dangers of not destroying the cursors, and you of course are correct on the GC. The softwareAG folks do seem pretty insistent on the importance of calling “destroy,” which makes me think there are perhaps resource issues in a production environment when GC timing is indeterminate. In the C# world this type of problem is manifested in IDisposable database connections – after some period of time on a busy server database connections start failing if the devs haven’t either wrapped all calls in “using” or been very careful to use try / finally and call Dispose.

Thanks again, I appreciate your time and look forward to learning more about WM. I’m really psyched to see how / if it’s possible to do stuff like secure REST (would involve signing the HTTP parms – PK support??) and SAML as well as maybe implementing PDP / PEP stuff with ABAC / RBAC and dynamic authorization. But I gotta learn the system first!

Cheers,

Andy

“…integrate my own POJOs into flow services”

There are differing views on this, but my general rule of thumb on Java services is “don’t.” IS is not a Java development environment. It is primarily a FLOW development environment, with accessibility to Java when needed.

There are a couple of big Java-related threads on the forums.

http://wmusers.com/forum/showthread.php?t=2943
http://wmusers.com/forum/showthread.php?p=55618
http://wmusers.com/forum/showthread.php?t=9473

A search for Java will turn up other threads you may find to be of interest.