-
Bug
-
Resolution: Won't Fix
-
P3
-
6u10
-
None
-
generic
-
windows_vista
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2170006 | 7 | Unassigned | P3 | Closed | Won't Fix | |
JDK-2170005 | 6-pool | Mala Bankal | P3 | Closed | Won't Fix |
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.
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
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.
---------------------------------------------------------------------------------
- backported by
-
JDK-2170005 XSLT optimization inconsistency between JDK versions
-
- Closed
-
-
JDK-2170006 XSLT optimization inconsistency between JDK versions
-
- Closed
-