1
votes

I am facing an annoying error for a few days now regarding JAX-WS web-services. I intend to generate a web-service with methods that use custom types (basically structures of "JAX-WS primitive" types such as int, long and string) as parameters and return values.

This is the exception I get when trying to publish the web-service:

Exception in thread "main" javax.xml.ws.WebServiceException: class org.econet.ecomanager.msgexchange.webservice.SendMessageReqType do not have a property of the name request at com.sun.xml.ws.server.sei.EndpointArgumentsBuilder$DocLit.(EndpointArgumentsBuilder.java:608) at com.sun.xml.ws.server.sei.TieHandler.createArgumentsBuilder(TieHandler.java:143) at com.sun.xml.ws.server.sei.TieHandler.(TieHandler.java:115) at com.sun.xml.ws.db.DatabindingImpl.(DatabindingImpl.java:112) at com.sun.xml.ws.db.DatabindingProviderImpl.create(DatabindingProviderImpl.java:75) at com.sun.xml.ws.db.DatabindingProviderImpl.create(DatabindingProviderImpl.java:59) at com.sun.xml.ws.db.DatabindingFactoryImpl.createRuntime(DatabindingFactoryImpl.java:128) at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:436) at com.sun.xml.ws.server.EndpointFactory.create(EndpointFactory.java:270) at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:147) at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:574) at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:557) at com.sun.xml.ws.transport.http.server.EndpointImpl.createEndpoint(EndpointImpl.java:321) at com.sun.xml.ws.transport.http.server.EndpointImpl.publish(EndpointImpl.java:245) at com.sun.xml.ws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:134) at javax.xml.ws.Endpoint.publish(Endpoint.java:240) at org.econet.ecomanager.msgexchange.webservice.EcoMsgExchangeSystemsSideWSPublisher.main(EcoMsgExchangeSystemsSideWSPublisher.java:8) Caused by: javax.xml.bind.JAXBException: request is not a valid property on class org.econet.ecomanager.msgexchange.webservice.SendMessageReqType at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getElementPropertyAccessor(JAXBContextImpl.java:985) at com.sun.xml.ws.db.glassfish.JAXBRIContextWrapper.getElementPropertyAccessor(JAXBRIContextWrapper.java:121) at com.sun.xml.ws.server.sei.EndpointArgumentsBuilder$DocLit.(EndpointArgumentsBuilder.java:596) ... 16 more

The web-service interface is:

@WebService(serviceName = "EcoMsgExchangeSystemsSide",
            targetNamespace="http://www.econet-cno.org/ecomsgexchange/ns",
            portName = "EcoMsgExchangeSystemsSidePort")
@BindingType (value = javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING)
public interface EcoMsgExchangeSystemsSide {

    @WebMethod(operationName="sendMessage")
    @RequestWrapper(className="org.econet.ecomanager.msgexchange.webservice.SendMessageReqType")
    @ResponseWrapper(className="org.econet.ecomanager.msgexchange.webservice.SendMessageRespType")
    @WebResult(name="sendMessageResp")
    public SendMessageRespType sendMessage(@WebParam(name="request") SendMessageReqType request);

...

}

The web-service implementation follows:

@WebService(serviceName = "EcoMsgExchangeSystemsSideService",
            portName = "EcoMsgExchangeSystemsSidePort",
            targetNamespace="http://www.econet-cno.org/ecomsgexchange/ns",
            endpointInterface="org.econet.ecomanager.msgexchange.webservice.EcoMsgExchangeSystemsSide")
public class EcoMsgExchangeSystemsSideImpl implements EcoMsgExchangeSystemsSide {

    public SendMessageRespType sendMessage(SendMessageReqType request) {
        long messageId = sendMessage(request.getClientId(), request.getClientPassword(), request.getRecipientId(), 
                request.getFileName()+"."+request.getFileExtension(), request.getFileBytes());
        SendMessageRespType response = new SendMessageRespType();
        if(messageId != -1) {
            response.setMessageId(messageId);
            response.setSenderId(request.getRecipientId());
            response.setFileName(request.getFileName());
            response.setFileExtension(request.getFileExtension());
            return response;
        }
        else
            return null;
    }

...

}

Classes SendMessageReqType and SendMessageRespType are just annotated with @XmlRootElement and have a bunch of atributes (protected) with getters and setters defined.

The problem is in JAXB that cannot interpret the data types in order to convert them to XML structures, but I have not been successful with all the attempts I made so far, trying different annotations. I searched a lot and almost all examples of JAX-WS available use only primitive types, the few ones that use complex types did not help either.

Anyone with an idea of what am I doing wrong?

2

2 Answers

1
votes

By default JAX-WS parameter type is wrapped. So your params are already wrapped with some generated elements, like sendMessage and sendMessageResponse:

<xs:element name="sendMessage" type="tns:sendMessage"/>
<xs:element name="sendMessageResponse" type="tns:sendMessageResponse"/>
<xs:complexType name="sendMessage">
    <xs:sequence>
      <xs:element minOccurs="0" name="request" type="tns:sendMessageReqType"/>
    </xs:sequence>
</xs:complexType>
<xs:complexType name="sendMessageReqType">
    <xs:sequence/>
</xs:complexType>
<xs:complexType name="sendMessageResponse">
    <xs:sequence>
      <xs:element minOccurs="0" name="sendMessageResp" type="tns:sendMessageRespType"/>
    </xs:sequence>
</xs:complexType>
<xs:complexType name="sendMessageRespType">
    <xs:sequence/>
</xs:complexType>

<wsdl:message name="sendMessage">
    <wsdl:part element="tns:sendMessage" name="parameters">
    </wsdl:part>
</wsdl:message>
<wsdl:message name="sendMessageResponse">
    <wsdl:part element="tns:sendMessageResponse" name="parameters">
    </wsdl:part>
</wsdl:message>

If you want to use your own wrapping elements instead of generated ones switch to Bare parameter style by adding @SOAPBinding(parameterStyle=ParameterStyle.BARE) to your SEI (i.e. EcoMsgExchangeSystemsSide) and remove @*Wrapper annotations (they don't make sense in this form). The result will be:

<xs:complexType name="sendMessageReqType">
    <xs:sequence/>
</xs:complexType>
<xs:complexType name="sendMessageRespType">
    <xs:sequence/>
</xs:complexType>
<xs:element name="request" nillable="true" type="sendMessageReqType"/>
<xs:element name="sendMessageResp" nillable="true" type="sendMessageRespType"/>


<wsdl:message name="sendMessage">
    <wsdl:part element="tns:request" name="request">
    </wsdl:part>
</wsdl:message>
<wsdl:message name="sendMessageResponse">
    <wsdl:part element="tns:sendMessageResp" name="sendMessageResp">
    </wsdl:part>
</wsdl:message>
1
votes

I managed to solve the problem. In fact, it was the result from using multiple web service methods/operations with the same name, only changing the parameters bteween them. A Java like programming approach that is not acceptable when dealing with we services. After changing the methods names all worked fine.