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

SAXParser leaks file descriptors when an exception is thrown

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.8.0_101"
      Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Linux hostname-redacted 3.10.0-327.13.1.el7.x86_64 #1 SMP Thu Mar 31 16:04:38 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      The forms of SAXParser.parse that accept a File don't close it when a parsing exception occurs.


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.io.File;
      import java.io.FileWriter;
      import java.lang.management.ManagementFactory;

      import javax.management.MBeanServer;
      import javax.management.ObjectName;
      import javax.xml.parsers.SAXParser;
      import javax.xml.parsers.SAXParserFactory;

      import org.xml.sax.helpers.DefaultHandler;

      public class Show
      {

          public static void main(String[] args) throws Exception
          {
              MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
              tryParsing(true);
              tryParsing(false);
              System.out.printf("At launch there are %d open descriptors\n", openFds(mbs));

              for (int i = 0; i < 5; i++)
              {
                  tryParsing(true);
                  System.out.printf("After parsing valid XML there are %d open descriptors\n", openFds(mbs));
                  tryParsing(false);
                  System.out.printf("After parsing invalid XML there are %d open descriptors\n", openFds(mbs));
              }
          }

          private static void tryParsing(boolean valid) throws Exception
          {
              SAXParserFactory factory = SAXParserFactory.newInstance();
              SAXParser parser = factory.newSAXParser();

              File temp = new File("/tmp/test.xml");
              try (FileWriter w = new FileWriter(temp))
              {
                  w.write(valid ? "<validxml/>" : "invalidxml");
              }

              try
              {
                  parser.parse(temp, new DefaultHandler());
              }
              catch (Exception e)
              {
                  // discard
              }
          }

          private static Long openFds(MBeanServer mbs) throws Exception
          {
              ObjectName os = new ObjectName("java.lang:type=OperatingSystem");
              return (Long) mbs.getAttribute(os, "OpenFileDescriptorCount");
          }

      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Use a try-with-resources to open the file and pass an InputSource wrapping a FileInputStream.

            joehw Joe Wang
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: