SAXParseException XML-20221文本中的char无效

对于独立的Java应用程序,我们看到非常罕见的错误,其中包含有效XML内容的字符串导致JAXB抛出exception,例如:

javax.xml.bind.UnmarshalException - with linked exception: [org.xml.sax.SAXParseException: : XML-20221: (Fatal Error) Invalid char in text.] 

这是一个非常古老的Java应用程序,它是为旧版本的Java编写的,我们有一个现有的依赖项:

  com.oracle xdb-xmlparser 10.2.0.3.0  

错误代码始终是XML-20221,但原因可能有所不同,例如:

 XML-20221: (Fatal Error) Invalid char in text. XML-20100: (Fatal Error) Expected '?>'.] XML-20121: (Fatal Error) End tag does not match start tag 'TotalDepositReqd'. 

堆栈跟踪的其余部分也会有所不同,但通常看起来像:

 at oracle.xml.parser.v2.XMLError.flushErrorHandler(XMLError.java:415) at oracle.xml.parser.v2.XMLError.flushErrors1(XMLError.java:284) at oracle.xml.parser.v2.NonValidatingParser.parseEndTag(NonValidatingParser.java:1359) at oracle.xml.parser.v2.NonValidatingParser.parseElement(NonValidatingParser.java:1304) at oracle.xml.parser.v2.NonValidatingParser.parseRootElement(NonValidatingParser.java:326) at oracle.xml.parser.v2.NonValidatingParser.parseDocument(NonValidatingParser.java:293) at oracle.xml.parser.v2.XMLParser.parse(XMLParser.java:209) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:211) 

我们的Java版本是:

 java version "1.6.0_16" Java(TM) SE Runtime Environment (build 1.6.0_16-b01) Java HotSpot(TM) Server VM (build 14.2-b01, mixed mode) 

我们当前的命令行是:

 java -server -Xmx2048m -Xms2048m -XX:MaxPermSize=128m -XX:+UseConcMarkSweepGC -Dsun.rmi.dgc.server.gcInterval=0x2932E00 -Dsun.rmi.dgc.client.gcInterval=3600000 -verbosegc -Xloggc:/path/to/file -gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImpl -Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl -Djava.endorsed.dirs=/path/to/endorsed -Duser.country=GB -Duser.language=en -Dhttp.keepAlive=false foo.ListenerServer 

通常情况下,我们会在几秒钟的小突发中看到这些,这告诉我一些内部缓冲区已经损坏了 ? JVM的时间越长,这些exception就越常见。 JVM的反弹解决了这个问题好几天。

  • 还有其他人看过类似的东西吗?
  • 如果是这样,你有没有设法解决这个问题?
  • 也许我们应该转向不同的JAXB / JAXP实现?

当开发人员缓存Unmarshaller实例并在不同线程之间共享它时,我已经看到了类似的问题(解Unmarshaller期间的零星exception)。 根据文档, Unmarshaller不是线程安全的。