Pergunta

Um cliente está tendo um problema executando java2ws em algum de seu código, que usa e estende as classes que são consumidos de meus serviços web SOAP. Confuso ainda? :)

Eu estou expondo um serviço web SOAP (JBoss5, Java 6). Alguém está a consumir esse serviço web com Axis1 e criando um frasco de fora com os tipos de dados e recibos de cliente. Eles são, então, definir o seu próprio tipo, que se estende um dos meus tipos. Meu tipo contém uma enumeração.

class MyParent {
 private MyEnumType myEnum;

 // getters, settters for myEnum;
 }

 class TheirChild extends MyParent {
 ...
 }

Quando eles estão executando java2ws em seu código (que se estende minha classe), que recebem

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

A enumeração eu defini está abaixo. Este é agora como ele sai depois de ser consumido, mas é como eu tê-lo definido no servidor app:


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

Eu vi coisas on-line e outras mensagens, como ( esta ) sobre a incapacidade do JAXB para Listas punho ou coisas assim, mas estou perplexo sobre o meu enum. Eu tenho certeza que você não pode ter um construtor padrão para uma enumeração (bem, pelo menos um público construtor sem argumento, Java grita comigo quando eu tento), então eu não sei o que faz com que esse erro possível. Alguma idéia?

Além disso, os "2 crimes de IllegalAnnotationsExceptions" pode ser porque o meu código realmente tem duas enumerações que são escritas da mesma forma, mas eu deixei-os fora deste exemplo para brevidade.

Foi útil?

Solução

O construtor sem argumento para JAXB não tem que ser public, pode ser private:

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

MyEnumType(String v) {
    value = v;
}

Você não pode manter o value membro final Desta forma, embora.

Outras dicas

Estou certo de que você pode ter um construtor padrão para uma enumeração. Na verdade, que o que você tem quando você não definir um construtor explicitamente (Como o seu com um parâmetro String).

Você também pode ter vários construtores, um no-args e outros.


No exemplo preciso que você dá, seria simples para evitar o parâmetro da sequência completamente. O método nome fornecido () tem exatamente o valor que são fornecidos. O código seria ainda mais simples:

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

Se você tem realmente alguns parâmetros complexos para definir para cada valor, e não podem ter construtores específicos por causa de uma biblioteca, você também pode armazenar seus valores variando em um EnumMap, e ler este quando necessário.

Quando você faz de-java para WSDL, apache verificação em primeiro lugar é que enum classe ou não, e somente se esta verificação falhar, verificar se há construtor. Você pode vê-lo em org.apache.axis.wsdl.fromJava.Types :: isBeanCompatible. Qualquer homem normal, vai pensar que, se ele escrever

public enum MyEnum{} 

será o suficiente. Mas os desenvolvedores do Apache não pensa assim (IDK por isso, pode ser por algumas razões de compatibilidade). Eles fazem este método -. Org.apache.axis.utils.JavaUtils :: isEnumClassSub

Se você vai decomile esta classe, você vai ver, que a sua enumeração

  1. deve implementar public String getValue () {nome return ();}
  2. deve implementar pública MyEnum fromString (String v) {return valueOf (v);}
  3. não pode conter setValue public void () {}
  4. deve implementar Cordas toString (), mas cada objeto implementá-lo.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top