Extensibility mechanisms

In addition to the recommended and documented URI format java:com.package.name.ClassName for use when calling Java extension functions, Saxon has always supported other formats for compatibility with other XSLT processors. Specifically, Saxon accepted any URI containing the package and class name after the last "/", or the entire URI if there is no "/". On XQuery in particular this causes unnecessary failed attempts to locate corresponding classes on the classpath when in fact the namespace URI of a function is that of an imported module. Two changes have been made to solve this problem: firstly, imported modules are now searched before attempting to dynamically load a Java class. Secondly, when running XQuery or XPath, the only URI format now recognized for Java extension functions is the recommended form java:com.package.name.ClassName. Other formats remain available in XSLT to allow a level of compability with other Java-based XSLT processors.

The rules for type conversions when calling extension functions have been aligned more closely with the XPath 2.0 rules, rather than the more flexible XPath 1.0 rules. For example it is no longer possible to supply a string as an argument value when calling a method that expects an integer or a boolean (but supplying an untypedAtomic is fine). Similarly, it is not possible to supply a boolean when a string is expected. Instead, such conversions must now be done explicitly. The implementation now does more static type checking, resulting in more errors being detected at compile time and in greater run-time efficiency as in many cases decisions on which conversions to perform are now made at compile time rather than at run-time.

There may be cases where this type checking causes things to fail that previously worked. One example is where an extension function declares a return type of java.lang.Object, and the application then tries to use the returned object in a context where a string (say) is required. In this situation an explicit cast to string (or a call to the string() function) may be required.

It is now possible in XQuery to compile queries (generating Java source code) that contain calls to extension functions. There are still some restrictions (not all argument and result types are handled).

As part of these changes, the ExternalObjectModel interface has been redesigned; developers of integration modules for third-party object models (like JDOM, XOM etc) will need to implement a couple of additional methods and can delete a number of existing methods that are no longer used.

It is now possible to call Java methods that expect a JDOM or DOM4J node as their argument, provided that the actual node passed as a parameter from the query or stylesheet is a wrapper around a JDOM or DOM4J node respectively. Returning JDOM or DOM4J nodes from an extension function remains unsupported.