Enum & # 8220; не имеет конструктора по умолчанию без аргументов & # 8221; с Jaxb и CXF

StackOverflow https://stackoverflow.com/questions/1429509

  •  07-07-2019
  •  | 
  •  

Вопрос

У клиента есть проблема с запуском java2ws для некоторого их кода, который использует & amp; расширяет классы, которые используются моими веб-сервисами SOAP. Смущены еще? :)

Я раскрываю веб-сервис SOAP (JBoss5, Java 6). Кто-то использует этот веб-сервис с Axis1 и создает из него банку с типами данных и клиентскими заглушками. Затем они определяют свой собственный тип, который расширяет один из моих типов. Мой тип содержит перечисление.

class MyParent {
 private MyEnumType myEnum;

 // getters, settters for myEnum;
 }

 class TheirChild extends MyParent {
 ...
 }

Когда они запускают java2ws в своем коде (который расширяет мой класс), они получают

Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
net.foo.bar.MyEnuMType does not have a no-arg default constructor.
    this problem is related to the following location:
            at net.foo.bar.MyEnumType
            at public net.foo.bar.MyEnumType net.foo.bar.MyParent.getMyEnum()

Перечисление, которое я определил ниже. Вот как это получается после потребления, но так я определил его на сервере приложений:


@XmlType(name = "MyEnumType")
@XmlEnum
public enum MyEnumType {

    Val1("Val1"),
    Val2("Val2")

    private final String value;

    MyEnumType(String v) {
        value = v;
    }

    public String value() {
        return value;
    }

    public static MyEnumType fromValue(String v) {
        if (v == null || v.length() == 0) {
            return null;
        }

        if (v.equals("Val1")) {
            return MyEnumType.Val1;
        } 
        if (v.equals("Val2")) {
            return MyEnumType.Val2;
        }  
        return null;
    }
}

Я видел вещи в Интернете и другие сообщения, например ( this ) о неспособности Jaxb обрабатывать списки или тому подобное, но я озадачен своим перечислением. Я почти уверен, что у вас не может быть конструктора по умолчанию для перечисления (ну, по крайней мере, общедоступного конструктора без аргументов, Java кричит на меня, когда я пытаюсь), поэтому я не уверен, что делает эту ошибку возможной. Есть идеи?

Кроме того, " 2 учитывает IllegalAnnotationsExceptions " возможно, потому что мой код на самом деле имеет два перечисления, которые написаны одинаково, но я для краткости оставил их в этом примере.

Это было полезно?

Решение

Конструктор без аргументов для JAXB не обязательно должен быть общедоступным , он может быть приватным :

private String value;
private MyEnumType() {} // for JAXB

MyEnumType(String v) {
    value = v;
}

Вы не можете сохранить value member final таким образом.

Другие советы

Я уверен, что вы можете иметь конструктор по умолчанию для перечисления. На самом деле, это то, что у вас есть, когда вы явно не определяете конструктор (как у вас с параметром String).

Вы также можете иметь несколько конструкторов, один без аргументов и другие.

<Ч>

В приведенном вами точном примере было бы просто вообще избежать параметра String. Предоставленный метод name () имеет именно то значение, которое вы указали. Код был бы даже проще:

    @XmlType(name = "MyEnumType")
    @XmlEnum
    public enum MyEnumType {

    Val1, Val2;

    public String value() {
      return name();
    }

    public static MyEnumType fromValue(String v) {
      for(MyEnumType type : values()) {
        if (type.value().equals(v)) {
          return type;
        }
      }
      return null;
    }
   }
<Ч>

Если у вас действительно есть несколько сложных параметров, которые можно установить для каждого значения, и у вас нет конкретных конструкторов из-за библиотеки, вы также можете сохранить свои переменные значения в EnumMap и читать их по мере необходимости.

когда вы делаете from-java-to-wsdl, сначала проверяется apache, является ли он перечислимым классом или нет, и только в случае неудачной проверки он проверяет конструктор. Вы можете увидеть это в org.apache.axis.wsdl.fromJava.Types :: isBeanCompatible. Любой нормальный мужчина, подумает, что если он напишет

public enum MyEnum{} 

этого будет достаточно. Но разработчики Apache так не считают (IDK почему, возможно, по некоторым причинам совместимости). Они делают этот метод - org.apache.axis.utils.JavaUtils :: isEnumClassSub.

Если вы разложите этот класс, вы увидите, что ваше перечисление

<Ол>
  • НЕОБХОДИМО реализовать public String getValue () {return name ();}
  • ДОЛЖЕН реализовывать общедоступный MyEnum fromString (String v) {return valueOf (v);}
  • НЕ МОЖЕТ содержать публичный void setValue () {}
  • ДОЛЖЕН реализовывать String toString (), но каждый объект реализует его.
  • Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top