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

XSLTC cannot handle large stylesheets; error loading DocBook Slides

    XMLWordPrintable

Details

    • x86, sparc
    • linux_redhat_9.0, linux_suse_sles_9, solaris_9, windows_xp

    Description

      There is a regression in the Xalan XSLT engine from JDK 1.4.2_04 to JDK 1.5.0 when handling large stylesheets, probably due to the use of XSLTC by default.

      It seems that very large stylesheets can overrun the maximum size of a method in the JVM, and there is no check for this (to fall back to interpreted mode, or break up the method into loadable pieces).

      Known to affect the DocBook Slides stylesheets, which are fairly complex (processes all of DocBook XML).


      To reproduce:

      1. Download from http://sourceforge.net/project/showfiles.php?group_id=21935 (docbook.sf.net):

         docbook-xsl-1.65.1.tar.gz
         slides-3.3.1.tar.gz

         Note: these are the most recent releases at time of writing. Bug appears also with earlier versions.

      2. Unpack both to disk somewhere, e.g.

         $ cd /tmp
         $ tar xvfz docbook-xsl-1.65.1.tar.gz
         $ slides-3.3.1.tar.gz

         Adjust file paths below (in RESOLVER_MAPPING) if you choose a different path.

      3. Compile this class (using JDK 1.4.2 so the class file can be used w/ both JDKs):

      ---%<---
      package testXsltBug;
      import java.io.IOException;
      import java.net.URL;
      import java.util.*;
      import javax.xml.parsers.SAXParserFactory;
      import javax.xml.transform.*;
      import javax.xml.transform.sax.SAXSource;
      import javax.xml.transform.stream.StreamSource;
      import org.xml.sax.*;
      public class Main {
          private static final String XSL_SLIDES = "http://docbook.sourceforge.net/release/slides/current/xsl/xhtml/plain.xsl";
          private static final Map/*<String,String>*/ RESOLVER_MAPPING = new HashMap();
          static {
              RESOLVER_MAPPING.put("http://docbook.sourceforge.net/release/slides/current/", "file:/tmp/slides-3.3.1/");
              RESOLVER_MAPPING.put("http://docbook.sourceforge.net/release/xsl/current/", "file:/tmp/docbook-xsl-1.65.1/");
          }
          public static void main(String[] args) throws Exception {
              SAXParserFactory saxpf = SAXParserFactory.newInstance();
              saxpf.setNamespaceAware(true);
              XMLReader reader = saxpf.newSAXParser().getXMLReader();
              EntityResolver resolver = new TestResolver();
              reader.setEntityResolver(resolver);
              InputSource styleSource = resolver.resolveEntity(null, XSL_SLIDES);
              Source style = new SAXSource(reader, styleSource);
              TransformerFactory tf = TransformerFactory.newInstance();
              tf.setURIResolver(new EntityResolver2URIResolver(resolver));
              Transformer t = tf.newTransformer(style);
              System.out.println("OK.");
          }
          private static final class TestResolver implements EntityResolver {
              public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
                  Iterator it = RESOLVER_MAPPING.entrySet().iterator();
                  while (it.hasNext()) {
                      Map.Entry e = (Map.Entry)it.next();
                      String prefix = (String)e.getKey();
                      if (systemId.startsWith(prefix)) {
                          String suffix = (String)e.getValue();
                          return new InputSource(suffix + systemId.substring(prefix.length()));
                      }
                  }
                  return null;
              }
          }
          private static final class EntityResolver2URIResolver implements URIResolver {
              private final EntityResolver resolver;
              public EntityResolver2URIResolver(EntityResolver resolver) {
                  this.resolver = resolver;
              }
              public Source resolve(String href, String base) throws TransformerException {
                  try {
                      String abs = new URL(new URL(base), href).toExternalForm();
                      InputSource s = resolver.resolveEntity(null, abs);
                      if (s != null) {
                          return new StreamSource(s.getSystemId());
                      } else {
                          return null;
                      }
                  } catch (SAXException e) {
                      throw new TransformerException(e);
                  } catch (IOException e) {
                      throw new TransformerException(e);
                  }
              }
          }
      }
      ---%<---

         Note that the test class just loads the stylesheet - does not try to use it. The resolver is needed because the Slides stylesheets refer to the main stylesheets by HTTP.

      4. Run on JDK 1.4.2_04:

      ---%<---
      $ /space/jdk1.4.2_04/bin/java -cp /tmp/test-xslt-bug/build/classes -showversion testXsltBug.Main
      java version "1.4.2_04"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_04-b02)
      Java HotSpot(TM) Client VM (build 1.4.2_04-b02, mixed mode)

      OK.
      ---%<---

      5. Now run on JDK 1.5.0 b51:

      ---%<---
      $ /space/jdk1.5.0-b51/bin/java -cp /tmp/test-xslt-bug/build/classes -showversion testXsltBug.Main
      java version "1.5.0-beta2"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b51)
      Java HotSpot(TM) Client VM (build 1.5.0-beta2-b51, mixed mode, sharing)

      Exception in thread "main" javax.xml.transform.TransformerConfigurationException: Could not load the translet class 'plain'.
      at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.defineTransletClasses(TemplatesImpl.java:315)
      at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:333)
      at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:366)
      at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:620)
      at testXsltBug.Main.main(Main.java:27)
      ---%<---

      6. Using a patched version of TemplatesImpl.java that prints a stack trace when it catches ClassFormatError:

      ---%<---
      $ /space/jdk1.5.0-b51/bin/java -Xbootclasspath/p:/tmp/test-boot-cp -cp /tmp/test-xslt-bug/build/classes testXsltBug.Main
      java.lang.ClassFormatError: Invalid method Code length 94971 in class file plain
      at java.lang.ClassLoader.defineClass1(Native Method)
      at java.lang.ClassLoader.defineClass(ClassLoader.java:605)
      at java.lang.ClassLoader.defineClass(ClassLoader.java:449)
      at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$TransletClassLoader.defineClass(TemplatesImpl.java:125)
      at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.defineTransletClasses(TemplatesImpl.java:296)
      at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:334)
      at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:367)
      at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:620)
      at testXsltBug.Main.main(Main.java:27)
      Exception in thread "main" javax.xml.transform.TransformerConfigurationException: Could not load the translet class 'plain'.
      at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.defineTransletClasses(TemplatesImpl.java:316)
      at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:334)
      at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:367)
      at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:620)
      at testXsltBug.Main.main(Main.java:27)
      ---%<---


      My system:
      LSB_VERSION="1.3"
      Red Hat Linux release 9 (Shrike)
      Linux localhost 2.4.20-20.9 #1 Mon Aug 18 11:45:58 EDT 2003 i686 i686 i386 GNU/Linux
      glibc-2.3.2-27.9.7

      ###@###.### 2004-06-02
      ###@###.### 2004-06-10
      Please use this small proggy (also attached):

      import java.io.File;
      import javax.xml.transform.Source;
      import javax.xml.transform.Transformer;
      import javax.xml.transform.TransformerFactory;
      import javax.xml.transform.stream.StreamSource;

      public class XMLProblemDemo {
              public static void main(String[] args) {
                      Source xslt = new StreamSource(new File(args[0]));

                      try {
                      TransformerFactory factory = TransformerFactory.newInstance();
                      Transformer tr = factory.newTransformer(xslt);
                      System.out.print("\nSuccess\n");
                      } catch (Exception e) { System.out.print("\nFailure\n");
                                                                      e.printStackTrace();}
              }
      }


      And run it with the files attached (good.xsl + bad.xsl):

      > > java XMLProblemDemo good.xsl
      >
      > Success
      > > java XMLProblemDemo bad.xsl
      >
      > Failure
      > javax.xml.transform.TransformerConfigurationException: Could not load the translet class 'bad'.
      > at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.defineTransletClasses(TemplatesImpl.java:315)
      > at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:333)
      > at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:366)
      > at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:620)
      > at XMLProblemDemo.main(XMLProblemDemo.java:13)

      Attachments

        Issue Links

          Activity

            People

              spericas Santiago Pericasgeertsen
              jglick Jesse Glick (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: