Project

Profile

Help

Error: A Closure can only be read once

Added by Clay Helberg about 8 years ago

Hi--

We are in the process of migrating a version of our app from saxon-PE to saxon-EE in order to use XQuery update features. In running our test suite, we are getting some perplexing errors, with the cryptic text "A Closure can only be read once".

We are not generating any closures programmatically, we are just executing XQueries. The error doesn't give any info on what it doesn't like in the query. Is there a way to get more insight into what's happening here?

--Clay

Stack trace:

A Closure can only be read once java.lang.IllegalStateException at net.sf.saxon.value.Closure.iterate(Closure.java:205) at net.sf.saxon.value.Closure.head(Closure.java:160) at net.sf.saxon.expr.PJConverter$UnwrapExternalObject.convert(PJConverter.java:725) at net.sf.saxon.expr.PJConverter$General.convert(PJConverter.java:1037) at com.saxonica.expr.JavaExtensionFunctionCall.getTargetInstance(JavaExtensionFunctionCall.java:613) at com.saxonica.expr.JavaExtensionFunctionCall.call(JavaExtensionFunctionCall.java:518) at com.saxonica.expr.JavaExtensionFunctionCall.iterate(JavaExtensionFunctionCall.java:417) at net.sf.saxon.expr.FilterExpression.iterate(FilterExpression.java:1175) at net.sf.saxon.expr.flwor.ForClausePull.nextTuple(ForClausePull.java:48) at net.sf.saxon.expr.flwor.OrderByClausePull.nextTuple(OrderByClausePull.java:57) at net.sf.saxon.expr.flwor.ReturnClauseIterator.next(ReturnClauseIterator.java:55) at net.sf.saxon.query.XQueryExpression$ErrorReportingIterator.next(XQueryExpression.java:836) at net.sf.saxon.value.SequenceExtent.(SequenceExtent.java:86) at net.sf.saxon.value.SequenceExtent.makeSequenceExtent(SequenceExtent.java:110) at net.sf.saxon.s9api.XQueryEvaluator.evaluate(XQueryEvaluator.java:434) at com.terraxml.filesysdb.api.FileSysDbApi.getSaxonXqueryResults(FileSysDbApi.java:180) at com.terraxml.filesysdb.api.FileSysDbApi.runXQueryModule(FileSysDbApi.java:102) at com.terraxml.filesysdb.api.FileSysDbFilesTest.testListFoldersLong(FileSysDbFilesTest.java:112)

Source is a little complicated, but I can post it if it will help.


Replies (2)

RE: Error: A Closure can only be read once - Added by Michael Kay about 8 years ago

Sorry for the slowness in responding: for some reason I haven't been getting notification of new forum messages for a couple of weeks.

It's a little bit difficult to work out what's happening with only the stack trace to go by, but it's obviously related to a series of reflexive extension function calls. It's calling an instance-level (non-static) method on a class as an extension function, and it's looking at the first argument in the XPath function call, which represents the instance that will be the target of the call. The way this gets converted depends on the type information available (which we can't see). As one might expect, the XDM value supplied as this argument is an "external object" (that is, a wrapper around the target Java instance) and the job of the converter is simply to do the unwrapping.

The problem now is that the XDM value isn't actually an external object, but a Closure, which is like a promise of an external object that hasn't yet been evaluated. In general, when you evaluate a variable, it isn't immediately materialized, rather the required information to evaluate it (the things it depends on) is saved, and the object in which it is saved is called a Closure. There are two kinds of Closure: memo closures and non-memo closures; this one is a non-memo closure. The difference is that when you eventually get around to evaluating a closure, a memo closure remembers that value for future use, whereas a non-memo closure assumes that the value is only needed once, and discards it. What has gone wrong here is that Saxon decided the value was only needed once, but it got it wrong.

I think we'll have trouble working out why that happened (let alone be confident in any fix) unless we can reproduce it in the lab. I would ask you therefore, please, to produce a repro that enables us to reproduce the bug, debug the causes, test a fix, and create a regression test. Please do this directly on the bug tracker.

RE: Error: A Closure can only be read once - Added by Clay Helberg about 8 years ago

Hi Michael--

Thank you for the reply. I, too, apologize for the delay, I've been on holiday since 31 March, and have just gotten back to the office today.

I think the problem was something to do with an incorrect configuration of my webapp. I cleaned and rebuilt the entire app, and I no longer got this error, so I think it was probably due to a stale class file somewhere in the app or something along those lines.

If I come across this issue again, I will make more detailed notes and try to develop a stripped down test case to reproduce the problem. But until then, you can probably file this away under "user error" and not worry about it. Sorry for the trouble.

--Clay

    (1-2/2)

    Please register to reply