Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6772791

XSLT optimization inconsistency between JDK versions

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P3 P3
    • 5.0-pool
    • 6u10
    • core-libs
    • None

        The issue has been reported by SAP who use both JDK 1.5 and 6u10 in their development systems. Their code works with JDK 1.5. However, with JDK 6, the code seems to be optimized by the compiler. The conversation with SAP is provided below for your perusal.
        ---------------------------------------------------------------------------------
        During our tests with with jdk1.6 we found 2 problems with XSLT
        transformation.
        1. When using java extensions one sometimes has to use variables for
        adding content to the java object without later using this variable. The
        1.6 Java is optimizing the XSLT and removing these unused variables and
        the real purpose is lost.
        A workaround would be to have a second variable that gets assigned the
        value of the variable with java extension, but this is error prone in my
        opinion.
        I think that when extensions are used in variables they should not be
        optimized, another solution would be to have a switch that allows to
        disable the optimization.
        2. We have information in several XML files, we use one XSLT to
        transform them into 1 html report. Due to the size of the XML the only
        performant solution is to use <xsl:key ...>.
        With 1.5 it was possible to also have keys on XMLs that are loaded with
        the document() function, with 1.6 this doesn't work anymore. The
        workaround would be to use xpath statements, but this is a huge
        performance bottleneck. We have XMLs that are over 20MB in size with
        thousands of elements. Without keys the transformation drops from ~1min
        to over 30min which is not acceptable.

        I have attached a zip with XMLs and a XSLT that demonstrates these 2
        problems plus the resulting html, once for 1.5 and once for 1.6
        ---------------------------------------------------------------------------------
        actually a java file is not necessary. There is also an ant build file
        included (style.xml) that you can use (ant 1.6.4 or newer)
        Set JAVA_HOME to jdk 1.5 and run
        ant -f style.xml test1.5
        then set JAVA_HOME to jdk 1.6 and run
        ant -f style.xml test1.6
        You'll get the reports that are already included in the zip file.
        But if you want I can also create a small java class that calls the
        transformer, though it is not necessary.
        I think there is also a way to call the transformation from command
        line, but I don't know the class that can do this (as it is very easy
        with ant).
        ---------------------------------------------------------------------------------
        I've downloaded the latest jdk:
        java version "1.6.0_10"
        Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
        Java HotSpot(TM) Client VM (build 11.0-b15, mixed mode, sharing)

        The problem is still there.
        The bug reports do not help, the first one is not related to my
        problem, the second one doesn't exist.

        This problem might become critical to us, as it prevents us from
        switching our builds to jdk 1.6
        ---------------------------------------------------------------------------------
        one more question: The SUN JDK includes the Xalan from Apache (with the
        packages converted to com.sun so one can use another XSLT without
        problems).
        Which version of Xalan is included in jdk 1.5 and in jdk 1.6?
        The problem might be related to
        http://issues.apache.org/jira/secure/ViewIssue.jspa?key=XALANJ-2294
        ---------------------------------------------------------------------------------
        actually it must be the XLSTC that is optimizing the statements.
        Assigning a variable in XSLT, that modifies a java object should not be
        optimized.
        There is no other way than use a variable to change the java object. For
        clarification once more an XSL snippet to demonstrate this:

        <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        ,,xmlns:java="http://xml.apache.org/xslt/java"
        exclude-result-prefixes="java">

        <xsl:variable name="counter1" select="java:java.util.Vector.new()"/>

        <xsl:template match="/">
        <xsl:variable name="temp" select="java:add($counter1,'test')"/>
        Elements in Counter1: <xsl:value-of select="java:toString($counter1)"/>
        </xsl:template>
        </xsl:stylesheet>
        ---------------------------------------------------------------------------------
        I have to use the variable "temp" in order to add a value to the vector
        that is stored in the variable "counter", so the variable is never used
        but the statement "java:add($counter1,'test')" is crucial for the xslt
        to work. It might be ok to optimize out the variable "temp", but it is
        not ok to optimize out the "java:add($counter1,'test')".

        Doing the same thing with the interpreting XSLT processor in xalan works
        fine, so this is only an issue in XSLTC.
        ---------------------------------------------------------------------------------
        About the issue with the keys, I've taken a look at the W3C spec.
        For XSLT 1.0 (and afaik in jdk is only a 1.0 processor) the spec is not
        precise wether the "key" function should match only nodes from the
        document of the context node or nodes from all loaded documents. The
        spec for xslt "2.0" is better in this point, the key function can have
        an optional third argument specifying a node describing the document the
        "key" function should work on.
        So with jdk1.5 the "key" function returned nodes from all documents,
        while jdk1.6 only returns nodes from the document of the context node
        (see also here this also explains it
        http://issues.apache.org/jira/secure/ViewIssue.jspa?key=XALANJ-2294).
        For me this change in behaviour is an incompatible change and strongly
        reduces the functionality.
        ---------------------------------------------------------------------------------
        Let's have the following code:

        ArrayList<String> list = new ArrayList<String>();
        list.add("test");
        String r = list.remove(0);

        Now consider the variable "r" above is never used.
        Should the java compiler optimize this in the way that the
        list.remove(0) is not executed? Of course not the list.remove(0) is
        executed, but I'm sure the assignement to r is never done.
        But the XSLTC is just doing this. It is removing the list.remove(0).
        Now you can say ok, just change your code to:

        ArrayList<String> list = new ArrayList<String>();
        list.add("test");
        list.remove(0);

        Sure in java this works. But in XSLT it is not possible to just execute
        a function. The only simple way to do this is by assigning the result of
        the function call to a variable.
        ---------------------------------------------------------------------------------

              mbankal Mala Bankal (Inactive)
              duke J. Duke
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: