Uploaded image for project: 'XMLBeans'
  1. XMLBeans
  2. XMLBEANS-46

Regex validation fails in multi-threaded, multi-processor environment

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • Version 1.0.3, Version 2
    • unspecified
    • Validator
    • None
    • sun 1.4.2_04, jrockit 1.4.2_04, multi-cpu machine

    Description

      When using validate() method in multi-threaded, multi-cpu environment, there is a pretty high probability of getting false XMLErrors for elements defined with regex patterns in schema.

      import EDU.oswego.cs.dl.util.concurrent.CountDown;
      import junit.framework.TestCase;
      import org.apache.xmlbeans.XmlException;
      import org.apache.xmlbeans.XmlOptions;
      import org.apache.xmlbeans.XmlError;

      import java.util.Collection;
      import java.util.ArrayList;
      import java.util.Iterator;

      public class XmlBeansTest extends TestCase {

      public void testMultipleThreads() throws XmlException, InterruptedException {
      final int totalThreadCount = 100;
      CountDown latch = new CountDown(totalThreadCount);
      CountDown start = new CountDown(1);

      long now = System.currentTimeMillis();

      System.out.println("Starting");
      for (int i = 0; i < totalThreadCount; i++)

      { new ParseAndValidate(latch, start).start(); }

      start.release();
      latch.acquire();

      System.out.println("Finished: " + (System.currentTimeMillis() - now));
      }

      public static void main(String[] args) throws Exception, InterruptedException

      { XmlBeansTest xmlBeansTest = new XmlBeansTest(); xmlBeansTest.setUp(); xmlBeansTest.testMultipleThreads(); }

      private class ParseAndValidate extends Thread {

      private CountDown countDownLatch;
      private CountDown start;
      private final String xmldata = ...;

      public ParseAndValidate(CountDown countDownLatch, CountDown start)

      { this.countDownLatch = countDownLatch; this.start = start; }

      public void run() {
      try {
      start.acquire();
      boolean valid = parseAndValidate();
      if (!valid)

      { System.out.println("Not Valid!!!"); }

      countDownLatch.release();
      } catch (XmlException e)

      { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); }

      }

      private boolean parseAndValidate() throws XmlException

      { MyXml xml = MyXml.Factory.parse(xmldata); return validate(xml); }

      private boolean validate(MyXml rdd) {
      Collection errors = new ArrayList();
      XmlOptions validateOptions = new XmlOptions();
      validateOptions.setErrorListener(errors);
      boolean valid = rdd.validate(validateOptions);
      if (!valid) {
      for (Iterator iterator = errors.iterator(); iterator.hasNext()

      { XmlError xmlError = (XmlError) iterator.next(); System.out.println("XML Error - " + xmlError.getMessage() + " at\n" + xmlError.getCursorLocation().xmlText()); }

      }
      return valid;
      }
      }
      }

      The code above, when executed on a MP machine, has a pretty high probability (5%+ I'd say) of generating at least one failed validation. On machines with hyperthreading, the probability is even higher (10%+).
      I only saw it fail on regex patterns. On SP machines it never fails. The only workaround I've found is encasing a validate method in a globally synchronised block (not really a workaround, I know).
      The code also runs very slowly on MP machines with sun jdk, but that's unrelated to the problem I guess.

      Attachments

        Activity

          People

            kkrouse@bea.com Kevin Krouse
            dpredovic Dejan Predovic
            Votes:
            2 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: