Thursday, September 30, 2010

Protecting against LinkageErrors from DFC

Unfortunately I've discovered the hard way that DFC can throw more than just DfException and RuntimeException. It turns out that DFC can also generate nasty throwables like LinkageError. The problem with throwables like LinkageError is that the catch clauses people commonly put in there code to catch and handle unexpected conditions generally do not catch LinkageError because it is derived from Error and is not derived from Exception.

The reason DFC can throw LinkageError is because of its BOF activities. The dynamic classloading related to BOF can throw these errors when there are configuration problems with a particular BOF module.

To protect against occurances you need to add a "catch" clause for Throwable like this:
    try
    {
        IDfFolder object = (IDfFolder) session.newObject(XdsxFolderType.TYPE_NAME);
        object.setObjectName(folder.getEntryUuid());
        object.save();
    }
    catch (DfException e)
    {
        // Do something with this exception
    }
    catch (Throwable e) // Because DFC can generate a couple nasty "Error" throwables
    {
        throw new RuntimeException(e);
    }

Diagnosing DFC Configuration Problems

One common problem when trying to diagnose DFC configuration problems is determining where exactly your DFC configuration is coming from. The DFC configuration files likg log4j.properties and dfc.properties are located through the classpath. This provides a lot of power for configuring DFC in various different environments (like WAR files and EAR files). It is a double edged sword though. If your classpath is not quite set up right then you can often find the wrong DFC configuration.

There is a system property that you can set to help diagnose these kinds of problems. The property is "dfc.diagnose_config". If you add this system property to the command line of your java invocation then DFC will display the name of the configuration files that it is using.

For example:

   java -Ddfc.diagnose_config ...

The output will include something like the following:

   Reading DFC configuration from "file:/C:/configuration/dfc.properties"
   Reading log4j configuration from "file:/C:/configuration/log4j.properties"
   Reading dbor configuration from "file:/C:/configuration/dbor.properties"