在 java-8“安全处理 org.xml.sax.SAXNotRecognizedException 导致 java.lang.IllegalStateException”中解组 xml 时出错
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25644023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Error unmarshalling xml in java-8 "secure-processing org.xml.sax.SAXNotRecognizedException causing java.lang.IllegalStateException"
提问by mmx73
The following code worked fine in Java 7
以下代码在 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);
....
Now we had to upgrade to Java 8 and now I get this exception when executing the code:
现在我们不得不升级到 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)
I know that there is a questiontargeting a similar problem, but stepping back to java 7 is not a solution for me.
我知道,有一个问题,针对类似的问题,但退一步Java 7的是不是一个解决方案给我。
I tried to add the following maven dependency
我尝试添加以下 maven 依赖项
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxp-api</artifactId>
<version>1.4</version>
</dependency>
but that did not change the result, so I removed it (thanks to @BlaiseDoughan for the information, that this is included in Java 6)
但这并没有改变结果,所以我删除了它(感谢@BlaiseDoughan 提供的信息,它包含在 Java 6 中)
Any hints are welcome, many thanks.
欢迎任何提示,非常感谢。
采纳答案by mmx73
It was a dependency problem.
这是一个依赖问题。
Here is my way how I solved the problem:
这是我解决问题的方法:
- Make a new maven project, with that simple pieces of code, I attached below, the programm crashed normally with an error, that the structure couldn't be parsed which is ok.
Copy your dependencies into the project pom.xml, now the programm should crash (as described above)
no you remove dependencies after your favoured method (good guessing, Bisection , 1-by-1 ..) to find the "bad" dependency. Maybe someone has a better (more professional) method, this one worked for me.
- 制作一个新的maven项目,用我在下面附上的那段简单的代码,程序正常崩溃并出现错误,无法解析结构,这没关系。
将您的依赖项复制到项目 pom.xml 中,现在程序应该崩溃(如上所述)
不,你在你喜欢的方法(很好的猜测,二分法,1-by-1 ..)之后删除依赖项以找到“坏”依赖项。也许有人有更好(更专业)的方法,这个方法对我有用。
now you can descide what to do, maybe a new version is available, in our case it was out own package of a colleage, where he included a package of a colleage, which i could exclude.
现在您可以决定要做什么,也许有新版本可用,在我们的情况下,它是自己的一个学院包,其中他包含了一个学院包,我可以排除它。
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();
}
}
}
and the testXML class
和 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;
}
}
BTW: In my case it was
顺便说一句:就我而言,它是
<dependency>
<groupId>jcs</groupId>
<artifactId>jcs</artifactId>
<version>1.3</version>
</dependency>
Hope that helps.
希望有帮助。
回答by bdoughan
An implementation of JAXB has been included in Java SE since version 6. If you remove the Maven dependency (which is probably causing a version conflict), everything should work.
从版本 6 开始,Java SE 中就包含了 JAXB 的实现。如果您删除 Maven 依赖项(这可能会导致版本冲突),一切都应该可以正常工作。
回答by Naveen Kumar
Using SAXparser can be a nightmare. This is the most widely used XML parser in java and every one have end up using either directly or indirectly. JDK 8 have JAXB already available . So if you are using JDK 8 then only possible way should be removing the maven dependency. I had this issue as well so I tried removing the maven dependency but not happened. Then I thought why not revert to older version if java and VOILLA I got success. I am using jdk 7 currently and my tests run smoothly. I guess this is the only solution.
使用 SAXparser 可能是一场噩梦。这是 java 中使用最广泛的 XML 解析器,每个人都直接或间接使用过。JDK 8 已经提供了 JAXB。因此,如果您使用的是 JDK 8,那么唯一可能的方法应该是删除 maven 依赖项。我也有这个问题,所以我尝试删除 maven 依赖,但没有发生。然后我想,如果 java 和 VOILLA 成功了,为什么不恢复到旧版本。我目前正在使用 jdk 7,我的测试运行顺利。我想这是唯一的解决方案。
回答by Robert H.
We had a similar issue - our head developer found a solution that works for us.
我们遇到了类似的问题 - 我们的首席开发人员找到了适合我们的解决方案。
We added this dependency to a couple of our pom.xml files
我们将此依赖项添加到我们的几个 pom.xml 文件中
For those that care, the unit tests in Sonar that were failing were apparently failing because Cobatura by default pulls in an old version of xerces. The version it pulls in is incompatible with JAX-B in Java 8. The library is not used in production code – just Cobatura. Therefore, the fix was to add a test dependency on a more recent version of xerces (2.11.0). This is done by adding the dependency to the pom file:
对于那些关心的人来说,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>
回答by pimlottc
Both Bernard and Blaise's answers were very helpful. In my case, since I am using JDK 7, the solution was to exclude the xerces subdependency that was being included by one of my dependencies:
伯纳德和布莱斯的回答都非常有帮助。就我而言,由于我使用的是 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>
回答by madhugeeth
Try to create a XML Document and unmarshal it. It was worked for me. JAXBContext jc = JAXBContext.newInstance( Message.class );
尝试创建一个 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 );
回答by shashwatZing
Xerces impl is the main culprit here. Remove it. Jdk has inbuilt jaxb parser, you don't need this.
Xerces impl 是这里的罪魁祸首。去掉它。Jdk 内置了 jaxb 解析器,你不需要这个。
so, if that dependency is coming from a parent project in case of maven use a exclusion tab in case you can't directly remove it.
因此,如果在 maven 的情况下该依赖项来自父项目,请使用排除选项卡,以防您无法直接删除它。
<exclusion>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
</exclusion>
The reason this problem is so hard to detect is because, when you usually write a jaxb unmarshalling code
这个问题如此难以检测的原因是因为,当您通常编写 jaxb 解组代码时
you will do a unmarshalling on a try block and then catch jaxb exception and then do whatever with the error.
您将对 try 块进行解组,然后捕获 jaxb 异常,然后对错误执行任何操作。
But this culprit parser of a jar (xercesimpl) throws a runtime exception in the middle causing error to not get logged and will be only be detected after careful debugging. Look at the code snippet below
但是这个 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();
}
Here xercesImpl causes the unmarshaller to use some other sax parser (instead of the regular jaxb parser) causing it to throw different exception which won't be caught in our catch block which is expecting a jaxbexception or one of its subclasses.
这里 xercesImpl 导致解组器使用其他一些 sax 解析器(而不是常规的 jaxb 解析器),导致它抛出不同的异常,这些异常不会在我们的 catch 块中被捕获,它期待 jaxbeexception 或其子类之一。
回答by Mitch1077487
Another possible solution to this is to add system variables:
另一个可能的解决方案是添加系统变量:
I used these in the maven tomcat plugin which worked for me:
我在对我有用的 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>
But you should also be able to set as follows:
但您也应该能够进行如下设置:
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"
or even use System.setProperty:
甚至使用 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");
回答by James Liu
We also met the issue and noticed that you need to keep the jdk version and jre version the same, otherwise will exist the version mismatch caused the issue.
我们也遇到了这个问题,注意到你需要保持jdk版本和jre版本相同,否则会存在版本不匹配导致的问题。
The guys who met the issue use jdk1.6 and jre 1.8, when changed to both jdk1.6, the issue gone.
遇到这个问题的人用jdk1.6和jre 1.8,换成jdk1.6,问题就解决了。
回答by foxpaps
I resolved this problem on my project with the second Mitch ‘solution but just with
我使用第二个 Mitch 解决方案解决了我的项目中的这个问题,但只是使用
java -Djavax.xml.parsers.SAXParserFactory="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"