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

(prefs) ClassCastException in prefs.XmlSupport using non-Crimson JAXP XML Parser

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P4
    • 6
    • 1.4.0
    • core-libs
    • b17
    • x86
    • windows_2000

    Description

      Name: nt126004 Date: 06/10/2002


      FULL PRODUCT VERSION :
      java version "1.4.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
      Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

      FULL OPERATING SYSTEM VERSION :
      Microsoft Windows XP [Version 5.1.2600]


      ADDITIONAL OPERATING SYSTEMS :
      Problem is generic to any OS


      A DESCRIPTION OF THE PROBLEM :
      When using the new JDK 1.4 Preferences API with a JAXP 1.1
      compliant parser *OTHER* than Sun's Crimson parser, you
      receive a ClassCastException when the code on line 183 and
      line 192 incorrectly cast the 2nd child node of the XML
      Document node to an org.w3c.dom.Element.

      ANALYSIS
      ========
      java.util.prefs.XmlSupport on lines 183 and 192 contains
      code that uses DOM api's in a way that makes a bad
      assumption, and this assumption makes this code fail
      against Oracle XML Parser as well as Xerces 2.0.1. It
      works fine against the Crimson parser.

      Line 182/183 look like this:

       String xmlVersion =
       ((Element)doc.getChildNodes().item(1)).getAttribute
      ("EXTERNAL_XML_VERSION");


      Line 191/192 looks like this:

       Element xmlRoot = (Element) doc.getChildNodes().item(1).
                                          getChildNodes().item
      (0);


      Both of these are bad DOM code because they are making the
      incorrect assumption that the document element is the 2nd
      child node of the document root node. They should use the
      DOM function getDocumentElement() instead like this:

      CHANGE line 182/183 to look like this:

       String xmlVersion =
       doc.getDocumentElement().getAttribute
      ("EXTERNAL_XML_VERSION");

      CHANGE line 191/192 to look like this:

       Element xmlRoot = doc.getDocumentElement().
                                          getChildNodes().item
      (0);


      I tested this fix and then it works correctly with Xerces
      and OracleXML.

      REGRESSION. Last worked in version 1.4

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Download Apache Xerces 2.0.1
         from http://xml.apache.org/dist/xerces-j/Xerces-J-
      bin.2.0.1.tar.gz
         or Oracle XML Parser 9.2.0.2
         from http://otn.oracle.com/tech/xml/xdk_java

      2. Run the test program provided with Xerces 2.0.1
         or Oracle XML Parser 9.2.0.2 in your classpath

      3. Run without either of these in your classpath to
         observe that it works with Crimson.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      I expected the preferences XML file to load without
      getting a ClassCastException with any JAXP 1.1 compliant
      XML Parser, in particular, with Oracle XML Parser 9.2.0.2
      or Xerces 2.0.1, two popular JAXP 1.1 compliant XML
      parsers in use in the Java community.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      ClassCastException occurs at line 183 of java.util.prefs.XmlSupport

      for reasons indicated in the analysis above.

      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.io.ByteArrayInputStream;
      import java.util.prefs.Preferences;
      public class Bug {
      public static void main(String[] args) throws Throwable {
            // ClassCastException using Xerces 2.0.1 or Oracle XML 9.2.0.2
            Preferences.importPreferences(
               new ByteArrayInputStream(PREFS.getBytes()));
            System.out.println("ok");
        }
        private static String PREFS =
        "<?xml version='1.0'?>\n"+
        "<!DOCTYPE preferences SYSTEM 'http://java.sun.com/dtd/preferences.dtd&#39;>"+
        "\n"+
        "<preferences EXTERNAL_XML_VERSION='1.0'>"+
        " <root type='user'>"+
        " <map />"+
        " <node name='Test'>"+
        " <map>"+
        " <entry key='TestEntry' value='true' />"+
        " </map>"+
        " </node>"+
        " </root>"+
        "</preferences>";
      }
      ---------- END SOURCE ----------

      CUSTOMER WORKAROUND :
      Don't use the new Preferences feature if you are required
      by other reasons to use a non-Crimson parser in your
      application.

      No real workaround, other than patching the source code of
      this JDK class and including the patch using -
      Xbootclasspath/p

        Patch is:

      CHANGE line 182/183 to look like this:

       String xmlVersion =
       doc.getDocumentElement().getAttribute
      ("EXTERNAL_XML_VERSION");

      CHANGE line 191/192 to look like this:

       Element xmlRoot = doc.getDocumentElement().
                             getChildNodes().item(0);
      (Review ID: 148317)
      ======================================================================
      ###@###.### 10/28/04 07:40 GMT

      Attachments

        Activity

          People

            sherman Xueming Shen
            nthompsosunw Nathanael Thompson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: