No adapter for endpoint; Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?
Asked Answered
E

13

33

I am struggling with an Spring-WS with JMS example. I set the Spring-WS and JMS wiring as per the Spring recommendations. But I kept getting following error. I dont know how to bypass this issue, any help will be highly appreciated:

[org.springframework.ws.soap.server.endpoint.SoapFaultAnnotationExceptionResolver] - 
Resolving exception from endpoint 
[org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint@1c8b0b1]: 
java.lang.IllegalStateException: No adapter for endpoint 
[org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint@1c8b0b1]: 
Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?

[org.springframework.ws.soap.server.endpoint.SimpleSoapExceptionResolver] - Resolving exception from endpoint
[org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint@1c8b0b1]: 
java.lang.IllegalStateException: No adapter for endpoint [org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint@1c8b0b1]: 
Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?

[org.springframework.ws.soap.server.SoapMessageDispatcher] - 
Endpoint invocation resulted in exception - responding with Fault
java.lang.IllegalStateException: No adapter for endpoint  [org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint@1c8b0b1]: 
Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?

My Web Service Wiring is

<bean id="imageRepository"
    class="org.springframework.ws.samples.mtom.service.StubImageRepository" />

<!-- JMS WIRING TO WS START -->
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />

<bean id="messageDispatcher"
    class="org.springframework.ws.soap.server.SoapMessageDispatcher">
    <property name="endpointMappings">
        <bean
            class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
            <property name="defaultEndpoint">
                <bean
                    class="org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint">
                    <constructor-arg ref="imageRepository" />
                </bean>
            </property>
        </bean>
    </property>
</bean>

<bean
    class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="jmsConnectionFactory" />
    <property name="destinationName" value="WS.JMS.EXAMPLE.V1.IMAGE.REPO.REQUEST" />
    <property name="messageListener">
        <bean
            class="org.springframework.ws.transport.jms.WebServiceMessageListener">
            <property name="messageFactory" ref="messageFactory" />
            <property name="messageReceiver" ref="messageDispatcher" />
        </bean>
    </property>
</bean>

My End point code is

@PayloadRoot(localPart = "StoreImageRequest", namespace = "http://www.springframework.org/spring-ws/samples/mtom")
@ResponsePayload
public String  store(@RequestPayload JAXBElement<Image> requestElement) throws IOException {
    Image request = requestElement.getValue();
    return imageRepository.storeImage(request.getName());
}

My Schema is

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.springframework.org/spring-ws/samples/mtom"
    xmlns:tns="http://www.springframework.org/spring-ws/samples/mtom"
    xmlns:xmime="http://www.w3.org/2005/05/xmlmime" elementFormDefault="qualified">
    <element name="StoreImageRequest" type="tns:Image"/>
    <element name="LoadImageRequest" type="string"/>
    <element name="LoadImageResponse" type="tns:Image"/>
    <complexType name="Image">
        <sequence>
            <element name="name" type="string"/>
        </sequence>
    </complexType>
</schema>

My Client Request is

<ns2:StoreImageRequest xmlns:ns2="http://www.springframework.org/spring-ws/samples/mtom"><ns2:name>spring-ws-logo.png</ns2:name></ns2:StoreImageRequest>

Can some one help?

Elate answered 18/1, 2013 at 0:13 Comment(0)
G
87

I had a similar error message. My problem was in request and response class that I generated from XSD. It missed @XMLRootElement annotation. This caused that description of operation (in WSDL) and description of implemented method (in Endpoint) did not match. Adding JAXBElement to my endpoint method solved my problem.

import javax.xml.bind.JAXBElement;

