在 java-8 中取消分组 xml 的错误 “secure-processing org.xml.sax.SAXNotRecognizedException 导致 java.lang.IllegalStateException”

2022-09-01 09:08:58

以下代码在 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,现在我在执行代码时得到这个异常:

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对我来说不是一个解决方案。

我试图添加以下专家依赖关系

<dependency>
    <groupId>javax.xml</groupId>
    <artifactId>jaxp-api</artifactId>
    <version>1.4</version>
</dependency>

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

任何提示都是受欢迎的,非常感谢。


答案 1

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

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

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

<dependency>
    <groupId>xerces</groupId>
    <artifactId>xercesImpl</artifactId>
    <version>2.11.0</version>
    <scope>test</scope>
</dependency>

答案 2

Xerces impl是这里的主要罪魁祸首。删除它。Jdk有内置的jaxb解析器,你不需要这个。

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

<exclusion>
                 <groupId>xerces</groupId>  
            <artifactId>xercesImpl</artifactId> 
                </exclusion>

这个问题之所以如此难以检测,是因为,当你通常编写一个jaxb解编组代码时。

您将在尝试块上执行取消分组,然后捕获jaxb异常,然后对错误执行任何操作。

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

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解析器),导致它抛出不同的异常,这些异常不会被捕获在我们的捕获块中,该块期望jaxbexception或其子类之一。


推荐