SAPTechno

Note 1273115 - Size limitation for XSLT stylesheets

Header
Version / Date 5 / 2008-11-12
Priority Correction with medium priority
Category Release planning information
Primary Component BC-JVM SAP Java Virtual Machine
Secondary Components

Summary
Symptom

Document transformations using large XSLT stylesheets fail with Java exception "com.sun.org.apache.bcel.internal.generic.ClassGenException: Branch target offset too large for short" when used with SAP JVM 5.1, 6.1 or other derivates of Sun's JDK 5 or 6 (e.g the HP JDK 1.5). They formerly worked with JDKs of version 1.4.2.

Other terms

SAP NetWeaver PI 7.1
com.sap.aii.messaging.adapter.XSLTConversion
"Error initializing XSLT Mode:; caused by javax.xml.transform.TransformerConfigurationException: Could not compile stylesheet"

Reason and Prerequisites

Template definitions contained in XSLT stylesheets are compiled by SAP JVM's XSLT compiler "Xalan" into Java methods for faster execution of transformations. Java bytecode branch instructions contained in these Java methods are limited to 32K offsets. Large template definitions can now lead to very large Java methods, where the branch offset would need to be larger than 32K. Therefore these stylesheets cannot be compiled to Java methods and therefore cannot be used for transformations.

Solution

Since each template definition of an XSLT stylesheet is compiled into a separate Java method, using multiple smaller templates can be used as solution. A very large template can be broken into multiple smaller templates by using the "call-template" element.

As an example see the following stylesheet containing 1 large template:

[...]
<xsl:stylesheet version="1.0" ... >
  <xsl:template match="/MyTopLevelElement">
    <xsl:for-each select="MySubElementA0">
      <NewElementA0>
        <xsl:value-of select="."/>
      </NewElementA0>
    </xsl:for-each>
    <xsl:for-each select="MySubElementA1">
      <NewElementA1>
        <xsl:value-of select="."/>
      </NewElementA1>
    </xsl:for-each>
    [...]
    <xsl:for-each select="MySubElementA98">
      <NewElementA98>
        <xsl:value-of select="."/>
      </NewElementA98>
    </xsl:for-each>
    <xsl:for-each select="MySubElementA99">
      <NewElementA99>
        <xsl:value-of select="."/>
      </NewElementA99>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

This template can be changed into the following stylesheet containing multiple (here: 10) smaller templates called by the main template (at the end of the example below):

[...]
<xsl:stylesheet version="1.0" ... >
<xsl:template name="SubElements0to9">
    <xsl:for-each select="MySubElementA0">
      <NewElementA0>
        <xsl:value-of select="."/>
      </NewElementA0>
    </xsl:for-each>
    [...]
    <xsl:for-each select="MySubElementA9">
      <NewElementA9>
        <xsl:value-of select="."/>
      </NewElementA9>
    </xsl:for-each>
  </xsl:template>
  [...]
<xsl:template name="SubElements90to99">
    <xsl:for-each select="MySubElementA90">
      <NewElementA90>
        <xsl:value-of select="."/>
      </NewElementA90>
    </xsl:for-each>
    [...]
    <xsl:for-each select="MySubElementA99">
      <NewElementA99>
        <xsl:value-of select="."/>
      </NewElementA99>
    </xsl:for-each>
  </xsl:template>
  <xsl:template match="/MyTopLevelElement">
    <xsl:call-template name="SubElements0to9"/>
    [...]
    <xsl:call-template name="SubElements90to99"/>
  </xsl:template>
</xsl:stylesheet>

If the source template is using local variables or parameters, of course appropriate XSL constructs have to be choosen to pass them to the smaller templates with the "call-template" element (e.g. via "with-param" elements).

Affected Releases
Software Component Release From Release To Release And subsequent
SAPJVM5.15.15.1
SAPJVM6.16.16.1

Related Notes
1362176Upgrade to SAP NW 7.1 EHP 1 for banking services 7.0 and 8.0
1252365Upgrades based on SAP NetWeaver 7.1 including EHP 1
1061649Upgrade to SAP NetWeaver Process Integration 7.1