在java-8中解组xml时出错“安全处理org.xml.sax.SAXNotRecognizedException导致java.lang.IllegalStateException”

以下代码在Java 7中运行良好

import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; String xmlString = '<xml ..... '; StringReader reader = new StringReader(xmlString); JAXBContext jc = JAXBContext.newInstance(MyClass.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); MyClass myClass = (MyClass) unmarshaller.unmarshal(reader); .... 

现在我们不得不升级到Java 8,现在我在执行代码时遇到了这个exception:

 Sep 03, 2014 1:42:47 PM com.sun.xml.internal.bind.v2.util.XmlFactory createParserFactory SCHWERWIEGEND: null org.xml.sax.SAXNotRecognizedException: Feature: http://javax.xml.XMLConstants/feature/secure-processing at org.apache.xerces.jaxp.SAXParserFactoryImpl.setFeature(SAXParserFactoryImpl.java:100) at com.sun.xml.internal.bind.v2.util.XmlFactory.createParserFactory(XmlFactory.java:114) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.getXMLReader(UnmarshallerImpl.java:139) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:214) 

我知道有一个针对类似问题的问题,但回到java 7并不是我的解决方案。

我试图添加以下maven依赖项

  javax.xml jaxp-api 1.4  

但这没有改变结果,所以我删除了它(感谢@BlaiseDoughan提供的信息,这包含在Java 6中)

欢迎任何提示,非常感谢。

我们遇到了类似的问题 – 我们的开发人员找到了一个适合我们的解决方案。

我们将这个依赖项添加到了几个pom.xml文件中

对于那些关心的人来说,在声纳中失败的单位测试显然是失败的,因为Cobatura默认会拉出旧版本的xerces。 它所引入的版本与Java 8中的JAX-B不兼容。该库未用于生产代码 – 只是Cobatura。 因此,修复是在更新版本的xerces(2.11.0)上添加测试依赖项。 这是通过将依赖项添加到pom文件来完成的:

  xerces xercesImpl 2.11.0 test  

Xerces impl是这里的罪魁祸首。 去掉它。 Jdk内置了jaxb解析器,你不需要这个。

因此,如果在maven的情况下该依赖项来自父项目,则使用排除选项卡,以防您无法直接删除它。

  xerces xercesImpl  

这个问题很难被发现的原因是因为,当你经常写一个jaxb解编码时

你将在try块上进行解组,然后捕获jaxbexception,然后对错误做任何事情。

但是这个jar的罪魁祸首解析器(xercesimpl)会在中间抛出一个运行时exception,导致错误无法记录,只有在仔细调试后才能检测到。 请查看下面的代码段

 try { JAXBContext context = JAXBContext.newInstance(YourClass.class); Unmarshaller unmarshaller = context.createUnmarshaller(); YourClass object = (YourClass)unmarshaller.unmarshal(new StringReader("SomeXmlInString")); } catch (JAXBException e){ e.printStackTrace(); } 

这里xercesImpl导致unmarshaller使用其他一些sax解析器(而不是常规的jaxb解析器),导致它抛出不同的exception,这个exception不会在我们的catch块中捕获,它会遇到jaxbexception或它的一个子类。

另一种可能的解决方案是添加系统变量:

我在为我工作的maven tomcat插件中使用了这些:

 com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl com.sun.org.apache.xerces.internal.parsers.SAXParser com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl 

但是你也应该能够设置如下:

 java -Dorg.xml.sax.parser="com.sun.org.apache.xerces.internal.parsers.SAXParser" \ -Djavax.xml.parsers.DocumentBuilderFactory="com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl" \ -Djavax.xml.parsers.SAXParserFactory="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl" 

甚至使用System.setProperty:

 System.setProperty("org.xml.sax.driver", "com.sun.org.apache.xerces.internal.parsers.SAXParser"); System.setProperty("javax.xml.parsers.DocumentBuilderFactory","com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"); System.setProperty("javax.xml.parsers.SAXParserFactory","com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"); 

这是一个依赖性问题。

以下是我解决问题的方法:

  1. 创建一个新的maven项目,使用下面附带的简单代码片段,程序正常崩溃并出现错误,结构无法解析,这是正常的。
  2. 将依赖项复制到项目pom.xml中,现在程序应该崩溃(如上所述)

  3. 不,你删除你喜欢的方法后的依赖关系(好猜测,Bisection,1-by-1 ..)来找到“坏”依赖。 也许某人有一个更好(更专业)的方法,这个方法对我有用。

现在你可以决定做什么了,也许有一个新版本可用,在我们的例子中,它是一个自己的大学包,其中包括一个大学的包,我可以排除。

 public class Test { public Test() { } public static void main(String[] args) { try { StringReader reader = new StringReader(""); JAXBContext jc = JAXBContext.newInstance(TestXML.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); TestXML testXMLs = (TestXML) unmarshaller.unmarshal(reader); } catch (JAXBException e) { e.printStackTrace(); } } } 

和testXML类

 @XmlRootElement(name="rss") @XmlAccessorType(XmlAccessType.FIELD) public class TestXML { public TestXML() { } @XmlElementWrapper(name="channel") @XmlElement(name="item") private int i ; public int getI() { return i; } public void setI(int i) { this.i = i; } } 

顺便说一句:就我而言

  jcs jcs 1.3  

希望有所帮助。

自版本6以来,Java SE中已包含JAXB的实现。如果删除Maven依赖项(可能导致版本冲突),则一切都应该有效。

伯纳德和布莱斯的回答都非常有帮助。 在我的例子中,因为我使用的是JDK 7,所以解决方案是排除我的一个依赖项所包含的xerces子依赖项:

  org.apache.axis axis 1.4.1-SNAPSHOT   xerces xercesImpl   xerces xmlParserAPIs    

使用SAXparser可能是一场噩梦。 这是java中使用最广泛的XML解析器,每个都最终直接或间接使用。 JDK 8已经有了JAXB。 因此,如果您使用的是JDK 8,那么只有可能的方法才能删除maven依赖项。 我也有这个问题,所以我尝试删除maven依赖但没有发生。 然后我想为什么不恢复到旧版本如果java和VOILLA我成功了。 我目前正在使用jdk 7,我的测试运行顺利。 我想这是唯一的解决方案。

我使用第二个Mitch解决方案在我的项目中解决了这个问题,但只是

 java -Djavax.xml.parsers.SAXParserFactory="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl" 

尝试创建XML文档并解组它。 这对我有用。 JAXBContext jc = JAXBContext.newInstance(Message.class);

  InputStream stream = new ByteArrayInputStream( string.getBytes( StandardCharsets.UTF_8 ) ); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse( stream ); Unmarshaller unmarshaller = jc.createUnmarshaller(); Message msg = ( Message ) unmarshaller.unmarshal( doc ); 

我们也遇到了这个问题,并注意到你需要保持jdk版本和jre版本相同,否则会出现版本不匹配导致的问题。

遇到这个问题的人使用jdk1.6和jre 1.8,当改为jdk1.6时,问题就消失了。

我遇到过类似的问题,当xerces jar和xercesImpl jar的版本存在很大差异时会出现这个问题。 为了解决这个问题,我使用了xerces-2.9.0和xercesImpl-2.9.1,问题就消失了。