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

mmx*_*x73 30 java jaxb xml-parsing java-8

以下代码在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);
....
Run Code Online (Sandbox Code Playgroud)

现在我们不得不升级到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)
Run Code Online (Sandbox Code Playgroud)

我知道,有一个问题,针对类似的问题,但退一步Java 7的是不是一个解决方案给我.

我试图添加以下maven依赖项

<dependency>
    <groupId>javax.xml</groupId>
    <artifactId>jaxp-api</artifactId>
    <version>1.4</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

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

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

小智 47

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

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

对于那些关心的人来说,在声纳中失败的单元测试显然是失败的,因为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>
Run Code Online (Sandbox Code Playgroud)


sha*_*ing 22

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

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

<exclusion>
                 <groupId>xerces</groupId>  
            <artifactId>xercesImpl</artifactId> 
                </exclusion>
Run Code Online (Sandbox Code Playgroud)

这个问题难以检测的原因是因为,当你经常编写一个jaxb解编码时

你将在try块上进行解组,然后捕获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();

}
Run Code Online (Sandbox Code Playgroud)

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

  • 对于未来的访问者:`mvn依赖:tree -Dverbose -Dincludes = xerces`.现在读取树以找出加载它的依赖项. (7认同)

小智 16

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

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

<javax.xml.parsers.DocumentBuilderFactory>com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl</javax.xml.parsers.DocumentBuilderFactory>
<org.xml.sax.parser>com.sun.org.apache.xerces.internal.parsers.SAXParser</org.xml.sax.parser>
<javax.xml.parsers.SAXParserFactory>com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl</javax.xml.parsers.SAXParserFactory>
Run Code Online (Sandbox Code Playgroud)

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

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"
Run Code Online (Sandbox Code Playgroud)

甚至使用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");
Run Code Online (Sandbox Code Playgroud)


mmx*_*x73 8

这是一个依赖性问题.

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

  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("<xml></xml>");
            JAXBContext jc = JAXBContext.newInstance(TestXML.class);
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            TestXML testXMLs = (TestXML) unmarshaller.unmarshal(reader);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

和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;
    }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句:在我看来是这样的

<dependency>
    <groupId>jcs</groupId>
    <artifactId>jcs</artifactId>
    <version>1.3</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.

  • >"也许有人有一个更好(更专业)的方法"这是使用Maven依赖插件,只是寻找Xerces.`org.apache.maven.plugins:Maven的依赖关系的插件:2.10:tree` (2认同)

bdo*_*han 5

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


pim*_*ttc 5

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

<dependency>
  <groupId>org.apache.axis</groupId>
  <artifactId>axis</artifactId>
  <version>1.4.1-SNAPSHOT</version>
  <exclusions>
    <exclusion>
      <groupId>xerces</groupId>
      <artifactId>xercesImpl</artifactId>
    </exclusion>
    <exclusion>
      <groupId>xerces</groupId>
      <artifactId>xmlParserAPIs</artifactId>
    </exclusion>
  </exclusions>
</dependency>
Run Code Online (Sandbox Code Playgroud)