I’d seen this problem before but neglected to tell David about it. Poor David, nothing like putting him on the spot. Anyway, for any of you’ve dealt with the LotusXSL.jar and XML4J.jar files, you’ll probably see where I’m going with this immediately. The problem revolves around the order in which Notes loads things onto the classpath. For more details…
When the jvm loads up, it looks for classes in the following order:
- Is there a JavaUserClasses variable in the Notes.ini file. Load those first.
- Look in the domino/java directory. Load those next.
- Has the agent or library included other jar files, load those last.
When dealing with XML classes, the LotusXSL.jar and XML4J.jar files are in the domino/java directory. So a vanilla setup of Notes will find those first (b/c there isn’t a JavaUserClasses variable by default). However, these packages are a bit, shall we say, dated. So, it’s entirely likely that you might go out to apache.org and get yourself the latest and greatest versions of xalan or xerxces. This would be ok, except many of the classes in these packages are also duplicated in the LotusXSL.jar or XML4J.jar set. So when a call is made to a Node or Document, the jvm will look into the IBM supplied versions first and find those. The method signatures or implementations of these might have changed from the earlier IBM version to the current Apache version.
The other gotcha is around Factory or Builder classes. In these cases, the default class that these factories want to use are in the xerxces package, which is NOT part of the IBM supplied packages. This will cause a run-time failure, not a compile time failure. Fortunately, the Factory class will take a non-default argument where a specific parser implementation can be specified. This is where you can route back to an XML4J supplied version. The line of code looks something like this:
org.apache.xalan.xslt.XSLTProcessor processor = org.apache.xalan.xslt.XSLTProcessorFactory.getProcessor(new XML4JLiaison4dom());
Now, could we have done this another way? Certainly. But our goal was to use what is supplied by IBM, and not have to require any special configuration items, like adding a JavaUserClasses variable. Joshua suggested that we take the lightweight approach and just write our own parser. Steve DeVoll (our CTO) would certainly have concurred with him, but again, not our goal. I think people who use OpenNTF code are just as interested in the application of IBM/Lotus technology within the solution as they are in the solution itself. So, it is that end we have pursued.
If you’ve ever wanted to make use of the LotusXSL and XML4j packages and had trouble locating the API docs, look no more. Here are some pointers:
Sadly, neither of these links is at a Lotus or IBM site. Perhaps they still exist there as well, but I haven’t found them. I kinda’ stopped when I found what I needed.