@PayloadRoot(namespace = "http://foo.bar/books", localPart = "GetBook")
@ResponsePayload
public JAXBElement<MyReponse> getBook(@RequestPayload JAXBElement<MyRequest> myRequest) {
    ...

See this blog for more details: spring-ws: No adapter for endpoint

Graze answered 6/3, 2014 at 14:54 Comment(7)
Thanks. This might not be the OP's issue, but it was mine.Scissure
Worked for me too. Here's example of my code: code @PayloadRoot(namespace = NAMESPACE_URI, localPart = "ServiceCheckRequest") @ResponsePayload public JAXBElement<ServiceCheckResponseType> serviceCheckRequest( @RequestPayload ServiceCheckRequestType request) { ServiceCheckResponseType response = new ServiceCheckResponseType(); response.setSystem("Testing system"); QName qname = new QName("ServiceCheckRequest"); JAXBElement<ServiceCheckResponseType> jaxbElement = new JAXBElement<ServiceCheckResponseType>( qname, ServiceCheckResponseType.class, response); return jaxbElement; }Meng
I don't see what @XMLRootElement has to do with the solution. I also found that wrapping my response with JAXBElement helped, but that doesn't seem like something I should have to do in a simple framework like Spring.Finned
Thanks, adding the @XMLRootElement to the JaxB Class generated from XSD worked for me.Moreen
Thanks a million, wrapping response in JAXBElement solved it for me. My example: QName qname = new QName("ResponseElement"); JAXBElement<ResponseElement> jaxbElement = new JAXBElement<>(qname, ResponseElement.class, response);One
Wrapping the response in the JAXBELement solved it as well for me!Teflon
With newer Java and the change in namespace for Jakarta from javax->jakarta can be an issue. I have the XmlRootElement specified, but it's the jakarta.xml.bind.annotation namespace not the javax.xml.bind.annotation namespace. I'm in kind of a catch 22 situation with this oneTrapeziform
V
8

I was using WSDL file and did as below, then it worked.

  @PayloadRoot(namespace = "http://www.myservice/v1.0/query", localPart = "queryRequest")
  @ResponsePayload
  public JAXBElement<QueryResponse> queryAddrLocation(@RequestPayload JAXBElement<QueryRequest> queryRequest) {
    System.out.println("Welcome to " + queryRequest);
    return createJaxbElement(new QueryResponse(), QueryResponse.class);
  }

  private <T> JAXBElement<T> createJaxbElement(T object, Class<T> clazz) {
    return new JAXBElement<>(new QName(clazz.getSimpleName()), clazz, object);
  }
Varney answered 21/3, 2019 at 2:12 Comment(4)
This doesn't even compile.Athanasius
@VladDinulescu you have to add lib for JAXBElment, and create 2 objects: QueryRequest & QueryResponse. Complie will be fine after this. The code I copy from my sample which worked for me already :)Varney
If you return a QueryResponse and the method's return type is JAXBElement<QueryResponse>, no, it won't compile.Athanasius
Updated the return as JAXBElement<QueryResponse>. Thanks @VladDinulescuVarney
J
3

I had a similar error. the problem is that the request and response generated from XSD/WSDL missed the @XMLRootElement annotation. By adding JAXBElement to the endpoint solved the problem.

private static final String NAMESPACE_URI = "<targetNamespace>";

@Autowired
Service   service;

@PayloadRoot ( namespace = Endpoint.NAMESPACE_URI, localPart = "name" )
@ResponsePayload
public JAXBElement < Response > Create ( @RequestPayload JAXBElement < Request> request ) throws Exception
{
ObjectFactory factory = new ObjectFactory ( );
Response response = new Response ( );
Request req = request.getValue ( );

response  = this.service.call( req);

return factory.createResponse ( response );
}
Jeth answered 27/11, 2019 at 13:24 Comment(2)
I have done that but gave me another error: "Implementation of JAXB-API has not been found on module path or classpath."Bacchant
@VincentGuyard to fix that you need to do this: https://mcmap.net/q/156731/-javax-xml-bind-jaxbexception-implementation-of-jaxb-api-has-not-been-found-on-module-path-or-classpathCarmancarmarthen
M
1

I'm not sure how your complete Endpoint looks, but the class should be annotated with @Endpoint or it should implement MessageHandler or PayloadEndpoint.

On other thing you can play with is the method signature. Spring-WS' endpoint mapping is pretty intelligent: it tries to map input and output classes from your method signature with the WSDL file. Are you sure a String is the @ResponsePayLoad, not a StoreImageResponse?

For example, here's the method signature of one of my endpoint

@PayloadRoot(
    localPart = "GetHiredCandidatesRequest", 
    namespace = DEFAULT_NAMESPACE
)
@ResponsePayload
public GetHiredCandidatesResponse getCandidates (
    @RequestPayload GetHiredCandidatesRequest getCandidate,
    MessageContext messageContext) {
    ...
}

Which is defined in my WSDL like this:

