Подтвердить что ты не робот

Я не могу понять, почему это исключение JAXB IllegalAnnotationException

Это мой XML файл:

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

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

Я сделал 2 класса для его анализа (Fields.java и Field.java):

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

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

и

public class Field {

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

Но я получаю это исключение.

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

Я не понимаю, почему это исключение возрастает. Исключение:

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

Я использую JDK 1.6_0.0.7. Спасибо.

4b9b3361

Ответ 1

Исключение связано с вашей реализацией JAXB (JSR-222), полагая, что есть две вещи, сопоставленные с тем же именем (поле и свойство). Для вашего варианта использования есть несколько вариантов:

ВАРИАНТ № 1 - аннотировать поле с помощью @XmlAccessorType(XmlAccessType.FIELD)

Если вы хотите аннотировать поле, тогда вы должны указать @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;
    }

}

ВАРИАНТ № 2 - аннотировать свойства

Тип доступа по умолчанию - XmlAccessType.PUBLIC. Это означает, что по умолчанию реализации JAXB будут отображать общедоступные поля и аксессоры в XML. Используя настройку по умолчанию, вы должны аннотировать общедоступные аксессоры, где вы хотите переопределить поведение отображения по умолчанию.

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

}

Дополнительная информация

Ответ 2

Для потомков ни один из этих ответов не помог мне с моей проблемой. Я получал исключение ### counts of IllegalAnnotationExceptions и, похоже, из-за неправильной иерархии зависимостей в моей проводке Spring.

Я понял это, поставив точку останова в коде JAXB, когда он делает бросок. Для меня это было в com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(). Затем я сбросил переменную list, которая дает что-то вроде:

[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.]
....

Мне показалось, что does not have a no-arg default constructor вводит в заблуждение. Возможно, я не понял этого.

Но это означало, что была проблема с моим LocalContextHandlerCollection. Я удалил цикл зависимостей, и ошибка была удалена.

Надеюсь, это будет полезно для других.

Ответ 3

Это связано с тем, что по умолчанию Jaxb при сериализации pojo ищет аннотации к публичным членам (getters или seters) свойств. Но вы предоставляете аннотации по полям. поэтому либо измените, либо установите аннотации на сеттеры или геттеры свойств, либо задайте поле XmlAccessortype в поле.

Вариант 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
}

Вариант 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
}

Для более подробной информации и глубины проверьте следующую документацию JDK http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAccessorType.html

Ответ 4

Одно из следующего может вызвать исключение:

  • Добавить пустой публичный конструктор в ваш класс Fields, JAXB использует отражение для загрузки ваших классов, поэтому исключение выбрано.
  • Добавьте отдельный тэгстер и сеттер для вашего списка.

Ответ 5

Я получил это сообщение после того, как подумал, что положить @XmlTransient в поле, которое мне не нужно сериализовать, в классе, который был аннотирован с помощью @XmlAccessorType(XmlAccessType.NONE).

В этом случае удаление XmlTransient разрешило проблему. Я не эксперт JAXB, но я подозреваю, что поскольку AccessType.NONE указывает, что автоматическая сериализация не должна выполняться (например, поля должны быть специально аннотированы для их сериализации), что делает XmlTransient незаконным, поскольку единственная его цель - исключить поле от автоматической сериализации.

Ответ 6

У меня была эта же проблема, я передавал spring bean обратно как объект ResponseBody. Когда я вернул объект, созданный новым, все было хорошо.

Ответ 7

У меня была такая же проблема

Мой вопрос

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

Измененный для его решения ниже

Я изменяю соответствующее имя на пространство имен

@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 = {

почему?

Как указано в журнале ошибок, два класса имеют одинаковое имя, поэтому мы должны использовать пространство имен, потому что пространства имен XML используются для предоставления уникально названных элементов и атрибутов в документе XML.

Ответ 8

Все приведенные ниже параметры работали для меня.

Вариант 1: аннотация для FIELD на уровне класса и поля с использованием методов getter/setter

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

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

Вариант 2: No Annotation для FIELD на уровне класса (@XmlAccessorType (XmlAccessType.FIELD) и только с помощью метода getter. Добавление метода Setter будет вызывать ошибку, поскольку в этом случае мы не включаем аннотацию. требуется, если вы явно задаете значения в своем XML файле.

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

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

Вариант 3: аннотация по методу геттера. Помните, что мы также можем использовать метод setter, поскольку в этом случае мы не делаем аннотации уровня FIELD.

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

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

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

        //setter
    }

Надеюсь, это поможет вам!