I can't understand why this JAXB IllegalAnnota

2019-01-21 22:56发布

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.

8条回答
我想做一个坏孩纸
2楼-- · 2019-01-21 23:32

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楼-- · 2019-01-21 23:32

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.

查看更多
Luminary・发光体
4楼-- · 2019-01-21 23:44

One of the following may cause the exception:

  1. Add an empty public constructor to your Fields class, JAXB uses reflection to load your classes, that's why the exception is thrown.
  2. Add separate getter and setter for your list.
查看更多
ゆ 、 Hurt°
5楼-- · 2019-01-21 23:49

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

查看更多
孤傲高冷的网名
6楼-- · 2019-01-21 23:52

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!

查看更多
聊天终结者
7楼-- · 2019-01-21 23:53

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.

查看更多
登录 后发表回答