<wsdl:operation name="GetHiredCandidates">
    <wsdl:input message="tns:GetHiredCandidatesRequest" name="GetHiredCandidatesRequest"></wsdl:input>
    <wsdl:output message="tns:GetHiredCandidatesResponse" name="GetHiredCandidatesResponse"></wsdl:output>
</wsdl:operation>

Do you see how it's mapped? Perhaps you're missing something like that in your signature.

Mountain answered 23/1, 2013 at 9:55 Comment(0)
B
1

This method works when called from SOAPUI:

@PayloadRoot(namespace = NAMESPACE_URI, localPart = "getOrderDetail")
public @ResponsePayload JAXBElement<OrderDetailResponse> getOrderDetail(@RequestPayload JAXBElement<String> customerId, @RequestPayload JAXBElement<String> promoCode)

In the method below, the values inside the customerStatusRequest are coming in null even though from SOAPUI I am populating them.

@PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCustomerStatus")
public @ResponsePayload
JAXBElement<CustomerStatusResponse> getCustomerStatus(@RequestPayload JAXBElement<CustomerStatusRequest> customerStatusRequest)

(CustomerStatusRequest implements Serializable)

It appears String parameter values are making it through the call. But not a custom class. I annotated the CustomerStatusRequest class in this manner:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CustomerStatusRequest", propOrder = {
    "customerId",
    "gender",
    "dob",
    "lastName",
    "sourceSystemId"
},namespace="http://www.mycompany.com/webservices")

and also each field in the CustomerStatusRequest this way:

@XmlElement(name = "customerId", required = true, nillable = true)

The method is called but the values for customerId, etc... are still coming in as null. Are additional annotations needed for a custom class?

--Thanks

Borgia answered 18/10, 2019 at 14:24 Comment(0)
R
1

What creating a problem for me is imports :

old imports are from javax

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

changed imports are from jakarta:

import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlType;

just by replacing the javax to jakarta it worked for me...

Rutter answered 6/6, 2023 at 5:10 Comment(0)
C
1

In my case, using jakarta.xml.bind.JAXBElement in place of javax.xml.bind.JAXBElement for both @ResponsePayload and @RequestPayload worked.

Cosme answered 26/6, 2023 at 17:32 Comment(0)
L
0

First, as per the guidelines, there should be an Endpoint class

@Endpoint
public class EmpEndpoint {

    @Autowired
    private EmpService empService;

    //This is like @RequestMapping of Spring MVC    
    @PayloadRoot(localPart = "EmpServiceRequest", namespace = "http://www.example.org/")
    @ResponsePayload
    public EmpServiceResponse getemployeeDetails(@RequestPayload EmpServiceRequest request) {
        EmpServiceResponse response = new ObjectFactory().createEmpServiceResponse();
        List<Employee> l = empService.getemployeeDetails(request.getName());
        response.setName(l.get(0).getName());
        response.setEmail(l.get(0).getEmail());
        return response;
    }
}

And one Service and its implementation class which will have PayloadRoot and other Annotations (Request and Response)

And place this in your spring-servlet.xml

  <!-- To detect @Endpoint -->
<sws:annotation-driven/>

<!-- To detect @Service, @Component etc -->
<context:component-scan base-package="your package for eg com.employee" />
Lancet answered 14/2, 2013 at 10:12 Comment(0)
I
0

Same problem but in my case was because I forgot to place the annotations @ResponsePayload and @RequestPayload in the handler function. Just check it! It's probably all it's needed.

Interrelation answered 12/4, 2017 at 18:51 Comment(0)
S
0

I had the same error, but only running my Spring Web Service integration tests.

The problem was that I setup the Jaxb2Marshaller with a different configuration if compared with Jaxb2Marshaller inside the test. I was not using the same Bean for the application and test.

My Jaxb2Marshaller with the application running is:

private Jaxb2Marshaller marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setContextPath("com.company.application");
    marshaller.setMtomEnabled(true);
    return marshaller;
}

But on my tests, I was using:

@Before
public void init() throws Exception {
    marshaller.setPackagesToScan(ClassUtils.getPackageName(Order.class));
    marshaller.afterPropertiesSet();
}

To make the test work, I just defined the two missing properties:

