Uploaded image for project: 'Xerces2-J'
  1. Xerces2-J
  2. XERCESJ-727

cloneNode(true) Element are still linked to original Element

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Resolution: Unresolved
    • 2.4.0
    • None
    • DOM (Level 3 Core)
    • None
    • Operating System: Windows NT/2K
      Platform: PC
    • 19982

    Description

      NB : tested only under Windows 2000/ jdk 1.4.1_02
      -------

      • Create a DOM Element.
      • Create many threads, giving each of them a cloneNode(true) copy of the
        Element.
      • Start all the threads.
      • Each thread just finds the Element's embedded sub-Elements.

      The following Exceptions occur many times (but not always) :
      java.lang.NullPointerException
      at org.apache.xerces.dom.ParentNode.nodeListItem(Unknown Source)
      at org.apache.xerces.dom.ParentNode.item(Unknown Source)
      at Tst2Threads.run(Tst2Threads.java:40)
      java.lang.NullPointerException
      at org.apache.xerces.dom.ParentNode.nodeListItem(Unknown Source)
      at org.apache.xerces.dom.ParentNode.item(Unknown Source)
      at Tst2Threads.run(Tst2Threads.java:41)

      where lines 40 and 41 are :
      if ( lesNoeuds.item.getNodeType() != Element.ELEMENT_NODE ) continue;
      noeud = (Element)(lesNoeuds.item( i ));
      in the following example.
      NB : if I create an different Element from file for each thread creation
      (different Element instances, not created from cloneNode) then no Exception
      occurs

      This seems a wrong behaviour, keeping Xerces from being used in multi-threading
      environment.
      I understand that Xerces is not thread safe, but how can I use same data in
      different threads if the cloning fails this way ?
      How can I write correct thread safe code using DOM data ?

      These symptoms seem close to bug #6885 but are NOT DUPLICATE at first sight :
      there is no concurrent access on the same instance in my example.

      Thanks to tell me if there is any error in my code. I am interested in any
      workaround for that behaviour...

      Francois.

      ***************************************
      Here follows a code example (sorry for poor comments .
      Usage :

      • just run it from command line,
      • enter a XML file name, Element used will be the first one read from file (I
        suggest a consequent Element),
      • enter a number of threads,
        ==> with 200 threads the Exception occurs almost immediately.
        ***************************************
        import org.w3c.dom.*;

      public class Tst2Threads extends Thread
      {
      static protected Document readDOM( String nomFichier ) throws Exception

      { java.net.URL url= new java.net.URL( nomFichier ); java.io.InputStream inputXML = url.openStream(); javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); factory.setValidating( false ); factory.setNamespaceAware( false ); factory.setIgnoringComments( true ); javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse( inputXML ); return document; }

      /*******************************************************/
      Element element = null;

      public Tst2Threads(ThreadGroup gp, Element elt, String _nom)

      { super( gp, _nom); element = elt; }

      public void run()
      {
      NodeList lesNoeuds = element.getChildNodes();
      Element noeud;
      while (true)
      {
      for (int i=0, max=lesNoeuds.getLength(); i<max ; i++)

      { if ( lesNoeuds.item(i).getNodeType() != Element.ELEMENT_NODE ) continue; noeud = (Element)(lesNoeuds.item( i )); }

      }
      }

      // get first Element
      static Element readElmt(String nomFic) throws Exception
      {
      Document doc = readDOM( "file://"+nomFic );

      NodeList liste = doc.getChildNodes();
      boolean done = false;
      Element elmt = null;
      if (liste != null)
      {
      for(int i=0, max=liste.getLength(); (i<max) && (! done); i++)

      { if ( liste.item(i).getNodeType() != Element.ELEMENT_NODE ) continue; elmt = (Element)(liste.item( i )); done = true ; }

      }
      return elmt;
      }

      /*******************************************************/
      public static void main( java.lang.String[] args)
      {
      try
      {
      java.io.BufferedReader br=new java.io.BufferedReader( new
      java.io.InputStreamReader( System.in));

      System.out.print("XML file name for Element description
      [d:/tmp/menu.xml] :");
      String nomFic= br.readLine();
      if ("".equals(nomFic)) nomFic = "d:/tmp/menu.xml";
      Element elmt = readElmt(nomFic);

      System.out.print("Nb of threads [200] :");
      String s= br.readLine();
      if ("".equals(s)) s="200";
      int nbThreads = Integer.valueOf(s).intValue() - 1;

      System.out.println(" Starting for :\n file="nomFic"\n nb
      threads="+nbThreads);

      ThreadGroup groupe = new ThreadGroup("TEST");
      Tst2Threads t;
      for (int i=0; i<nbThreads; i++)

      { // Element cloned here (from main thread --v) t = new Tst2Threads(groupe, (Element)(elmt.cloneNode(true)), "Th"+i); t.start(); }

      }
      catch (Throwable t)

      { t.printStackTrace(); }

      }
      }

      Attachments

        Activity

          People

            Unassigned Unassigned
            fabot@lucent.com Francois Abot
            Votes:
            2 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: