How to disable fatal error showing in java? - java

I would like to know if it is possible to disable the [Fatal Error]:1:50: White spaces are required between publicId and systemId. error in my java program.
Im using java built-in DOM parser api to parse an XML document. The xml document is deliberately incorrect because I want to learn how to handle exceptions related to xml parsing. I also want to say that when the xml document is correct, no exception occurs.
I have already tried with the following :
try {
Document doc = documentBuilder.parse(xmlDocument)
} catch (Throwable t){
System.out.println("An error occur when parsing");
}
The code inside the catch block is displayed correctly but the fatal error message is still showing.
If anyone has a solution, I would be delighted, thanks.

The problem is that by default the error handler for the XML parser prints the errors to the output. You can install your own handler to capture or ignore the errors:
class NullErrorHandler implements ErrorHandler {
#Override
public void fatalError(SAXParseException e) {
// do nothing
}
#Override
public void error(SAXParseException e) {
// do nothing
}
#Override
public void warning(SAXParseException e) {
// do nothing
}
}
Use it as follows:
documentBuilder.setErrorHandler(new NullErrorHandler());
You could also have an error handler that, for example, stored the exceptions in lists in member variables, so you could access them and examine them after parsing the document.
Here's a fully worked-out example:
import javax.xml.parsers.*;
import org.xml.sax.*;
String xml = """
<?xml version="1.0"?>
<!DOCTYPE whatsupdoc PUBLIC
"http://example.com/bugs""http://example.com/bunny">
""";
InputSource getXmlInput(String xml) {
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
return is;
}
var documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
documentBuilder.parse(getXmlInput(xml)); // prints the error and throws
documentBuilder.setErrorHandler(new NullErrorHandler());
documentBuilder.parse(getXmlInput(xml)); // only throws, does not print

Related

Premature end of file exception on XML file parsing occurs frequently but not regularly.

