Ошибка в unmarshalling xml в java-8 "secure-processing 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, и теперь я получаю это исключение при выполнении кода:
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)
Я знаю, что существует question таргетинг на аналогичную проблему, но переход к java 7 для меня не является решением.
Я попытался добавить следующую зависимость maven
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxp-api</artifactId>
<version>1.4</version>
</dependency>
но это не изменило результат, поэтому я удалил его (спасибо @BlaiseDoughan за информацию, что это включено в Java 6)
Любые намеки приветствуются, большое спасибо.
Ответы
Ответ 1
Это была проблема зависимости.
Вот мой способ, как я решил проблему:
- Создайте новый проект maven с этими простыми фрагментами кода, которые я приложил ниже, программа с ошибкой ошиблась, что структура не может быть проанализирована, что нормально.
-
Скопируйте свои зависимости в проект pom.xml, теперь программа должна потерпеть крах (как описано выше)
-
Вы не удаляете зависимости после вашего предпочтительного метода (хорошее угадывание, Bisection, 1-на-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();
}
}
}
и класс 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;
}
}
Кстати: в моем случае это было
<dependency>
<groupId>jcs</groupId>
<artifactId>jcs</artifactId>
<version>1.3</version>
</dependency>
Надеюсь, что это поможет.
Ответ 2
У нас была аналогичная проблема - наш главный разработчик нашел решение, которое работает для нас.
Мы добавили эту зависимость в пару наших файлов pom.xml
Для тех, кто заботится о том, что модульные тесты в Sonar, которые были неудачными, были, по-видимому, неудачными, потому что Cobatura по умолчанию использует старую версию xerces. Версия, которую он втягивает, несовместима с JAX-B в Java 8. Библиотека не используется в производственном коде - просто Cobatura. Поэтому исправление заключалось в том, чтобы добавить тестовую зависимость от более поздней версии xerces (2.11.0). Это делается путем добавления зависимости к файлу pom:
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.11.0</version>
<scope>test</scope>
</dependency>
Ответ 3
Xerces impl является главным виновником здесь. Убери это. Jdk имеет встроенный парсер jaxb, вам это не нужно.
поэтому, если эта зависимость исходит от родительского проекта в случае maven
используйте вкладку исключения, если вы не можете удалить ее напрямую.
<exclusion>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
</exclusion>
Причина, по которой эта проблема так трудно обнаружить, заключается в том, что, когда вы обычно пишете jaxb unmarshalling code
вы сделаете unmarshalling на блоке 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();
}
Здесь xercesImpl заставляет unmarshaller использовать другой синтаксический анализатор (вместо обычного Jaxb-парсера)
заставляя его бросать другое исключение, которое
не будет пойман в нашем блоке catch, который ожидает jaxbexception или один из его подклассов.
Ответ 4
Другим возможным решением для этого является добавление системных переменных:
Я использовал их в плагине 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>
Но вы также можете установить следующее:
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");
Ответ 5
Реализация JAXB была включена в Java SE с версии 6. Если вы удалите зависимость Maven (которая, вероятно, вызывает конфликт версий), все должно работать.
Ответ 6
Ответы Бернарда и Блейза были очень полезными. В моем случае, поскольку я использую 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>
Ответ 7
Использование SAXparser может стать кошмаром. Это наиболее широко используемый синтаксический анализатор XML в java, и каждый из них использует прямо или косвенно. JDK 8 уже доступен JAXB. Поэтому, если вы используете JDK 8, тогда только возможный способ - удалить зависимость maven.
У меня тоже была эта проблема, поэтому я попытался удалить зависимость от maven, но этого не произошло. Тогда я подумал, почему бы не вернуться к более старой версии, если java и VOILLA у меня получился успех. Я использую jdk 7 в настоящее время, и мои тесты проходят гладко. Я думаю, это единственное решение.
Ответ 8
Я решил эту проблему в своем проекте со вторым решением Mitch, но только с
java -Djavax.xml.parsers.SAXParserFactory="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"
Ответ 9
Попробуйте создать 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 );
Ответ 10
Мы также встретили эту проблему и заметили, что вам нужно сохранить версию jdk и jre-версию одинаково, иначе будет существовать несоответствие версии, вызвавшее проблему.
Ребята, которые встречались с проблемой, используют jdk1.6 и jre 1.8, когда они изменились на оба jdk1.6, проблема исчезла.
Ответ 11
Я столкнулся с подобной проблемой, эта проблема возникает, когда есть большая разница в версиях xerces jar и xercesImpl jar. Чтобы решить эту проблему, я использовал xerces-2.9.0 и xercesImpl-2.9.1, и проблема исчезла.