@Before
public void init() throws Exception {
    marshaller.setPackagesToScan(ClassUtils.getPackageName(Order.class));
    marshaller.afterPropertiesSet();
    marshaller.setContextPath("com.company.application");
    marshaller.setMtomEnabled(true);
}
Shanklin answered 5/6, 2019 at 21:3 Comment(0)
C
0

I added property in beanXml file

And it is work.

<bean id="marshaller"
    class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
     <property name="supportJaxbElementClass" value = "true"/>
    <property name="contextPaths">
        <list>
            <value>com.xxx</value>
        </list>
    </property>
    <property name="schemas">
        <list>
            <value>classpath:/xsd/service.xsd</value>
        </list>
    </property>
</bean>
Catechin answered 23/5, 2021 at 0:0 Comment(0)
R
0

I was also facing the same issue. Attaching the wsdl that is working fine for me.

<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://services.reactivestax.io/" name="UberPortType" targetNamespace="http://services.reactivestax.io/">
    <wsdl:types>
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://services.reactivestax.io/" elementFormDefault="unqualified" targetNamespace="http://services.reactivestax.io/" version="1.0">
            <xs:element name="updateRequest">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="id" type="xs:long"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>

            <xs:element name="updateResponse">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="result" type="tns:orders"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>


            <xs:complexType name="orders">
                <xs:sequence>
                    <xs:element minOccurs="0" name="customerId" type="xs:long"/>
                    <xs:element minOccurs="0" name="driverId" type="xs:long"/>
                    <xs:element minOccurs="0" name="orderId" type="xs:long"/>
                    <xs:element maxOccurs="unbounded" minOccurs="0" name="orderList" nillable="true" type="tns:orderDish"/>
                    <xs:element minOccurs="0" name="orderPrice" type="xs:double"/>
                    <xs:element minOccurs="0" name="orderStatus" type="tns:orderStatus"/>
                    <xs:element minOccurs="0" name="paymentStatus" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
            <xs:complexType name="orderDish">
                <xs:sequence>
                    <xs:element minOccurs="0" name="customerId" type="xs:long"/>
                    <xs:element minOccurs="0" name="dishId" type="xs:long"/>
                    <xs:element minOccurs="0" name="dishPrice" type="xs:double"/>
                    <xs:element minOccurs="0" name="id" type="xs:long"/>
                </xs:sequence>
            </xs:complexType>
            <xs:simpleType name="orderStatus">
                <xs:restriction base="xs:string">
                    <xs:enumeration value="ORDER_STARTED"/>
                    <xs:enumeration value="ORDER_ACCEPTED"/>
                    <xs:enumeration value="ORDER_READY"/>
                    <xs:enumeration value="ORDER_PICKED"/>
                    <xs:enumeration value="ORDER_DELIVERED"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="updateStatusResponse">
        <wsdl:part element="ns1:updateResponse" name="parameters"> </wsdl:part>
    </wsdl:message>
    <wsdl:message name="updateStatus">
        <wsdl:part element="ns1:updateRequest" name="parameters"> </wsdl:part>
    </wsdl:message>
    <wsdl:portType name="UberPortType">
        <wsdl:operation name="updateStatus">
            <wsdl:input message="ns1:updateStatus" name="updateStatus"> </wsdl:input>
            <wsdl:output message="ns1:updateStatusResponse" name="updateStatusResponse"> </wsdl:output>
        </wsdl:operation>
    </wsdl:portType>

    <wsdl:binding name="OrderStatusUpdateServiceSoapBinding" type="ns1:UberPortType">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="updateStatus">
            <soap:operation soapAction="urn:updateStatus" style="document"/>
            <wsdl:input name="updateStatus">
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output name="updateStatusResponse">
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="OrderStatusUpdateService">
        <wsdl:port binding="tns:OrderStatusUpdateServiceSoapBinding" name="OrderStatusUpdatePort">
            <soap:address location="http://localhost:8091/service/uber-springws"/>
        </wsdl:port>
    </wsdl:service>


</wsdl:definitions>
Refer answered 15/4, 2022 at 0:4 Comment(0)
E
0

We had the same problem.
We had the wrong soapheader import. We had:

import org.springframework.ws.soap.server.endpoint.annotation.SoapHeader;

But it should be:

import org.springframework.ws.soap.SoapHeader;

It's a good idea to check all the imports.

Ecumenicist answered 22/4 at 13:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.