I am currently trying to run a thread to read files from a directory and parse it.
The thread is to continuously watch the directory and send the listened file to process to parse.
I am facing "Premature end of file - org.xml.sax.SAXParseException" on continuously placing files in the specified directory using FTP.
I have tried checking for completion of file transfer and there is no error there.
I have not used inputSource/InputStream to read the file. In addition to that, I make sure that I am not reading the empty file. I just used Dom parser parse method to parse a given file.
I will attach both XML file and the java program for further reference.
I have read many blogs and links. However, no luck. Any assistance would be really helpful.
public class DirectoryWatcher implements Runnable {
private DocumentBuilderFactory factory;
private XPath xpath;
private Document doc;
public DirectoryWatcher() {
this.factory = DocumentBuilderFactory.newInstance();
this.factory.setNamespaceAware(true); // XML contains name space pattern. Hence without configuration of name
// space, XML will not be parsed
this.xpath = XPathFactory.newInstance().newXPath();
}
#Override
public void run() {
while (!cancel) {
try {
for (String file : directory.list(filter)) {
doc = factory.newDocumentBuilder().parse(directory.getAbsolutePath() + File.separator + file);
markAsProcessed(file);
TimeUnit.MILLISECONDS.sleep(interval);
}
} catch (InterruptedException e) {
cancel = true;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Error while parsing the file xx/parked.xml Premature end of file.
[Ljava.lang.StackTraceElement;#38661fd
org.xml.sax.SAXParseException; systemId: file:///home/sample.xml ;

Strange JAXB Exception after GIT merge - SAXParseException - well-formed character data?

After doing a GIT rebase, out of nowhere, I started receiving this exception:
by: org.xml.sax.SAXParseException: "The content of elements must consist of well-formed character data or markup"
The Java code simply tries to unmarshall an xml file to a jaxb object. Something like this:
...
FGIXmlValidationEventCollector collector = new FGIXmlValidationEventCollector();
Unmarshaller unmarshaller = null;
try {
unmarshaller = context.createUnmarshaller();
unmarshaller.setSchema(getSchema());
unmarshaller.setEventHandler(collector);
} catch (JAXBException e) {
throw new FGIXmlException(e);
} catch (SAXException e) {
throw new FGIXmlException(e);
}
public Schema getSchema() throws SAXException {
SchemaFactory schemaFactory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
URL schemaLocation = getClass().getResource("/config/xsd/fgi.xsd");
**return schemaFactory.newSchema(schemaLocation); // exception is thrown here!!!**
}
I'm clueless. There was no code change that justifies this. This code has worked for many years. I don't know why after some trivial git pull/rebase I ended up with this behavior. By the way, there's no apparent problem whatsoever with the XML file that I want to unmarshall. It's an UFT-8 xml file. I've even tried changing the encoding but to no avail.
Any ideas?
Thank you

Jdom2 parser with empty xml document

I am trying to parse a string representation of a xml document with jdom2. I expect the xml string
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
to be a valid xml document. But when I run this simple code snippet:
import java.io.IOException;
import java.io.StringReader;
import org.jdom2.*;
public class Main {
public static void main(String []args){
SAXBuilder parser = new SAXBuilder();
String data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
try {
Document doc = parser.build(new StringReader(data));
} catch (JDOMException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I receive the error:
org.jdom2.input.JDOMParseException: Error on line 1: Premature end of file.
at org.jdom2.input.sax.SAXBuilderEngine.build(SAXBuilderEngine.java:232)
at org.jdom2.input.sax.SAXBuilderEngine.build(SAXBuilderEngine.java:303)
at org.jdom2.input.SAXBuilder.build(SAXBuilder.java:1196)
at testpack.Main.main(Main.java:32)
Does the xml specification not allow an xml payload without an root element?
If not, how should I check if the xml document is empty?
Edit: I also noticed that the documentation in Jdom2 for the Document() class states that
A document must have a root element, so this document will not be well-formed and accessor methods will throw an IllegalStateException if this document is accessed before a root element is added.
It might just be that Jdom2 doesn't support empty xml documents?
After further investigation I have noted that the specification for and xml document as defined by w3 specifies that a 'Well formed xml document' should adhere to
It contains one or more elements.
Meaning zero elements is not an option. The input xml String is a malformed xml string.

xml 1.1 causing NullPointerException when used in xsd

I have an xsd file. I am trying to create javax.xml.validation.Schema using that xsd file. I have written a program that does it. When I use <?xml version="1.0" encoding="UTF-8"?> every thing works fine. But when I use <?xml version="1.1" encoding="UTF-8"?> then the first attempt to create the Schema is throwing NPE but the second and subsequent attempts are successful. Below is the source:
import java.io.File;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
public class Test {
SchemaFactory sf = null;
public static void main(String args[]) {
Test test = new Test();
test.init();
File schemaFile = new File("D:\\test.xsd");
try {
test.doIt(schemaFile);
} catch (Exception e) {
System.out.println("doIt() failed " + e.getMessage());
}
try {
test.doItAgain(schemaFile);
} catch (Exception e) {
System.out.println("doItAgain() failed " + e.getMessage());
}
System.out.println("Execution completed");
}
public void doIt(File schemaFile) throws Exception {
#SuppressWarnings("unused")
Schema schema = null;
synchronized (sf) {
schema = sf.newSchema(schemaFile);
}
System.out.println("doIt() success");
}
public void doItAgain(File schemaFile) throws Exception {
#SuppressWarnings("unused")
Schema schema = null;
synchronized (sf) {
schema = sf.newSchema(schemaFile);
}
System.out.println("doAgainIt() success");
}
public void init() {
sf = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
}
}
The method (doIt() or doItAgain()) executed first is throwing NPE.
Below is the stack trace:
java.lang.NullPointerException
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1738)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1770)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipSpaces(XMLEntityScanner.java:1543)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$TrailingMiscDriver.next(XMLDocumentScannerImpl.java:1400)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
at com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaParsingConfig.parse(SchemaParsingConfig.java:435)
at com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaParsingConfig.parse(SchemaParsingConfig.java:491)
at com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaDOMParser.parse(SchemaDOMParser.java:510)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getSchemaDocument(XSDHandler.java:1802)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:531)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:552)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:519)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:485)
at com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:210)
at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:594)
at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:610)
at Test.doIt(Test.java:39)
at Test.main(Test.java:20)
My question is,
Why XML 1.1 is not working properly?
Why only first attempt is unsuccessful?
I found that if I use the latest versio of Xerces jar I dont face the isue. I also found that the problem is because there is a bug in JDK itself and its also logged at openjdk website and more interesting is that no one cared to fix this. So, use latest version of Xerces jar or use xml version 1.0. I will go with the first option. Who knows how many hidden surprises would be there in the old one :P

