Enum & # 8220; no tiene un constructor predeterminado sin argumentos & # 8221; con Jaxb y cxf

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

  •  07-07-2019
  •  | 
  •  

Pregunta

Un cliente tiene un problema al ejecutar java2ws en parte de su código, que usa & amp; extiende las clases que se consumen de mis servicios web SOAP. Confundido todavía? :)

Estoy exponiendo un servicio web SOAP (JBoss5, Java 6). Alguien está consumiendo ese servicio web con Axis1 y está creando un frasco con los tipos de datos y los apéndices del cliente. Luego están definiendo su propio tipo, que extiende uno de mis tipos. Mi tipo contiene una enumeración.

class MyParent {
 private MyEnumType myEnum;

 // getters, settters for myEnum;
 }

 class TheirChild extends MyParent {
 ...
 }

Cuando ejecutan java2ws en su código (que extiende mi clase), obtienen

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()

La enumeración que he definido está abajo. Así es como sale después de ser consumido, pero así es como lo tengo definido en el servidor de aplicaciones:


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

He visto cosas en línea y otras publicaciones, como ( this ) con respecto a la incapacidad de Jaxb para manejar Listas o cosas así, pero estoy desconcertado sobre mi enumeración. Estoy bastante seguro de que no puede tener un constructor predeterminado para una enumeración (bueno, al menos un constructor público sin argumentos, Java me grita cuando lo intento), por lo que no estoy seguro de qué hace posible este error. ¿Alguna idea?

Además, el " 2 recuentos de IllegalAnnotationsExceptions " puede ser porque mi código en realidad tiene dos enumeraciones que están escritas de manera similar, pero las dejé fuera de este ejemplo por brevedad.

¿Fue útil?

Solución

El constructor sin argumentos para JAXB no tiene que ser public , puede ser private :

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

MyEnumType(String v) {
    value = v;
}

Sin embargo, no puede mantener el valor miembro final de esta manera.

Otros consejos

Estoy seguro de que puede tener un constructor predeterminado para una enumeración. De hecho, eso es lo que tiene cuando no define explícitamente un constructor (como el tuyo con un parámetro de cadena).

También puede tener varios constructores, uno sin argumentos y otros.


En el ejemplo preciso que da, sería simple evitar el parámetro String por completo. El método nombre () proporcionado tiene exactamente el valor que se le proporciona. El código incluso sería más simple:

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

Si realmente tiene algunos parámetros complejos para establecer en cada valor, y no puede tener constructores específicos debido a una biblioteca, también puede almacenar sus valores variables en un EnumMap y leer esto según sea necesario.

cuando haces de-java-a-wsdl, apache check al principio es enum class o no, y solo si esta verificación falla, busca constructor. Puede verlo en org.apache.axis.wsdl.fromJava.Types :: isBeanCompatible. Cualquier hombre normal, pensará que si escribe

public enum MyEnum{} 

será suficiente. Pero los desarrolladores de Apache no lo creen (IDK, por qué, puede ser por algunas razones de compatibilidad). Hacen este método: org.apache.axis.utils.JavaUtils :: isEnumClassSub.

Si va a descomponer esta clase, verá que su enumeración

  1. DEBE implementar public String getValue () {return name ();}
  2. DEBE implementar MyEnum public fromString (String v) {return valueOf (v);}
  3. NO PUEDE contener public void setValue () {}
  4. DEBE implementar String toString (), pero cada objeto lo implementa.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top