Enum "has no default-no-arg constructor" with Jaxb and cxf

The client has a problem running java2ws on some of their code, which uses and extends the classes that are consumed from my SOAP web services. Confused yet? :)

I am browsing a SOAP web service (JBoss5, Java 6). Someone consumes this web service using Axis1 and creates a jar from it with datatypes and client stubs. They then define their own type, which extends one of my types. My type contains an enum.

class MyParent {
 private MyEnumType myEnum;

 // getters, settters for myEnum;
 }

 class TheirChild extends MyParent {
 ...
 }

      

When they run java2ws on their code (which extends my class) they get

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

      

The following are the enumerations that I have defined. This is now how it happens after consumption, but how I defined it in the app server:


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

      

I've seen things on the internet and other posts like ( this one ) about Jaxb's inability to handle lists or something, but I'm puzzled by my ENUM. I'm sure you can't have a default constructor for enum (well, at least a public no-arg constructor, Java yells at me when I try), so I'm not sure what makes this error possible. Any ideas?

Also, the "2 counts of IllegalAnnotationsExceptions" can be caused by the fact that my code actually has two enums that are written in a similar way, but I have left them out of this example for brevity.

+2


source to share


3 answers


The no-arg constructor for JAXB shouldn't be public

, it could be private

:

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

MyEnumType(String v) {
    value = v;
}

      



You cannot save an item value

final

this way.

+9


source


I'm sure you might have a default constructor for an enum. In fact, this is what you have when you don't define a constructor explicitly (like yours with a String parameter).

You can also have multiple constructors, one without-args and others.


In the exact example you give, it would be easy to avoid the String parameter. The name () method provided has exactly the value you specify. The code will be simpler:



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

      


If you do have some complex parameters for each value and cannot have specific constructors due to the library, you can also store your variable values ​​in an EnumMap and read that as needed.

+2


source


when you do from-java-to-wsdl, apache first checks whether it is an enum class or not, and only if this check fails, it checks the constructor. You can see it at org.apache.axis.wsdl.fromJava.Types :: isBeanCompatible. Any normal person would think that if he wrote

public enum MyEnum{} 

      

it would be enough. But Apache developers don't think so (IDK why maybe for some compatibility reasons). They make this method - org.apache.axis.utils.JavaUtils :: isEnumClassSub.

If you expand this class, you will see that your enum

  • MUST implement public String getValue () {return name ();}
  • MUST implement public MyEnum fromString (String v) {return valueOf (v);}
  • CANNOT contain public void setValue () {}
  • MUST implement String toString (), but every object implements it.
0


source







All Articles