https://saxonica.plan.io/https://saxonica.plan.io/favicon.ico2020-06-02T12:05:59ZSaxonica Developer CommunitySaxon - Bug #4567: Failure trying to return a JDOM2 document from a reflexive extension functionhttps://saxonica.plan.io/issues/4567?journal_id=154732020-06-02T12:05:59ZMichael Kaymike@saxonica.com
<ul></ul><p>I also tried returning the JDOM2 Document object directly, hoping the implicit J-to-X conversion would handle it:</p>
<pre><code>public static Document parseToJdom(XPathContext context, String content) throws Exception {
SAXBuilder builder = new SAXBuilder();
return builder.build(new StringReader(content));
}
</code></pre>
<p>This fails at compile time saying</p>
<pre><code>Type error on line 1 column 1
XPTY0020 Axis step descendant-or-self::node() cannot be used here: the context item is not a node
</code></pre> Saxon - Bug #4567: Failure trying to return a JDOM2 document from a reflexive extension functionhttps://saxonica.plan.io/issues/4567?journal_id=154742020-06-02T12:57:48ZMichael Kaymike@saxonica.com
<ul></ul><p>At one time JDOM2DocumentWrapper implemented NodeInfo and would therefore be handled directly as a node, without conversion. With the split of NodeInfo/TreeInfo this is no longer the case. The logic for allocating a converter is treating it as a generic Source, so the converter <code>JPConverter.FromSource</code> is allocated, but this does not recognise this class. Adding this</p>
<pre><code> if (object instanceof TreeInfo) {
return ((TreeInfo)object).getRootNode();
}
</code></pre>
<p>to the logic of <code>FromSource</code> fixes the problem.</p> Saxon - Bug #4567: Failure trying to return a JDOM2 document from a reflexive extension functionhttps://saxonica.plan.io/issues/4567?journal_id=154752020-06-02T13:00:42ZMichael Kaymike@saxonica.com
<ul></ul><p>As for returning a JDOM2 Document from the extension function directly, the problem seems to be that the run-time code is capable of doing the conversion (by wrapping the JDOM2 Document in a suitable wrapper), but the compile-time type-checking is not aware of this possibility. (Note that AxisExpression has it own custom type-checking code, it doesn't use the generic static type checker, which could possibly be smarter).</p> Saxon - Bug #4567: Failure trying to return a JDOM2 document from a reflexive extension functionhttps://saxonica.plan.io/issues/4567?journal_id=154762020-06-02T18:21:08ZMichael Kaymike@saxonica.com
<ul></ul><p>I tried another variation: changing the XPath expression to</p>
<pre><code>base-uri(Q{java:jaxptest.ExtensionTest}parseToJdom('<magic/>'))
</code></pre>
<p>This one fails in a different way: a run-time error</p>
<pre><code>java.lang.ClassCastException: net.sf.saxon.value.ObjectValue cannot be cast to net.sf.saxon.om.NodeInfo
at net.sf.saxon.functions.BaseUri_1.call(BaseUri_1.java:25)
at net.sf.saxon.functions.BaseUri_1.call(BaseUri_1.java:22)
</code></pre>
<p>The static type checking here has established that the required type (<code>node()</code>) subsumes the supplied type <code>Q{http://saxon.sf.net/java-type}org.jdom2.Document</code> and has therefore not inserted any converter into the expression tree.</p>
<p>I've tracked this down to the fact that the JDOM2 object model isn't registered with the Configuration. When I add the line to the test case</p>
<pre><code>proc.getUnderlyingConfiguration().registerExternalObjectModel(new JDOM2ObjectModel());
</code></pre>
<p>it fails again, but this time legitimately, because the test is asking for the base URI of a node that doesn't have one.</p>
<p>Looking at the ClassCastException, the static typechecking is letting this through because of a bug in TypeHierarchy.computeRelationship(). At line 449 the code</p>
<pre><code>if (t2.isPlainType() || t2 instanceof FunctionItemType) ...
</code></pre>
<p>isn't allowing for the possibility that t2 is an external object type. If I fix this, we now get a type error instead of the ClassCastException. This raises the question of whether we could do better: could the "function conversion rules" invoke the wrapping of the JDOM2 Document node as a Saxon NodeInfo? The documentation at <a href="http://www.saxonica.com/documentation/index.html#!extensibility/functions/function-result" class="external">http://www.saxonica.com/documentation/index.html#!extensibility/functions/function-result</a> doesn't say that this should work.</p> Saxon - Bug #4567: Failure trying to return a JDOM2 document from a reflexive extension functionhttps://saxonica.plan.io/issues/4567?journal_id=154772020-06-02T18:25:08ZMichael Kaymike@saxonica.com
<ul></ul><p>A documentation point: we say at <a href="http://www.saxonica.com/documentation/index.html#!sourcedocs/thirdparty" class="external">http://www.saxonica.com/documentation/index.html#!sourcedocs/thirdparty</a></p>
<p>*<em>The support code for Axiom, DOM4J, JDOM2, and XOM is integrated into the main JAR files for Saxon-PE and Saxon-EE, but (unlike the case of DOM) it is not activated unless the object model is registered with the Configuration. This is done automatically if the relevant classes are found on the classpath. If object models other than these are to be supported, the implementation must either be included it in the relevant section of the configuration file, or it must be nominated to the configuration using the method registerExternalObjectModel().</em>
*</p>
<p>I don't think the sentence "This is done automatically if the relevant classes are found on the classpath. " is true any more (it probably was once) -- except that it seems to happen in the JAXP XPathFactory.</p> Saxon - Bug #4567: Failure trying to return a JDOM2 document from a reflexive extension functionhttps://saxonica.plan.io/issues/4567?journal_id=162682020-09-14T11:09:02ZMichael Kaymike@saxonica.com
<ul></ul><p>Discussed at team meeting. We decided it's probably correct to require external object models to be explicitly registered with the Configuration, and the documentation should be changed to say so.</p> Saxon - Bug #4567: Failure trying to return a JDOM2 document from a reflexive extension functionhttps://saxonica.plan.io/issues/4567?journal_id=162882020-09-15T11:47:25ZMichael Kaymike@saxonica.com
<ul><li><strong>Category</strong> set to <i>Saxon extensions</i></li><li><strong>Status</strong> changed from <i>New</i> to <i>Resolved</i></li><li><strong>Priority</strong> changed from <i>Low</i> to <i>Normal</i></li><li><strong>Applies to branch</strong> <i>10, trunk</i> added</li><li><strong>Fix Committed on Branch</strong> <i>10, trunk</i> added</li></ul><p>The code changes had already been made. I have now added JUnit tests and made documentation changes.</p> Saxon - Bug #4567: Failure trying to return a JDOM2 document from a reflexive extension functionhttps://saxonica.plan.io/issues/4567?journal_id=167112020-10-28T17:57:48ZO'Neil Delprattoneil@saxonica.com
<ul></ul><p>Bug fix applied in the Saxon 10.3 maintenance release</p> Saxon - Bug #4567: Failure trying to return a JDOM2 document from a reflexive extension functionhttps://saxonica.plan.io/issues/4567?journal_id=167602020-10-28T18:13:27ZO'Neil Delprattoneil@saxonica.com
<ul><li><strong>Status</strong> changed from <i>Resolved</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>100</i></li><li><strong>Fixed in Maintenance Release</strong> <i>10.3</i> added</li></ul>