2012-05-29 16 views
21

este es mi archivo XML:No puedo entender por qué este JAXB IllegalAnnotationException se lanza

<fields> 
    <field mappedField="Num"> 
    </field> 

    <field mappedField="Type">  
    </field>  
</fields> 

Hice 2 clases para analizarlo (Fields.java y Field.java):

@XmlRootElement(name = "fields") 
public class Fields { 

    @XmlElement(name = "field") 
    List<Field> fields = new ArrayList<Field>(); 
     //getter, setter 
} 

y

public class Field { 

    @XmlAttribute(name = "mappedField") 
    String mappedField; 
    /getter,setter 
} 

Pero obtengo esta excepción.

[INFO] com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions 
[INFO] at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:66) ~[na:1.6.0_07] 
[INFO] at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:422) ~[na:1.6.0_07] 
[INFO] at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:270) ~[na:1.6.0_07] 

No puedo entender por qué esta excepción aumenta. La excepción está aquí:

JAXBContext context = JAXBContext.newInstance(Fields.class); 

Uso JDK 1.6_0.0.7. Gracias.

+1

¿Podría intentar y reemplazar su nombre de atributo? Podría ser que la palabra clave 'campo' en realidad está reservada. – npinti

+0

@MyTitle su código funcionará bien si solo elimina los métodos setter en ambas clases ya que su xml se está ocupando de establecer valores para los atributos. Si dice que necesita los métodos getter y setter en sus clases, agregue la línea "@XmlAccessorType (XmlAccessType.FIELD)" sobre su nombre de clase y después de la anotación "@XmlRootElement" y funciona bien. – mannedear

Respuesta

40

La excepción se debe a su implementación de JAXB (JSR-222) ya que cree que hay dos elementos asignados con el mismo nombre (un campo y una propiedad). Hay un par de opciones para su caso de uso:

OPCIÓN # 1 - Anotar el campo con @XmlAccessorType(XmlAccessType.FIELD)

Si desea Anotación el campo, entonces se debe especificar @XmlAccessorType(XmlAccessType.FIELD)

campos. java:

package forum10795793; 

import java.util.*; 
import javax.xml.bind.annotation.*; 

@XmlRootElement(name = "fields") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Fields { 

    @XmlElement(name = "field") 
    List<Field> fields = new ArrayList<Field>(); 

    public List<Field> getFields() { 
     return fields; 
    } 

    public void setFields(List<Field> fields) { 
     this.fields = fields; 
    } 

} 

Field.java:

package forum10795793; 

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
public class Field { 

    @XmlAttribute(name = "mappedField") 
    String mappedField; 

    public String getMappedField() { 
     return mappedField; 
    } 

    public void setMappedField(String mappedField) { 
     this.mappedField = mappedField; 
    } 

} 

OPCIÓN # 2 - Anotar las propiedades

El tipo de acceso por defecto es XmlAccessType.PUBLIC. Esto significa que, de forma predeterminada, las implementaciones de JAXB asignarán campos y accesos públicos a XML. Con la configuración predeterminada, debe anotar los accesadores públicos en los que desea anular el comportamiento de asignación predeterminado.

Fields.java:

package forum10795793; 

import java.util.*; 
import javax.xml.bind.annotation.*; 

@XmlRootElement(name = "fields") 
public class Fields { 

    List<Field> fields = new ArrayList<Field>(); 

    @XmlElement(name = "field") 
    public List<Field> getFields() { 
     return fields; 
    } 

    public void setFields(List<Field> fields) { 
     this.fields = fields; 
    } 

} 

campo.java:

package forum10795793; 

import javax.xml.bind.annotation.*; 

public class Field { 

    String mappedField; 

    @XmlAttribute(name = "mappedField") 
    public String getMappedField() { 
     return mappedField; 
    } 

    public void setMappedField(String mappedField) { 
     this.mappedField = mappedField; 
    } 

} 

Para más información

+1

tienes razón, gracias) – MyTitle

+0

Esto me ayudó, pero el problema real para mí fue que, aunque el campo estaba anotado correctamente, faltaba la propiedad propOrder que se había definido en el nivel de clase @XmlType annotation. – Pytry

+0

