Project

Profile

Help

Bug #5495

closed

java.lang.UnsupportedOperationException: Cannot copy a variable reference whose binding is unknown

Added by Rohit Gaikwad about 2 months ago. Updated about 1 month ago.

Status:
Resolved
Priority:
Normal
Assignee:
-
Category:
s9api API
Sprint/Milestone:
-
Start date:
2022-05-18
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
10, 11, trunk
Fix Committed on Branch:
10, 11, trunk
Fixed in Maintenance Release:
Platforms:
Java

Description

Issue : We are getting below " binding is unknown " exception as in stackTrace while using Saxon-HE 10.8 and 11.3. With version 10.7 no regression is found.

Analysis:
I think the issue is at "/" in xsl:template of our source.xml file. It used to work till 10.7

Steps to reproduce :
Execute command below command using attached source.xml and myXsl.xsl files

java -jar saxon.jar -s:source.xml -xsl:myXsl.xsl

using Saxon-HE 10.8 or higher .

source.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/servlet/MyServlet/*</url-pattern>
</servlet-mapping>

myXsl.xsl file:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
                xmlns="http://java.sun.com/xml/ns/javaee"
                xpath-default-namespace="http://java.sun.com/xml/ns/javaee">
<xsl:output method="xml" indent="no" encoding="UTF-8"/>

<xsl:param name="servletName"/>
<xsl:param name="urlPattern" select='concat("/servlet/",$servletName,"/*")'/>  <!-- Default to normal servlet URL pattern -->

<xsl:template match="servlet-mapping[servlet-name=$servletName] /
                         url-pattern[position()=last()]">
</xsl:template>
</xsl:stylesheet>

StackTrace :

java.lang.UnsupportedOperationException: Cannot copy a variable reference whose binding is unknown
        at net.sf.saxon.expr.GlobalVariableReference.copy(GlobalVariableReference.java:43)
        at net.sf.saxon.expr.Atomizer.copy(Atomizer.java:348)
        at net.sf.saxon.expr.GeneralComparison20.copy(GeneralComparison20.java:43)
        at net.sf.saxon.expr.FilterExpression.copy(FilterExpression.java:1183)
        at net.sf.saxon.expr.SlashExpression.copy(SlashExpression.java:659)
        at net.sf.saxon.pattern.GeneralNodePattern.makeTopNodeEquivalent(GeneralNodePattern.java:61)
        at net.sf.saxon.pattern.GeneralNodePattern.<init>(GeneralNodePattern.java:47)
        at net.sf.saxon.expr.SlashExpression.toPattern(SlashExpression.java:855)
        at net.sf.saxon.expr.sort.DocumentSorter.toPattern(DocumentSorter.java:249)
        at net.sf.saxon.pattern.PatternMaker.fromExpression(PatternMaker.java:45)
        at net.sf.saxon.pattern.PatternParser30.parsePattern(PatternParser30.java:130)
        at net.sf.saxon.pattern.Pattern.make(Pattern.java:59)
        at net.sf.saxon.style.StyleElement.makePattern(StyleElement.java:723)
        at net.sf.saxon.style.XSLTemplate.prepareAttributes(XSLTemplate.java:371)
        at net.sf.saxon.style.StyleElement.processAttributes(StyleElement.java:594)
        at net.sf.saxon.style.StyleElement.processAllAttributes(StyleElement.java:531)
        at net.sf.saxon.style.XSLTemplate.processAllAttributes(XSLTemplate.java:428)
        at net.sf.saxon.style.PrincipalStylesheetModule.processAllAttributes(PrincipalStylesheetModule.java:589)
        at net.sf.saxon.style.PrincipalStylesheetModule.preprocess(PrincipalStylesheetModule.java:366)
        at net.sf.saxon.style.Compilation.compilePackage(Compilation.java:288)
        at net.sf.saxon.style.StylesheetModule.loadStylesheet(StylesheetModule.java:252)
        at net.sf.saxon.style.Compilation.compileSingletonPackage(Compilation.java:113)
        at net.sf.saxon.s9api.XsltCompiler.compile(XsltCompiler.java:851)
        at net.sf.saxon.Transform.doTransform(Transform.java:753)
        at net.sf.saxon.Transform.main(Transform.java:82)

Files

myXsl.xsl (626 Bytes) myXsl.xsl XSL file Rohit Gaikwad, 2022-05-18 15:10
source.xml (170 Bytes) source.xml Source XML Rohit Gaikwad, 2022-05-18 15:14
Actions #1

Updated by Rohit Gaikwad about 2 months ago

Hi Team,

Can someone please take a look into this?

Thanks, --Rohit

Actions #2

Updated by Michael Kay about 2 months ago

Thanks for reporting it.

I've reproduced it as test case variable-4802.

The bug appears to have been introduced as a side-effect of the fix for bug #5369.

As a workaround, please try changing the pattern to servlet-mapping[servlet-name=$servletName] / url-pattern[not(following-sibling::url-pattern)]

In fact, I would suggest that as a permanent change, since this pattern is what the optimizer is trying to generate anyway, because it enables the pattern to be evaluated without back-tracking.

Actions #3

Updated by Rohit Gaikwad about 2 months ago

Thanks Michael for your quick response!

The workaround is working fine. However, We are migrating from Saxon-B(9.1.x) to Saxon-HE 11.3 where amount of efforts required is huge. There are ~700 xsl files in our project, applying this workaround on applicable xsl files will be an additional cost at this time.

It will be better if this bug fix is available in Saxon-HE 11.4 , As right now our target is to make our codebase compatible with Saxon-HE 11.x. Once, this is achieved then we can look into further optimizations that you provided in the workaround.

Thanks, --Rohit

Actions #4

Updated by Michael Kay about 2 months ago

We'll obviously plan to fix this in the next maintenance release, but we always try to provide a workaround if we can so people can make progress in the meantime.

Actions #5

Updated by Rohit Gaikwad about 2 months ago

Can you please let me know when is the next maintenance release planned? Is it possible to make this fix available ASAP in 11.4?

Thanks, --Rohit

Actions #6

Updated by Michael Kay about 2 months ago

Let's focus on fixing it first. I'm currently working on a couple of problems raised by paying customers so those take priority.

Actions #7

Updated by Michael Kay about 1 month ago

In the solution bug #5369, we modify a GeneralNodePattern to ensure that it matches beneath a parentless element node; to modify an expression or pattern, we have to copy it (because the original might be referenced from elsewhere). The reason we have a GeneralNodePattern here is because it has a [position()=last()] predicate which prevents right-to-left evaluation. The copy operation on the pattern fails because of the global variable reference.

The preferred solution is probably to delay the modification/copying of the pattern until the variable reference has been resolved, specifically, until the typeCheck phase.

This works for this test case; now need to regression-test to see what we've broken.

Actions #8

Updated by Michael Kay about 1 month ago

  • Status changed from New to In Progress

Unfortunately the fix breaks tests match-273, -274, and -284, all tests introduced in response to bug #5369.

Actions #9

Updated by Michael Kay about 1 month ago

  • Priority changed from High to Normal

Fixed: GeneralNodePattern.copy() needs to copy the topNodeEquivalent field.

But then variable-4802 fails again.

Actions #10

Updated by Michael Kay about 1 month ago

I've copied the patch to the 10.x branch, but tests match-273, -274, and -284 are still failing.

I think this is because I happened to run them with -export:on, and the rewritten pattern isn't surviving the round trip through a SEF file.

Sure enough, the tests fail with -export:on on the 11.x branch as well.

Fixed by adding a completion action to invoke GeneralNodePattern.makeTopNodeEquivalent() in the package loader.

Actions #11

Updated by Michael Kay about 1 month ago

  • Status changed from In Progress to Resolved
  • Applies to branch 11, trunk added
  • Fix Committed on Branch 10, 11, trunk added
Actions #12

Updated by Rohit Gaikwad about 1 month ago

Thanks Michael for fixing this issue.

Please register to edit this issue

Also available in: Atom PDF