Enum & # 8220; не имеет конструктора по умолчанию без аргументов & # 8221; с Jaxb и CXF
Вопрос
У клиента есть проблема с запуском 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.
Если вы разложите этот класс, вы увидите, что ваше перечисление
<Ол>