web-dev-qa-db-fra.com

Erreur unmarshalling xml dans Java-8 "Exception de traitement sécurisé org.xml.sax.SAXNotRecognizedException provoquant Java.lang.IllegalStateException"

Le code suivant a bien fonctionné sous 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);
....

Nous devions maintenant passer à Java 8 et maintenant, je reçois cette exception lors de l'exécution du code:

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)

Je sais qu'il existe une question ciblant un problème similaire, mais revenir à Java 7 ne constitue pas une solution pour moi.

J'ai essayé d'ajouter la dépendance suivante maven

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

mais cela n'a pas changé le résultat, je l'ai donc enlevé (merci à @BlaiseDoughan pour l'information, cela est inclus dans Java 6)

Tous les indices sont les bienvenus, merci beaucoup.

27
mmx73

C'était un problème de dépendance.

Voici comment j'ai résolu le problème:

  1. Créez un nouveau projet maven, avec ce morceau de code simple, que j'ai joint ci-dessous, le programme s'est écrasé normalement avec une erreur, la structure ne pouvant pas être analysée, ce qui est correct.
  2. Copiez vos dépendances dans le projet pom.xml, le programme devrait maintenant se bloquer (comme décrit ci-dessus)

  3. non, vous supprimez les dépendances après la méthode que vous avez choisie (deviner, Bisection, 1-sur-1 ..) pour trouver la "mauvaise" dépendance. Peut-être que quelqu'un a une meilleure méthode (plus professionnelle), celle-ci a fonctionné pour moi.

maintenant, vous pouvez choisir quoi faire. Une nouvelle version est peut-être disponible. Dans notre cas, il s’agissait du paquet d’un collègue, dans lequel il incluait un paquet d’un collègue que je pouvais exclure.

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();
        }
    }
}

et la classe 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: Dans mon cas, c'était

<dependency>
    <groupId>jcs</groupId>
    <artifactId>jcs</artifactId>
    <version>1.3</version>
</dependency>

J'espère que cela pourra aider.

8
mmx73

Nous avons eu un problème similaire: notre développeur principal a trouvé une solution qui fonctionne pour nous.

Nous avons ajouté cette dépendance à quelques-uns de nos fichiers pom.xml.

Pour ceux que cela intéresse, les tests unitaires de Sonar qui échouaient échouaient apparemment car Cobatura, par défaut, récupère une ancienne version de xerces. La version qu'il extrait est incompatible avec JAX-B en Java 8. La bibliothèque n'est pas utilisée dans le code de production, mais simplement Cobatura. Par conséquent, le correctif consistait à ajouter une dépendance de test sur une version plus récente de xerces (2.11.0). Ceci est fait en ajoutant la dépendance au fichier pom:

<dependency>
    <groupId>xerces</groupId>
    <artifactId>xercesImpl</artifactId>
    <version>2.11.0</version>
    <scope>test</scope>
</dependency>
44
Robert H.

Xerces impl est le principal coupable ici. Enlevez-le. Jdk a un analyseur Jaxb intégré, vous n’avez pas besoin de ça.

ainsi, si cette dépendance provient d'un projet parent dans le cas où maven utilise un onglet d'exclusion si vous ne pouvez pas le supprimer directement.

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

La raison pour laquelle ce problème est si difficile à détecter est due au fait que, lorsque vous écrivez habituellement un code jaxb unmarshalling

vous ferez une inversion du processus sur un bloc try, puis attraperez une exception jaxb et ferez quoi que ce soit avec l'erreur.

Mais cet analyseur syntaxique coupable d'un fichier jar (xercesimpl) lève une exception d'exécution au milieu, causant une erreur qui ne sera pas enregistrée et sera détectée uniquement après un débogage minutieux. Regardez l'extrait de code ci-dessous

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


}

catch (JAXBException e){
e.printStackTrace();

}

Ici xercesImpl force le spectateur à utiliser un autre analyseur de sax (au lieu de l’analyseur jaxb normal) sous-classes.

22
shashwatZing

Une autre solution possible consiste à ajouter des variables système:

Je les ai utilisées dans le plugin Maven Tomcat qui a fonctionné pour moi: 

<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>

Mais vous devriez aussi pouvoir définir ce qui suit:

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"

ou même utilisez 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");
13
Mitch1077487

Les réponses de Bernard et Blaise ont été très utiles. Dans mon cas, étant donné que j'utilise JDK 7, la solution consistait à exclure la sous-dépendance xerces incluse par l'une de mes dépendances:

<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>
5
pimlottc

Une implémentation de JAXB est incluse dans Java SE depuis la version 6. Si vous supprimez la dépendance Maven (ce qui provoque probablement un conflit de version), tout devrait fonctionner.

5
Blaise Doughan

J'ai résolu ce problème sur mon projet avec la deuxième solution de Mitch, mais seulement avec 

Java -Djavax.xml.parsers.SAXParserFactory="com.Sun.org.Apache.xerces.internal.jaxp.SAXParserFactoryImpl"
2
foxpaps

L'utilisation de SAXparser peut être un cauchemar. Il s’agit de l’analyseur XML le plus répandu en Java et tous ont été utilisés directement ou indirectement. JDK 8 dispose déjà de JAXB. Donc, si vous utilisez JDK 8, alors le seul moyen possible devrait être de supprimer la dépendance maven. J'avais ce problème aussi, alors j'ai essayé de supprimer la dépendance Maven, mais cela ne s'est pas produit. Ensuite, j'ai pensé pourquoi ne pas revenir à l'ancienne version si Java et VOILLA me donnaient du succès. J'utilise actuellement jdk 7 et mes tests se déroulent sans heurts. Je suppose que c'est la seule solution.

1
Naveen Kumar

J'avais rencontré un problème similaire, ce problème se produit lorsqu'il existe une grande différence entre les versions de xerces jar et xercesImpl. Pour résoudre ce problème, j'ai utilisé xerces-2.9.0 et xercesImpl-2.9.1 et le problème a disparu.

0
Mahendra Andhale

Essayez de créer un document XML et dissociez-le. Cela a fonctionné pour moi . 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 );
0
madhugeeth

Nous avons également rencontré le problème et constaté que vous deviez conserver la version de jdk et la version de jre identiques. Sinon, le problème de version ne concordera pas.

Les gars qui ont rencontré le problème utilisent jdk1.6 et jre 1.8, quand ils sont passés à la fois jdk1.6, le problème a disparu.

0
James Liu