Question

Nous vivons une très difficile de retrouver problème où nous voyons ClassCastExceptions parfois en essayant de itérer sur une liste d'objets unmarshalled. Le bit important est parfois , après un redémarrage du code particulier fonctionne très bien. Cela semble pointer dans la direction de la concurrence / calendrier / condition de course. Je peux confirmer que ni le JAXBContext, ni les placiers et déballeurs sont utilisés en même temps. Nous sommes allés aussi loin que sérialisation leur accès par verrouillage.

Cependant, étant donné que nous courons sur une plate-forme OSGi où les faisceaux individuels s'initialisés de manière asynchrone par Spring DM, il peut être que 2 faisceaux différents créent leur JAXBContext en même temps.

Dans tous les cas, je vous serais reconnaissant de tous les pointeurs vers une explication pour ce qui pourrait causer ces intermittents ClassCastExceptions. Le intermittent est important car ils indiquent que le code lui-même fonctionne normalement bien, mais que certains facteurs externes semble influer sur le comportement.

Voici un exemple précis de l'exception (notez que j'enlevé la compagnie substance spécifique):

Caused by: java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to com.foobar.TunnelType
    at com.foobar.NetMonitorImpl.getVpnStatus(NetMonitorImpl.java:180)

Cette méthode à la ligne 180 est de () construire une boucle sur une collection d'objets TunnelType à l'intérieur d'un objet unmarshalled (ledit unmarshalling fonctionne très bien BTW).

Étant donné que l'objet réel unmarshalling allait bien, est encore physiquement possible pour JAXB de laisser des objets à l'intérieur ElementNSImpl des collections imbriquées?

Environnement d'exécution:

  • JAXB 2.1
  • OSGi
  • Spring DM
  • Le JAXBContext est initialisée avec le ClassLoader du faisceau contenant les classes à rangea / unmarshalled
Était-ce utile?

La solution 3

En désespoir nous avons tourné à synchroniser sur l'objet JAXBContext.class, voyant cela comme la seule possibilité restante pour une condition de course et au moins nous n'avons pas été en mesure de reproduire à nouveau cette question. Voici le code critique:

synchronized (JAXBContext.class) {
    context = JAXBContext.newInstance(packageList, classLoader);
}

Autres conseils

Je reçois cette exception que lorsque j'oublie de dire JAXBContext A propos de ALL à être-types, il pourrait marshalé être affaire.

JAXBContext.newInstance(MyClass1.class,MyClass2.class, [...]);

Aucune des approches suggérées ici l'ont fait pour moi. Cependant, cela résolu mon problème

@XmlAnyElement(lax = true)
public List<Foo> foos;

La clause ci-dessus synchronisée a résolu le problème pour moi aussi, mais il semble que le contexte ne doit pas être une variable locale. Au contraire, il doit être une variable d'instance ou statique. Je n'ai pas pu factoriser mon code que je voudrais, donc à la place je me suis déplacé le contexte dans un initialiseur statique, ce qui est pas parfait, mais semble fonctionner:

 private static Unmarshaller um;

  static{
    try {
      final JAXBContext ctx = JAXBContext.newInstance(ObjectFactory.class.getPackage().getName());
      um = ctx.createUnmarshaller();
    } catch (final JAXBException e) {
      e.printStackTrace();
    }
  }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top