Sunday, September 11, 2011

Introducing Enum Support With Apache Axis2

Now you can find java Enum support with Axis2 1.7.0 version (Not yet released, you can download trunk and build it). It is a new feature to Axis2 as previous versions didn't support a java Enum as a service method parameter. But with this new feature you can use java Enum constants as a service method parameter in your service. Not only in java level it supports wsdl level too. Therefore we can use this new feature in code-first approach as well as in contract-first approach. The following example explains about how to use Enum support in code-first approach and contract-first approach in pojo service.

Deploying a Service which uses Enum in method parameter.

Here is the simple pojo service class. This service class have three methods and two enum classes Day and Status, where Day is a simple enum constant and Status has a user defined constructor which gets an int and a String as its parameters.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
 * @author shameera
 */
public class EnumService {

    public Day testDay(Day day) {
        System.out.println(day.getDeclaringClass());
        System.out.println(day.toString());
        return day;
    }

    public Event callEvent(Event newEvent) {
        Day eventDay = newEvent.getStartingDay();
        System.out.println("Event Starting day is : " + eventDay.toString());
        return newEvent;
    }

    public Status testStatus(Status status) {
        return status;
    }

    public enum Day {
        MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;

    }

    public enum Status {
        START(0, "start"), ACTIVE(1, "active"), STOP(2, "stop");

        private final int val;
        private final String desc;

        Status(int val, String desc) {
            this.val = val;
            this.desc = desc;
        }

        public int value() {
            return this.val;
        }

        public String description() {
            return this.desc;
        }
    }
}
Methods :

1. testDay - get and return Day enum constant.

2. testStatus - get and return Status enum constant.

3. callEvent - get and return Event pojo object which use Day enum constant.

Here is the Event pojo class.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
 * @author shameera
 */
public class Event {

    private EnumService.Day startingDay;
    private String eventDesc ;
    private String eventName;

    public EnumService.Day getStartingDay() {
        return startingDay;
    }

    public void setStartingDay(EnumService.Day startingDay) {
        this.startingDay = startingDay;
    }

    public String getEventDesc() {
        return eventDesc;
    }

    public void setEventDesc(String eventDesc) {
        this.eventDesc = eventDesc;
    }

    public String getEventName() {
        return eventName;
    }

    public void setEventName(String eventName) {
        this.eventName = eventName;
    }
}

Using these two classes and services.xml create .aar file and deploy it in Axis2. After successfully deploy it you can see it in axis2 services page.

You can see generated wsdl of EnumService service by clicking it. Here are some parts of the wsdl file of Enumservice service.
NOTE: make sure that you are using Axis2 1.7.0 if not generated wsdl for this service is not a validated wsdl.

In wsdl file you can see that for the enum constants it has a new schema generated "http://ws.apache.org/namespaces/axis2/enum" as targetNamespace.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
    <xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://ws.apache.org/namespaces/axis2/enum">
    <xs:simpleType name="Status">
        <xs:restriction base="xs:string">
            <xs:enumeration value="START"/>
            <xs:enumeration value="ACTIVE"/>
            <xs:enumeration value="STOP"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="Day">
        <xs:restriction base="xs:string">
            <xs:enumeration value="MONDAY"/>
            <xs:enumeration value="TUESDAY"/>
            <xs:enumeration value="WEDNESDAY"/>
            <xs:enumeration value="THURSDAY"/>
            <xs:enumeration value="FRIDAY"/>
            <xs:enumeration value="SATURDAY"/>
            <xs:enumeration value="SUNDAY"/>
        </xs:restriction>
    </xs:simpleType>
    </xs:schema>

This is the generated schema part for testDay method
1
2
3
4
5
6
7
    <xs:element name="testDay">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="day" nillable="true" type="ax21:Day"/>
        </xs:sequence>
    </xs:complexType>
    </xs:element>

This is the generated schema part for testDayResponse
1
2
3
4
5
6
7
    <xs:element name="testDayResponse">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="return" nillable="true" type="ax21:Day"/>
        </xs:sequence>
    </xs:complexType>
    </xs:element>

Here is the main generated schema for this service
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    <xs:schema xmlns:ax24="http://axis2userguide.axis2.apache.org/xsd" xmlns:ax22="http://ws.apache.org/namespaces/axis2/enum" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://axis2userguide.axis2.apache.org">
    <xs:import namespace="http://ws.apache.org/namespaces/axis2/enum"/>
    <xs:import namespace="http://axis2userguide.axis2.apache.org/xsd"/>
    <xs:element name="testStatus">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" name="status" nillable="true" type="ax21:Status"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="testStatusResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" name="return" nillable="true" type="ax21:Status"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="testDay">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" name="day" nillable="true" type="ax21:Day"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="testDayResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" name="return" nillable="true" type="ax21:Day"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="callEvent">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" name="newEvent" nillable="true" type="ax23:Event"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="callEventResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" name="return" nillable="true" type="ax23:Event"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    </xs:schema>