How do I pass an error message generated by xslt to java application caller

I use a java application to call a xslt to do a xml transformation. The xslt file will generate a message and terminate the process if some condition happens. However, my java application couldn't catch the error message generated by xslt, it only catch an exception with general information - "Stylesheet directed termination".
Here is my java code:
SAXTransformerFactory saxTFactory = ((SAXTransformerFactory) tFactory);
// Create a TransformerHandler for stylesheet.
File f2 = new File(styleSheetPath);
TransformerHandler tHandler2 = saxTFactory.newTransformerHandler(new StreamSource(f2));
XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setContentHandler(tHandler2);
reader.setProperty("http://xml.org/sax/properties/lexical-handler", tHandler2);
CharArrayWriter outputWriter = new CharArrayWriter();
Result result = new StreamResult(outputWriter);
tHandler2.setResult(result);
try
{
reader.parse(new InputSource(new StringReader(XMLinput)));
}
catch(Exception ee)
{
dsiplay(ee.getMessage())
throw ee;
}
How can I catch the error message from xslt?
I tried to write a class:
private class MyErrorHandler extends DefaultHandler{
public void error(SAXParseException e)
{
System.out.println("error method "+e.getMessage());
}
public void fatalError(SAXParseException e)
{
System.out.println("fatal error method "+e.getMessage());
}
public void warning(SAXParseException e)
{
System.out.println("warning method "+e.getMessage());
}
and
MyErrorHandler myHandler = new MyErrorHandler();
reader.setErrorHandler(myHandler);
It didn't work.
Do you have any suggestion?
It looks as if you have placed an error handler on the source document XML parser, but are trying to catch errors from the transformer. So place the error handler on the Transformer rather than the XMLReader
tHandler2.getTransformer().setErrorListener(myHandler);
IIRC, I've always kept it simple and used Transformer directly rather than go for ContentHandler/TranformerHandler.
As alternatives you could go for an implementation specific extension or cause a special URI to be resolved and handle that (although as XSLT is a functional language, I guess it could technically resolve a URI that wont actually impact the result).
In what way is the XSLT generating an error and terminating? This might be crucial since the
<xsl:message>
tag does not always write to the standard output like you might expect. Especially with Saxon.
Thank you so much for the replying. Here is my xslt code:
<xsl:template match="*[not(*) and ((text() and not(normalize-space(text()) != '')) or .='')
and name(.) != 'para' and name(.) != 'recordDelimiter' and name(.) != 'physicalLineDelimiter' and name(.) != 'fieldDelimiter' ]">
<xsl:message terminate="yes">
<xsl:call-template name="output_message3_fail">
<xsl:with-param name="current_node" select="name(.)"/>
</xsl:call-template>
</xsl:message>
</xsl:template>
<xsl:template name="output_message3_fail">
<xsl:param name="current_node"/>
<xsl:text>
Conversion to EML2.1 failed:
The EML 2.0.1 document has empty string value in some elements which shouldn't be empty string in EML 2.1.0 sepcification - </xsl:text>
<xsl:value-of select="$current_node"/>
</xsl:template>
I use <xsl:message> to generate the error message.

Categories