Si hay otras clases en el mismo JAR que no están referenciadas por el código, ¿también tendrán que anotarse? Tengo un servicio JAXB SOAP que ofrece el mismo error y anoté que las clases se devuelven sin éxito, pero hay muchas otras clases en el mismo JAR. –

6

Uno de los siguientes puede causar la excepción:

  1. Añadir un constructor público vacío a su clase de campos, JAXB utiliza reflexión para cargar sus clases, por eso se produce la excepción.
  2. Agregue getter y setter por separado para su lista.
7

Esto se debe a que, por defecto, JAXB cuando serializa un POJO, busca las anotaciones más de los miembros del público (getters o setters) de las propiedades. Pero, estás proporcionando anotaciones en los campos. entonces, cambie y establezca las anotaciones en setters o getters de propiedades, o configure el campo XmlAccessortype.

Opción 1 ::

@XmlRootElement(name = "fields") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Fields { 

     @XmlElement(name = "field") 
     List<Field> fields = new ArrayList<Field>(); 
     //getter, setter 
} 

@XmlAccessorType(XmlAccessType.FIELD) 
public class Field { 

     @XmlAttribute(name = "mappedField") 
     String mappedField; 
     //getter,setter 
} 

Opción 2 ::

@XmlRootElement(name = "fields") 
public class Fields { 

     List<Field> fields = new ArrayList<Field>(); 

     @XmlElement(name = "field") 
     public List<Field> getFields() { 

     } 

     //setter 
} 

@XmlAccessorType(XmlAccessType.FIELD) 
public class Field { 

     String mappedField; 

     @XmlAttribute(name = "mappedField") 
     public String getMappedField() { 

     } 

     //setter 
} 

Para más detalle y profundidad, compruebe la siguiente documentación JDK http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAccessorType.html

18

No puedo entender por qué esta JAXB IllegalAnnotationException se arroja

También recibía la excepción ### counts of IllegalAnnotationExceptions y parecía deberse a una jerarquía de dependencia incorrecta en mi cableado de Spring.

Lo descubrí poniendo un punto de interrupción en el código JAXB cuando lanza el tiro. Para mí esto fue en com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(). Entonces me deshice de la variable list que da algo así como:

[org.mortbay.jetty.Handler is an interface, and JAXB can't handle interfaces. 
this problem is related to the following location: 
    at org.mortbay.jetty.Handler 
    at public org.mortbay.jetty.Handler[] org.mortbay.jetty.handler.HandlerCollection.getHandlers() 
    at org.mortbay.jetty.handler.HandlerCollection 
    at org.mortbay.jetty.handler.ContextHandlerCollection 
    at com.mprew.ec2.commons.server.LocalContextHandlerCollection 
    at private com.mprew.ec2.commons.server.LocalContextHandlerCollection com.mprew.ec2.commons.services.jaxws_asm.SetLocalContextHandlerCollection.arg0 
    at com.mprew.ec2.commons.services.jaxws_asm.SetLocalContextHandlerCollection, 
org.mortbay.jetty.Handler does not have a no-arg default constructor.] 
.... 

El does not have a no-arg default constructor parecía a mí ser engañosa. Tal vez no entendía lo que decía la excepción. Pero sí indicó que había un problema con mi LocalContextHandlerCollection. Eliminé un bucle de dependencia y se borró el error.

Esperamos que esto sea útil para los demás.

+0

