Project

Profile

Help

Extension Instructions Exceptions in 9.7

Added by lin am about 7 years ago

Hi, we are moving from saxon 9.5 to 9.7. The extension instructions are generating errors in 9.7 (SAXON-EE 9.7.0.18J) like below:

java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: org.highwire.saxon.http.api.HTTPGet$GetInstruction.copy() at java.util.concurrent.FutureTask.report(Unknown Source) at java.util.concurrent.FutureTask.get(Unknown Source) at org.highwire.babel.api.BatchProcessor.performBatchTasks(BatchProcessor.java:254) at org.highwire.babel.api.BatchProcessor.process(BatchProcessor.java:71) at org.highwire.babel.cli.Executor.main(Executor.java:67) Caused by: java.lang.UnsupportedOperationException: org.highwire.saxon.http.api.HTTPGet$GetInstruction.copy() at net.sf.saxon.expr.SimpleExpression.copy(SimpleExpression.java:103) at net.sf.saxon.expr.ItemChecker.copy(ItemChecker.java:266) at net.sf.saxon.expr.CardinalityChecker.copy(CardinalityChecker.java:379) at net.sf.saxon.expr.LetExpression.inlineReferences(LetExpression.java:352) at net.sf.saxon.expr.LetExpression.optimize(LetExpression.java:291) at net.sf.saxon.expr.Operand.optimize(Operand.java:200) at net.sf.saxon.expr.Expression.optimizeChildren(Expression.java:515) at net.sf.saxon.expr.instruct.Block.optimize(Block.java:566) at net.sf.saxon.expr.parser.ExpressionTool.optimizeComponentBody(ExpressionTool.java:1087) at net.sf.saxon.style.XSLTemplate.optimize(XSLTemplate.java:820) at net.sf.saxon.style.PrincipalStylesheetModule.optimizeTopLevel(PrincipalStylesheetModule.java:1349) at net.sf.saxon.style.PrincipalStylesheetModule.compile(PrincipalStylesheetModule.java:1199) at net.sf.saxon.style.Compilation.compilePackage(Compilation.java:265) at net.sf.saxon.style.StylesheetModule.loadStylesheet(StylesheetModule.java:260) at net.sf.saxon.style.Compilation.compileSingletonPackage(Compilation.java:101) at net.sf.saxon.s9api.XsltCompiler.compile(XsltCompiler.java:858) at org.highwire.babel.api.Batch.compileTemplate(Batch.java:370) at org.highwire.babel.api.Batch.load(Batch.java:303) at org.highwire.babel.api.BatchProcessor$2.call(BatchProcessor.java:104) at org.highwire.babel.api.BatchProcessor$2.call(BatchProcessor.java:102) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)

Some of the changes we had to make was in prepareAttributes and compile but perhaps we are missing something. 9.5 version:

   @Override
    public final void prepareAttributes() throws XPathException {
        final int attLength = getAttributeList().getLength();

        // First, pre-define the non-required attributes because they have to be something
        this.headers.put("wrap", makeAttributeValueTemplate("false"));
        this.headers.put("timeout", makeAttributeValueTemplate("100000"));
        this.headers.put("debug", makeAttributeValueTemplate("false"));

        String key;
        String value;
        for (int i = 0; i < attLength; i++) {
            key = getAttributeList().getQName(i);
            value = getAttributeList().getValue(i);
            if (key.equals("href")) {
                final String hrefAtt = getAttributeList().getValue("", "href");
                if (hrefAtt == null) {
                    this.reportAbsence("href");
                }
                this.headers.put("href", makeAttributeValueTemplate(hrefAtt));
            } else {
                this.headers.put(key, makeAttributeValueTemplate(value));
            }
        }
    }

Question: How should makeAttributeValueTemplate be adjusted in this case? How should attIndex be determined in 9.7 for makeAttributeValueTemplate in the above implementation?

Already tried things like the following and different variations : this.headers.put("wrap", makeAttributeValueTemplate("false"),1); this.headers.put("timeout", makeAttributeValueTemplate("100000"),2); this.headers.put("debug", makeAttributeValueTemplate("false"),3); this.headers.put("href", makeAttributeValueTemplate(hrefAtt), i);

But still got the same errors. Or perhaps the above adjustment is ok but the error is somewhere else?

version 9.5 compile looks like this:

   @Override
    public final Expression compile(
      final Executable exec, final Declaration decl) throws XPathException {
      final AxisIterator kids = iterateAxis(AxisInfo.CHILD);
        final Expression contents = (this.getFirstChild() != null)
            ? this.compileSequenceConstructor(exec, decl, kids, true)
            : makeAttributeValueTemplate("");

      return new GetInstruction(contents, getHeaders());
}

 9.7: 
 @Override
    public final Expression compile( final Compilation comp, final ComponentDeclaration decl) throws XPathException 
    {		
    	final AxisIterator kids = iterateAxis(AxisInfo.CHILD);
    	final Expression contents = (this.getFirstChild() != null)
	            ? this.compileSequenceConstructor(comp, decl, kids, true)
	            : makeAttributeValueTemplate("",1);
	return new GetInstruction(contents, getHeaders());
}

xslt looks like this:




    
    

      
        
      
      
        
        
      
      
      -------fasebj.atom $response wrapped:       
        
    -------royopensci.atom $response not wrapped:       
    

     

Any suggestions? Thanks.


Replies (2)

RE: Extension Instructions Exceptions in 9.7 - Added by Michael Kay about 7 years ago

It's failing during compile-time optimization because your extension instruction doesn't implement the copy() method.

The requirement to implement the copy() method isn't new, but it has become increasingly important as more optimizations are attempted that require an expression subtree to be copied. In this example the copy() is triggered by LetExpression.inlineReferences(), which replaces all references to a variable by the variable's initializer. This is typically done if (a) there is only one reference to the variable, or (b) the value is a literal, or (c) the value is itself a variable reference. The main value of this optimization is that it simplifies the expression tree allowing further optimizations to be discovered, such as moving an expression out of a template into a global variable. Again, some of these optimizations are not new, but we have become increasingly careful about copying an expression rather than simply reusing it, partly because the expression tree now contains parent pointers which causes havoc if the same expression is used in more than one place in the tree, and partly because of the impact of XSLT 3.0 packages which makes the static context information more important, even for literals.

The copy() method should create a new instance of the expression, copy across all local variables, and call ExpressionTool.copyLocationInfo() to copy location information from the old expression to the new.

RE: Extension Instructions Exceptions in 9.7 - Added by lin am about 7 years ago

Thanks for the reply. I read in another ticket that every Expression class should have implemented a copy() method so I didn't expect the extension instruction class to need one, especially when it ran without one in 9.5. Can you please elaborate on how to do a copy across all local variables? Are there examples I can look at? Thanks!

    (1-2/2)

    Please register to reply