FULL PRODUCT VERSION :
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) Server VM (build 11.0-b15, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
OpenSuSe 11.0
Linux dev3 2.6.25.18-0.2-pae #1 SMP 2008-10-21 16:30:26 +0200 i686 i686 i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
javax.xml.validation.Schema is not thread safe, according documentation:
A Schema object is thread safe and applications are encouraged to share it across many parsers in many threads.
but I have problem when sharing schema instance, my validation failed
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Validating....
Validating....
Validating....
org.xml.sax.SAXException: **Parsing Error. Line: -1 URI: null Message: cvc-complex-type.2.4.d: Invalid content was found starting with element '{TransactionRecord}'. No child element is expected at this point.
(see complete stack trace in attachment)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package com.sargis;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class XMLValidationTest {
private static final int NTHREADS = 25;
private static final ExecutorService EXEC = Executors.newCachedThreadPool();
private static final CyclicBarrier BARRIER = new CyclicBarrier(NTHREADS);
public static final String IN_FOLDER = "/home/sargis/projects/twm/branches/ng/epayment/Vasp/dist/inout/in";
public static final String XSD_PATH = "/home/sargis/projects/twm/branches/ng/epayment/Vasp/config/epayoth.xsd";
private static Schema schema;
public static void main(String[] args) {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Source schemaFile = new StreamSource(XSD_PATH);
try {
schema = factory.newSchema(schemaFile);
} catch (SAXException e) {
e.printStackTrace();
System.exit(-1);
}
File incoming = new File(IN_FOLDER);
File[] files = incoming.listFiles(new FileFilter() {
public boolean accept(File file) {
return file.isFile() && file.getName().endsWith(".xml");
}
});
for (int i = 0; i < files.length; i++) {
EXEC.execute(new XMLValiddator(files[i], i));
}
EXEC.shutdown();
}
private static class XMLValiddator implements Runnable {
private File file;
private int index;
public XMLValiddator(File file, int index) {
this.file = file;
this.index = index;
}
public void run() {
try {
System.out.printf("Waiting for barrier: %s%n", index);
BARRIER.await();
System.out.println("Validating....");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(file);
Validator validator = schema.newValidator();
validator.setErrorHandler(new ErrorHandlerImpl());
validator.validate(new DOMSource(document));
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static class ErrorHandlerImpl implements ErrorHandler {
public void warning(SAXParseException exception) throws SAXException {
System.out.printf("**Parsing Warning. Line: %s URI: %s Message: %s%n",
exception.getLineNumber(), exception.getSystemId(), exception.getMessage());
}
public void error(SAXParseException exception) throws SAXException {
String msg = String.format("**Parsing Error. Line: %s URI: %s Message: %s%n",
exception.getLineNumber(), exception.getSystemId(), exception.getMessage());
System.out.println(msg);
throw new SAXException(msg);
}
public void fatalError(SAXParseException exception) throws SAXException {
String msg = String.format("**Parsing Fatal Error. Line: %s URI: %s Message: %s%n",
exception.getLineNumber(), exception.getSystemId(), exception.getMessage());
System.out.println(msg);
throw new SAXException(msg);
}
}
}
---------- END SOURCE ----------