¡Gracias! esto es lo único que me ayudó cuando el mismo código arrojaba una 'IllegalAnnotationsException' en diferentes entornos. Resulta que [las versiones de Java/JAXB importaban] (http://stackoverflow.com/questions/19642792/what-might-cause-jaxbelement-does-not-have-a-no-arg-default-constructor). Sin embargo, el "no tiene un constructor predeterminado sin argumentos" fue el problema para mí. ¡Agregar uno lo arregló! – insanity

+2

Tu respuesta resolvió mi problema. No esperaba que un 'constructor predeterminado no-arg' causara el problema. ¡Gracias! –

+1

La pila de información faltaba información clave. Establecer un punto de interrupción encontró el problema. –

1

Una vez recibí este mensaje después de pensar que poner @XmlTransient en un campo que no necesitaba serializar, en una clase que se anotó con @XmlAccessorType(XmlAccessType.NONE).

En ese caso, eliminar XmlTransient resolvió el problema. No soy un experto en JAXB, pero sospecho que debido a que AccessType.NONE indica que no se debe realizar la serialización automática (es decir, los campos deben ser anotados específicamente para serializarlos) hace que XmlTransient sea ilegal ya que su único propósito es excluir un campo del auto -publicación por entregas.

0

Tuve el mismo problema, estaba pasando un grano de primavera hacia atrás como un objeto ResponseBody. Cuando devolví un objeto creado por nuevo, todo estaba bien.

0

que estaba teniendo el mismo problema

mi problema

Caused by: java.security.PrivilegedActionException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions 

Two classes have the same XML type name "{urn:cpq_tns_Kat_getgroupsearch}Kat_getgroupsearch". Use @XmlType.name and @XmlType.namespace to assign different names to them. 
this problem is related to the following location: 
at katrequest.cpq_tns_kat_getgroupsearch.KatGetgroupsearch 
at public javax.xml.bind.JAXBElement katrequest.cpq_tns_kat_getgroupsearch.ObjectFactory.createKatGetgroupsearch(katrequest.cpq_tns_kat_getgroupsearch.KatGetgroupsearch) 
at katrequest.cpq_tns_kat_getgroupsearch.ObjectFactory 
this problem is related to the following location: 
at cpq_tns_kat_getgroupsearch.KatGetgroupsearch 

Two classes have the same XML type name "{urn:cpq_tns_Kat_getgroupsearch}Kat_getgroupsearchResponse0". Use @XmlType.name and @XmlType.namespace to assign different names to them. 
this problem is related to the following location: 
at katrequest.cpq_tns_kat_getgroupsearch.KatGetgroupsearchResponse0 
at public javax.xml.bind.JAXBElement katrequest.cpq_tns_kat_getgroupsearch.ObjectFactory.createKatGetgroupsearchResponse0(katrequest.cpq_tns_kat_getgroupsearch.KatGetgroupsearchResponse0) 
at katrequest.cpq_tns_kat_getgroupsearch.ObjectFactory 
this problem is related to the following location: 
at cpq_tns_kat_getgroupsearch.KatGetgroupsearchResponse0 

cambiado hizo para resolverlo se encuentran por debajo

cambio el nombre correspondiente al espacio de nombres

@XmlAccessorType(XmlAccessType.FIELD) @XmlType(**name** = 
    "Kat_getgroupsearch", propOrder = { 

    @XmlAccessorType(XmlAccessType.FIELD) @XmlType(namespace = 
    "Kat_getgroupsearch", propOrder = { 


@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(**name** = "Kat_getgroupsearchResponse0", propOrder = { 

    @XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(namespace = "Kat_getgroupsearchResponse0", propOrder = { 

¿por qué?

Como está escrito en el registro de errores dos clases tienen el mismo nombre, por lo que deberíamos usar el espacio de nombres porque espacios de nombres XML se utilizan para proporcionar elementos y atributos con nombre único en un documento XML.

0

Todas las opciones a continuación funcionaron para mí.

Opción 1: Anotación de CAMPO en clase & nivel de campo con métodos de captador/

@XmlRootElement(name = "fields") 
@XmlAccessorType(XmlAccessType.FIELD) 
    public class Fields { 

     @XmlElement(name = "field") 
     List<Field> fields = new ArrayList<Field>(); 
      //getter, setter 
    } 

Opción 2: No anotación para CAMPO a nivel de clase (@XmlAccessorType (XmlAccessType.FIELD) y con único método getter . la adición de un método seleccionador lanzará el error, ya que no estamos incluyendo la anotación en este caso Recuerde, no es necesaria la moda cuando se establece explícitamente los valores en el archivo XML

@XmlRootElement(name = "fields") 
    public class Fields { 

     @XmlElement(name = "field") 
     List<Field> fields = new ArrayList<Field>(); 
      //getter 
    } 

Opción 3:.. Anotación al método getter solo. Recuerde que también podemos usar el método setter aquí ya que no estamos haciendo ninguna anotación de nivel FIELD en este caso.

@XmlRootElement(name = "fields") 
    public class Fields { 

     List<Field> fields = new ArrayList<Field>(); 

     @XmlElement(name = "field") 
     //getter 

     //setter 
    } 

Espero que te ayude!

Cuestiones relacionadas