可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
This is my XML file:
<fields>
<field mappedField="Num">
</field>
<field mappedField="Type">
</field>
</fields>
I made 2 classes to parse it (Fields.java and Field.java):
@XmlRootElement(name = "fields")
public class Fields {
@XmlElement(name = "field")
List<Field> fields = new ArrayList<Field>();
//getter, setter
}
and
public class Field {
@XmlAttribute(name = "mappedField")
String mappedField;
/getter,setter
}
But I get this exception.
[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]
I can't understand why this exception rises. Exception is here:
JAXBContext context = JAXBContext.newInstance(Fields.class);
I use JDK 1.6_0.0.7. Thanks.
回答1:
The exception is due to your JAXB (JSR-222) implementation believing that there are two things mapped with the same name (a field and a property). There are a couple of options for your use case:
OPTION #1 - Annotate the Field with @XmlAccessorType(XmlAccessType.FIELD)
If you want to annotation the field then you should specify @XmlAccessorType(XmlAccessType.FIELD)
Fields.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;
}
}
OPTION #2 - Annotate the Properties
The default accessor type is XmlAccessType.PUBLIC
. This means that by default JAXB implementations will map public fields and accessors to XML. Using the default setting you should annotate the public accessors where you want to override the default mapping behaviour.
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;
}
}
Field.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;
}
}
For More Information
- http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
回答2:
I can't understand why this JAXB IllegalAnnotationException is thrown
I also was getting the ### counts of IllegalAnnotationExceptions
exception and it seemed to be due to an improper dependency hierarchy in my Spring wiring.
I figured it out by putting a breakpoint in the JAXB code when it does the throw. For me this was at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check()
. Then I dumped the list
variable which gives something like:
[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.]
....
The does not have a no-arg default constructor
seemed to me to be misleading. Maybe I wasn't understanding what the exception was saying. But it did indicate that there was a problem with my LocalContextHandlerCollection
. I removed a dependency loop and the error cleared.
Hopefully this will be helpful to others.
回答3:
This is because, by default, Jaxb when serializes a pojo, looks for the annotations over the public members(getters or setters) of the properties. But, you are providing annotations on fields. so, either change and set the annotations on setters or getters of properties, or sets the XmlAccessortype to field.
Option 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
}
Option 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
}
For more detail and depth, check the following JDK documentation http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAccessorType.html
回答4:
One of the following may cause the exception:
- Add an empty public constructor to your Fields class, JAXB uses
reflection to load your classes, that's why the exception is thrown.
- Add separate getter and setter for your list.
回答5:
I once received this message after thinking that putting @XmlTransient
on a field I didn't need to serialize, in a class that was annotated with @XmlAccessorType(XmlAccessType.NONE)
.
In that case, removing XmlTransient
resolved the issue. I am not a JAXB expert, but I suspect that because AccessType.NONE indicates that no auto-serialization should be done (i.e. fields must be specifically annotated to serialize them) that makes XmlTransient
illegal since its sole purpose is to exclude a field from auto-serialization.
回答6:
I had this same issue, I was passing a spring bean back as a ResponseBody object. When I handed back an object created by new, all was good.
回答7:
I was having the same issue
My Issue
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
Changed made to solve it are below
I change the respective name to namespace
@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 = {
why?
As written in error log two classes have same name so we should use namespace because XML namespaces are used for providing uniquely named elements and attributes in an XML document.
回答8:
All below options worked for me.
Option 1: Annotation for FIELD at class & field level with getter/setter methods
@XmlRootElement(name = "fields")
@XmlAccessorType(XmlAccessType.FIELD)
public class Fields {
@XmlElement(name = "field")
List<Field> fields = new ArrayList<Field>();
//getter, setter
}
Option 2: No Annotation for FIELD at class level(@XmlAccessorType(XmlAccessType.FIELD) and with only getter method. Adding Setter method will throw the error as we are not including the Annotation in this case. Remember, setter is not required when you explicitly set the values in your XML file.
@XmlRootElement(name = "fields")
public class Fields {
@XmlElement(name = "field")
List<Field> fields = new ArrayList<Field>();
//getter
}
Option 3: Annotation at getter method alone. Remember we can also use the setter method here as we are not doing any FIELD level annotation in this case.
@XmlRootElement(name = "fields")
public class Fields {
List<Field> fields = new ArrayList<Field>();
@XmlElement(name = "field")
//getter
//setter
}
Hope this helps you!