Sunday 13 August 2017

[wsdlc] [ERROR] A class/interface with the same name “com.mydomain.layer.inbound.ws.ValidateResponse” is already in use. Use a class customizat ion to resolve this conflict. ~ foundjava

I got the error [wsdlc] [ERROR] A class/interface with the same name "com.mydomain.layer.inbound.ws.ValidateResponse" is already in use. Use a class customization to resolve this conflict. a few days ago when I tried to generate the Java code from a WSDL file, using Oracle’s wsdlc Ant task. The problem is caused by having two elements with the same name, but with a different namespace, in the WSDL file. For example the following bit of code will result in the error above:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<s:element name="ValidateResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="ValidateResult" type="tns:ValidateResponse" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:complexType name="ValidateResponse">
        <s:complexContent mixed="false">
          <s:extension base="tns:Response">
            <s:sequence>
              <s:element minOccurs="1" maxOccurs="1" name="Status" type="tns:ResponseStatus" />
              <s:element minOccurs="0" maxOccurs="1" name="SubscriptionExpiry" type="s:string" />
              <s:element minOccurs="0" maxOccurs="1" name="Allowed" type="tns:ArrayOfGuid" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
The solution to this is to use a JAXB Customisation Binding, as explained here. By using a JAXB Customisation Binding you can essentially bind a WSDL element to another type and therefore resolve the conflict, since in the generated Java code you end up with two different artifacts.
There are two ways do it. The first one is to use an external JAXB Customisation Binding file. Unfortunately this solution did not work for me. Not sure what the problem was. The second solution is to use inline JAXB Customisation Binding code. Fortunately this solution did work for me. By inlining the JAXB binding you end up with the following bit of code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
      <s:element name="ValidateResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="ValidateResult" type="tns:ValidateResponse" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:complexType name="ValidateResponse">
        <s:annotation>
          <s:appinfo>
            <jaxb:class name="ValidateResponseComplexType"/>
          </s:appinfo>
        </s:annotation>
      <s:complexContent mixed="false">
        <s:extension base="tns:Response">
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="1" name="Status" type="tns:ResponseStatus" />
            <s:element minOccurs="0" maxOccurs="1" name="SubscriptionExpiry" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="Allowed" type="tns:ArrayOfGuid" />
          </s:sequence>
        </s:extension>
      </s:complexContent>
      </s:complexType>
When the wsdlc runs you will end up with the different classes for the ValidateResponse element: ValidateResponse and ValidateResponseComplexType. Of course you will also need to define the jaxb namespace: xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" in the WSDL file.

No comments:

Post a Comment