Here is the generated schema for Event Pojo object.
1
2
3
4
5
6
7
8
9
    <xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://axis2userguide.axis2.apache.org/xsd">
    <xs:complexType name="Event">
        <xs:sequence>
            <xs:element minOccurs="0" name="eventDesc" nillable="true" type="xs:string"/>
            <xs:element minOccurs="0" name="eventName" nillable="true" type="xs:string"/>
            <xs:element minOccurs="0" name="startingDay" nillable="true" type="ax21:Day"/>
        </xs:sequence>
    </xs:complexType>
    </xs:schema>

Enum schema generation process is intelligent enough to generate only one schema type for each enum class.

You can write a schema for Enum support now which means now you can use contract-first approach too.

If you have any problem regarding enum support in Axis2 you can ask it here or Axis2-user mailing list.

8 comments:

  1. Hi Shameera,

    Can you please tell when is Axis2 1.7 release expected? We are planning to make use of Axis2 on web service for existing web service project.

    Goal here is to make the experience seemless to our existing client by using the original WSDL.

    In the existing WSDL we have couple of SimpleType and ComplexType objects. These are resulting in "java.lang.InstantiationException" while generating client requests.

    Is there any way to use Simple and Complex types in Axis 1.6.2? We spent couple of days already porting our web service to Axis2 and this issue came as total shocker.

    Please provide your insights at the earliest. This information is crucial for me to decide whether to go with Axis2 1.6.2 or not.

    Thanks in advance.

    ReplyDelete
    Replies
    1. Actually i cant say exactly when they(devs) will release Axis2 1.7 major release.

      are you using wsdl2java tool to generate the stub? , Axis2 already support simple and complex type objects. BTW according to this issue[1] it is not support when wsdl has ref element with an anonymous complextype. check whether your wsdl file has such a ref elements.

      [1] https://issues.apache.org/jira/browse/AXIS2-5169

      Delete
    2. Any idea how i can work around it??
      I cant for the life me build 1.7 from source.. i have tried.. but failed terribly a million times.
      Could you build a war file and send it to me.. war file of 1.6.2 but with enum support?? i dont know if its asking a lot.. but i am hoping you have already built it :D

      i ran into junit.framework not found found errors.. while import junit.framework worked.. then i ran into running out of memory issues.. so i am wondering if you could help me by releasing a binary war file containing 1.6.2+enum support.. thanks!

      decent post!

      Delete
    3. I think increasing the memory allocation to Maven will solve that memory problem. The Enum issue have been fixed for current trunk, not for 1.6.2. And I haven't tried it with 1.6.2. Yes i already have built it but it is not only current trunk, it has several modifications as i am working on solving some issues and new features. I would like to help you to build trunk if you face any issue after fixing that memory problem.

      You can increase memory adding MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=256m" as an environmental variable.

      Delete
  2. Hi, when i am using java2wsdl in the Axis2 1.7.0-SNAPSHOT build (14-04-2013), the enums are generated correctly, but there is a problem with the created namespace "xmlns:ax28=http://ws.apache.org/namespaces/axis2/enum/xsd". I get the error message:
    "It was detected that 'ax28:PointPosition' is in namespace 'http://ws.apache.org/namespaces/axis2/enum/xsd', but
    components from this namespace are not referenceable from schema document".
    PointPosition is the name of an enum, which is part of another class PointTurn.
    The error message occurs in the line where the namespace is used for xs:element defintion in the PointTurn-Class. I hope my description is not too confusing.
    Any idea? Thanks for the help.

    ReplyDelete
    Replies
    1. It is hard to guess where the issue is? If you can provide a sample to reproduce this error it would help me to identify the issue. By the way It is good if you can open a Axis2 JIRA[1] issue for this i will work on this.

      Cheers,
      Shameera.

      [1] https://issues.apache.org/jira/browse/AXIS2

      Delete
  3. Found the Issue: In the wsdl-schema part that defines the class-type which includes the enum-element, the import statement below the schema definition was missing (this happenens for enum and map types). It was as simple as adding the
    "xs:import namespace="http://ws.apache.org/namespaces/axis2/enum"- Tag, now everything seems fine. Another thing is that I have to rename the namespace to enum1 oder Enum, otherwise the axis2-created serverside bean-classes freak out because of usage of the java reserved word "enum" on multiple places where they do not belong.
    Any news on when axis2 1.7 will see a release? Enum Support would be great, and I'm a little nervous using 1.7-snapshot in a production environment.

    ReplyDelete
    Replies
    1. Sound like a bug , please create a JIRA issue for this, if you have add a small saple to reproduce the issue, That is how we can follow up the problem and provide the fixes which makes users happy.
      About 1.7 release Can't say exact date need to do lot works for this.

      Cheers,
      Shameera.

      Delete

Sample Text

Website counter

Categories