Wednesday, September 29, 2010

Building a web service with Spring-WS

[WCF client for a Spring Webservice: An interoperabilty story. Part 2.]

     There is an abundance of web service frameworks in Java. Apache Axis(1&2), Apache CXF, XFire, Metro (from the Java family itself),.. the list goes on. All are rich in features. It is not an easy job to select the right one always.

    Our selection of Spring Web Services(Spring-WS) was based on few compelling reasons.
  • First and foremost reason was its coverage. Spring covers almost all areas of Web Service specifications, utilizing the existing libraries wherever they are strong. Spring allows you to plug in the best libraries available for each specific need. For example, we can choose between SAAJ(SOAP with Attachments API) and Axis 2's AXIOM for the concrete implementations of SOAP Message Factories, to create the SOAP Messages.
  • It supports most of the XML APIs for handling the incoming XML messages, ranging from JAXP APIs such as DOM, SAX, and StAX, but also JDOM, dom4j, XOM, or even marshalling technologies. XML marshalling technologies include JAXB 1 and 2, Castor, XMLBeans, JiBX, and XStream.
  • The highly configurable WS-Security implementation of Spring-WS allows you to sign SOAP messages, encrypt and decrypt them, or authenticate against them.     Primarily WSS4J is used, while you can leverage your existing Acegi based Spring-Security as well.
  • Moreover, we were already quiet comfortable with the Spring style of application development. Our Spring expertise enabled us to jump start into the implementation. (For those who are new to Spring Framework, I highly recommend to dive into it, you will soon start enjoying your programming because of this wonderful framework).

    For the purpose of illustrating the construction process of web services, let us use a simple business scenario of a fictitious restaurant, Live Restaurant , that needs to accept online orders from customers.

    Live Restaurant decides to publish its OrderService component as a web-service. For simplicity, just two operations are considered for the OrderService(Java Interface).
  1. placeOrder
  2. cancelOrder
 
 Figure 2.1. OrderService Java Interface


    Now we need to publish OrderService as a web service. Let us examine how we will accomplish it.

    When building web services, generally there are two different approaches considered – Contract First(WSDL/XSD first) and Contract Last(Java first). Spring recommends and only supports the Contract First approach. The Spring team describes the reasons for that decision in this link. http://static.springsource.org/spring-ws/sites/1.5/reference/html/why-contract-first.html.

    So, in our implementation, we start with an XML Schema(XSD), as our contract. Spring, with its magical components generates rest of the artifacts to form the complete WSDL.

    Now let us look at the steps involved in building the service.

    Let us use our favorite Eclipse IDE for Java EE Developers. Additionally, you will need the JAXB plugin for Eclipse. We will use the Apache Tomcat Server 6 for deploying the service.

Now let us follow these steps.
  1. Add the JAXB Plugin for Eclipse.
    1. Download the JAXB Eclipse plugin from
      https://jaxb-workshop.dev.java.net/plugins/eclipse/xjc-plugin.html%20

      OR

      https://jaxb-workshop.dev.java.net/servlets/ProjectDocumentList?folderID=4962&expandFolder=4962&folderID=0 .

       
    2. Copy the extracted plugin into the plugins folder of your eclipse installation and then restart eclipse. Now we are ready to go. We are using JAXB(Java API for XML Binding) for the XML marshalling. The JAXB plugin will generate the Java (model) classes for us from a given XSD file.
       
  2. Create a Dynamic Web Project(Name: LiveRestaurant) in Eclipse, with src and resource folders as Source Folders on build path(Project --> Properties --> Java Build Path --> Source).
    You should have the following project structure when the setup is complete.




    Figure 2.2 Project Structure.


  3. Now we need to write the XML Schema first, which is based on this domain model.


    Figure 2.3. Domain Model


    Here is the XML Schema file, OrderService.xsd, save it under resource/com/live/order/schema

    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.liverestaurant.com/OrderService/schema"
        xmlns:tns="http://www.liverestaurant.com/OrderService/schema"
        elementFormDefault="qualified"
        xmlns:QOrder="http://www.liverestaurant.com/OrderService/schema">

        <element name="placeOrderRequest">
            <complexType>
                <sequence>
                    <element name="order" type="QOrder:Order"></element>
                </sequence>
            </complexType>
        </element>

        <element name="placeOrderResponse">
            <complexType>
                <sequence>
                    <element name="refNumber" type="string"></element>
                </sequence>
            </complexType>
        </element>

        <element name="cancelOrderRequest">
            <complexType>
                <sequence>
                    <element name="refNumber" type="string"></element>
                </sequence>
            </complexType>
        </element>

        <element name="cancelOrderResponse">
            <complexType>
                <sequence>
                    <element name="cancelled" type="boolean"></element>
                </sequence>
            </complexType>
        </element>

      <complexType name="Order">
          <sequence>
              <element name="refNumber" type="string"></element>
              <element name="customer" type="QOrder:Customer"></element>
              <element name="dateSubmitted" type="dateTime"></element>
              <element name="orderDate" type="dateTime"></element>
              <element name="items" type="QOrder:FoodItem"
                  maxOccurs="unbounded" minOccurs="1">
              </element>
          </sequence>
      </complexType>

      <complexType name="Customer">
          <sequence>
              <element name="addressPrimary" type="QOrder:Address"></element>
              <element name="addressSecondary" type="QOrder:Address"></element>
              <element name="name" type="QOrder:Name"></element>
          </sequence>
      </complexType>
      
      <complexType name="Name">
          <sequence>
              <element name="fName" type="string"></element>
              <element name="mName" type="string"></element>
              <element name="lName" type="string"></element>
          </sequence>
      </complexType>

      <complexType name="Address">
          <sequence>
              <element name="doorNo" type="string"></element>
              <element name="building" type="string"></element>
              <element name="street" type="string"></element>
              <element name="city" type="string"></element>
              <element name="country" type="string"></element>
              <element name="phoneMobile" type="string"></element>
              <element name="phoneLandLine" type="string"></element>
              <element name="email" type="string"></element>
          </sequence>
      </complexType>

        <simpleType name="FoodItemType">
            <restriction base="string">
                <enumeration value="Snacks"></enumeration>
                <enumeration value="Beverages"></enumeration>
                <enumeration value="Starters"></enumeration>
                <enumeration value="Meals"></enumeration>
                <enumeration value="Coffee"></enumeration>
                <enumeration value="Juices"></enumeration>
                <enumeration value="Desserts"></enumeration>
            </restriction>
        </simpleType>

        <complexType name="FoodItem">
            <sequence>
                <element name="type" type="QOrder:FoodItemType"></element>
                <element name="name" type="string"></element>
                <element name="quantity" type="double"></element>
            </sequence>
        </complexType>
    </schema>
    Code 2.1. OrderService.xsd

  4. We can now use the JAXB Plugin to generate the Domain classes from this XSD file.

    1. Right click on the xsd file(OrderService.xsd)
    2. JAXB 2.1
    3. Run XJC.
    4. Enter Package name : com.live.order.domain
    5. Enter Output Directory: <Project Root>\src\com\live\order\domain
    6. Next 
    7. Finish.



      Figure 2.4. XML to Java (XJC) Wizard for JAXB

    8. Refresh your workspace and see the classes generated in the src directory.
  5. Create the OrderService Java interface in the package, src/com.live.order.service


    package com.live.order.service;

    import com.live.order.domain.Order;

    /**
    * <pre>
    * Service interface for Order Service operations, handles two operations. <ul>
    *     <li>placeOrderRequest</li>
    *     <li>cancelOrderRequest</li>
    * </ul>
    * </pre>
    *
    *
    * @see OrderServiceImpl
    *
    */
    public interface OrderService {

        String placeOrder(Order order);

        boolean cancelOrder(String orderRef);
    }
    Code 2.2.OrderService.java
  6. Create a concrete implementation for OrderService, OrderServiceImpl.java, under  src/com.live.order.service.


    package com.live.order.service;

    import java.util.Calendar;

    import org.apache.commons.lang.ObjectUtils;
    import org.apache.log4j.Logger;

    import com.live.order.domain.Order;

    /**
    * <pre>
    * Service implementation for {@link OrderService}
    * </pre>
    *
    * @see OrderService
    *
    */
    public class OrderServiceImpl implements OrderService {
       
        private static final Logger logger = Logger.getLogger(OrderServiceImpl.class);

        public OrderServiceImpl() {
        }

        @Override
        public String placeOrder(Order order) {
            logger.info("Order has been placed. Order Info is : " + ObjectUtils.toString(order));
            return getRandomOrderRefNo();
        }

        @Override
        public boolean cancelOrder(String orderRef) {
            logger.info("Order has been placed. Order Reference : " + orderRef);
            return true;
        }
       
        private String getRandomOrderRefNo() {
            Calendar calendar = Calendar.getInstance();
            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH);
            int day = calendar.get(Calendar.DAY_OF_MONTH);

            return "Ref-" + year + "-" + month + "-" + day + "-" + Math.random();
           
        }
    }

    Code 2.3.OrderServiceImpl.java
  7. Now, create an Endpoint class for exposing this service, internally delegating to the OrderServiceImpl.

    package com.live.order.service.endpoint;

    import javax.xml.bind.JAXBElement;
    import javax.xml.namespace.QName;

    import org.springframework.ws.server.endpoint.annotation.Endpoint;
    import org.springframework.ws.server.endpoint.annotation.PayloadRoot;

    import com.live.order.domain.CancelOrderRequest;
    import com.live.order.domain.CancelOrderResponse;
    import com.live.order.domain.ObjectFactory;
    import com.live.order.domain.PlaceOrderRequest;
    import com.live.order.domain.PlaceOrderResponse;
    import com.live.order.service.OrderService;

    /**
    * <pre>
    * This is the endpoint for the {@link OrderService}.
    * Requests are simply delegated to the {@link OrderService} for processing.
    * Two operations are mapped, using annotation, as specified in the link,
    * <a href="http://static.springsource.org/spring-ws/sites/1.5/reference/html/server.html#server-at-endpoint"
    * >http://static.springsource.org/spring-ws/sites/1.5/reference/html/server.html#server-at-endpoint</a
    * ><ul>
    *     <li>placeOrderRequest</li>
    *     <li>cancelOrderRequest</li>
    * </ul>
    * </pre>
    *
    */
    @Endpoint
    public class OrderServicePayloadRootAnnotationEndPoint {

        private final OrderService orderService;
        private final ObjectFactory JAXB_OBJECT_FACTORY = new ObjectFactory();
       
        public OrderServicePayloadRootAnnotationEndPoint(OrderService orderService) {
            this.orderService = orderService;
        }

        @PayloadRoot(localPart = "placeOrderRequest", namespace = "http://www.liverestaurant.com/OrderService/schema")
        public JAXBElement<PlaceOrderResponse> getOrder(
                PlaceOrderRequest placeOrderRequest) {
            PlaceOrderResponse response = JAXB_OBJECT_FACTORY
                    .createPlaceOrderResponse();
            response.setRefNumber(orderService.placeOrder(placeOrderRequest
                    .getOrder()));

            return new JAXBElement<PlaceOrderResponse>(new QName(
                    "http://www.liverestaurant.com/OrderService/schema",
                    "placeOrderResponse"), PlaceOrderResponse.class, response);
        }

        @PayloadRoot(localPart = "cancelOrderRequest", namespace = "http://www.liverestaurant.com/OrderService/schema")
        public JAXBElement<CancelOrderResponse> cancelOrder(
                CancelOrderRequest cancelOrderRequest) {
            CancelOrderResponse response = JAXB_OBJECT_FACTORY
                    .createCancelOrderResponse();
            response.setCancelled(orderService.cancelOrder(cancelOrderRequest
                    .getRefNumber()));
            return new JAXBElement<CancelOrderResponse>(new QName(
                    "http://www.liverestaurant.com/OrderService/schema",
                    "cancelOrderResponse"), CancelOrderResponse.class, response);
        }

    }
    Code 2.4. OrderServicePayloadRootAnnotationEndPoint.java
  8. Add Spring-WS nature and dependencies to the project
    1. Download Spring-WS-2.0.0-M2-with-dependencies.zip from http://www.springsource.com/download/community.
    2. Extract and copy the dependency jar files to <project-root>/WebComtent/WEB-INF/lib.

  9. Modify the web configuration file, web.xml to add the MessageDispatcherServlet as given below(the entire web.xml file)



    <?xml version="1.0" encoding="UTF-8"?>
               
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           
        xmlns="http://java.sun.com/xml/ns/javaee"          xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee             http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
               
        <display-name>LiveRestaurant</display-name>
        <servlet>
            <servlet-name>spring-ws</servlet-name>
            <servlet-class>
    org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
        </servlet>
               
        <servlet-mapping>
            <servlet-name>spring-ws</servlet-name>
            <url-pattern>/*</url-pattern>
        </servlet-mapping>
    </web-app>
    Code 2.3. web.xml

     
  10. Add the Spring-WS configuration file, under WEB-INF, with the following content


    <?xml  version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"                     xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/context                        
    http://www.springframework.org/schema/context/spring-context-2.5.xsd">

        <!--     PayloadRootAnnotationMethodEndpointMapping is the Mapping that             detects and handles the @PayloadRoot Annotation -->
        <bean             class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
            <property name="interceptors">
                <list>
                     <bean             class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
                </list>
            </property>
        </bean>
               
        <bean id="orderServiceEndpoint"
    class="com.live.order.service.endpoint.OrderServicePayloadRootAnnotationEndPoint">
            <constructor-arg>
                <bean class="com.live.order.service.OrderServiceImpl"/>
            </constructor-arg>
        </bean>
        <bean id="OrderService"             class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
            <property name="schema" ref="orderServiceSchema"/>
            <property name="portTypeName" value="OrderService"/>
            <property name="locationUri" value="http://www.liverestaurant.com/OrderService/" />
            <property name="targetNamespace" value="http://www.liverestaurant.com/OrderService/schema"/>
        </bean>
               
        <bean id="orderServiceSchema" class="org.springframework.xml.xsd.SimpleXsdSchema">
            <property name="xsd" value="/WEB-INF/classes/com/live/order/schema/OrderService.xsd"/>
        </bean>

        <bean             class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter">
            <constructor-arg ref="marshaller" />
        </bean>

        <bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
            <property name="contextPath" value="com.live.order.domain"/>
        </bean>
               
    </beans>       
    Code 2.4. spring-ws-servlet.xml

  11. Configure your Tomcat Server inside your Eclipse workspace.
  12. Deploy the application into the Tomcat Server
  13. Resolve all IDE specific and deployment errors by resolving dependencies and paths
  14. Find the WSDL url at http://localhost:8080/LiveRestaurant/spring-ws/OrderService.wsdl.

    You should be able to see the wsdl with this structure, in the usual xml format.


    <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:sch="http://www.liverestaurant.com/OrderService/schema"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.liverestaurant.com/OrderService/schema"
        targetNamespace="http://www.liverestaurant.com/OrderService/schema">
        <wsdl:types>
            <schema xmlns="http://www.w3.org/2001/XMLSchema"
                xmlns:QOrder="http://www.liverestaurant.com/OrderService/schema"
                elementFormDefault="qualified"
                targetNamespace="http://www.liverestaurant.com/OrderService/schema"
                xmlns:tns="http://www.liverestaurant.com/OrderService/schema">

                <element name="placeOrderRequest">
                    <complexType>
                        <sequence>
                            <element name="order" type="QOrder:Order"/>
                        </sequence>
                    </complexType>
                </element>

                <element name="placeOrderResponse">
                    <complexType>
                        <sequence>
                            <element name="refNumber" type="string" />
                        </sequence>
                    </complexType>
                </element>

                <element name="cancelOrderRequest">
                    <complexType>
                        <sequence>
                            <element name="refNumber" type="string" />
                        </sequence>
                    </complexType>
                </element>

                <element name="cancelOrderResponse">
                    <complexType>
                        <sequence>
                            <element name="cancelled" type="boolean"/>
                        </sequence>
                    </complexType>
                </element>

                <complexType name="Order">
                    <sequence>
                        <element name="refNumber" type="string" />
                        <element name="customer" type="QOrder:Customer"/>
                        <element name="dateSubmitted" type="dateTime" />
                        <element name="orderDate" type="dateTime" />
                        <element maxOccurs="unbounded" minOccurs="1" name="items"
                            type="QOrder:FoodItem">
                        </element>
                    </sequence>
                </complexType>

                <complexType name="Customer">
                    <sequence>
                        <element name="addressPrimary" type="QOrder:Address" />
                        <element name="addressSecondary" type="QOrder:Address" />
                        <element name="name" type="QOrder:Name" />
                    </sequence>
                </complexType>

                <complexType name="Name">
                    <sequence>
                        <element name="fName" type="string" />
                        <element name="mName" type="string" />
                        <element name="lName" type="string" />
                    </sequence>
                </complexType>

                <complexType name="Address">
                    <sequence>
                        <element name="doorNo" type="string" />
                        <element name="building" type="string" />
                        <element name="street" type="string" />
                        <element name="city" type="string" />
                        <element name="country" type="string" />
                        <element name="phoneMobile" type="string" />
                        <element name="phoneLandLine" type="string" />
                        <element name="email" type="string" />
                    </sequence>
                </complexType>

                <simpleType name="FoodItemType">
                    <restriction base="string">
                        <enumeration value="Snacks" />
                        <enumeration value="Beverages" />
                        <enumeration value="Starters" />
                        <enumeration value="Meals" />
                        <enumeration value="Coffee" />
                        <enumeration value="Juices" />
                        <enumeration value="Desserts" />
                    </restriction>
                </simpleType>

                <complexType name="FoodItem">
                    <sequence>
                        <element name="type" type="QOrder:FoodItemType"/>
                        <element name="name" type="string" />
                        <element name="quantity" type="double" />
                    </sequence>
                </complexType>


            </schema>
        </wsdl:types>
        <wsdl:message name="placeOrderRequest">
            <wsdl:part element="tns:placeOrderRequest" name="placeOrderRequest">
            </wsdl:part>
        </wsdl:message>
        <wsdl:message name="cancelOrderResponse">
            <wsdl:part element="tns:cancelOrderResponse" name="cancelOrderResponse">
            </wsdl:part>
        </wsdl:message>
        <wsdl:message name="cancelOrderRequest">
            <wsdl:part element="tns:cancelOrderRequest" name="cancelOrderRequest">
            </wsdl:part>
        </wsdl:message>
        <wsdl:message name="placeOrderResponse">
            <wsdl:part element="tns:placeOrderResponse" name="placeOrderResponse">
            </wsdl:part>
        </wsdl:message>
        <wsdl:portType name="OrderService">
            <wsdl:operation name="placeOrder">
                <wsdl:input message="tns:placeOrderRequest" name="placeOrderRequest">
                </wsdl:input>
                <wsdl:output message="tns:placeOrderResponse" name="placeOrderResponse">
                </wsdl:output>
            </wsdl:operation>
            <wsdl:operation name="cancelOrder">
                <wsdl:input message="tns:cancelOrderRequest" name="cancelOrderRequest">
                </wsdl:input>
                <wsdl:output message="tns:cancelOrderResponse" name="cancelOrderResponse">
                </wsdl:output>
            </wsdl:operation>
        </wsdl:portType>
        <wsdl:binding name="OrderServiceSoap11" type="tns:OrderService">
            <soap:binding style="document"
                transport="http://schemas.xmlsoap.org/soap/http" />
            <wsdl:operation name="placeOrder">
                <soap:operation soapAction="" />
                <wsdl:input name="placeOrderRequest">
                    <soap:body use="literal" />
                </wsdl:input>
                <wsdl:output name="placeOrderResponse">
                    <soap:body use="literal" />
                </wsdl:output>
            </wsdl:operation>
            <wsdl:operation name="cancelOrder">
                <soap:operation soapAction="" />
                <wsdl:input name="cancelOrderRequest">
                    <soap:body use="literal" />
                </wsdl:input>
                <wsdl:output name="cancelOrderResponse">
                    <soap:body use="literal" />
                </wsdl:output>
            </wsdl:operation>
        </wsdl:binding>
        <wsdl:service name="OrderServiceService">
            <wsdl:port binding="tns:OrderServiceSoap11" name="OrderServiceSoap11">
                <soap:address location="http://www.liverestaurant.com/OrderService/" />
            </wsdl:port>
        </wsdl:service>
    </wsdl:definitions>
    OrderService.wsdl
          Now our web-service is successfully deployed, ready to be consumed by any client application which has an access to the WSDL. Note, the URL for a client program is http://localhost:8080/LiveRestaurant/spring-ws/OrderService.

         In the next post, I will describe how these components work together, and the roles of each component in that process, before we build a client program for this service. Expect it soon...

93 comments:

  1. Hi Murali,

    The URL of the WSDL is formed in this format:
    http://[host]:[port]/[context]/[servlet]/[wsdl-name].wsdl.

    Hence the URL in the above example is : http://localhost:8080/LiveRestaurant/spring-ws/OrderService.wsdl.

    From the error message you have posted[Servlet spring-ws is not available], it looks like the application has some start up problems, or the servlet is not initialized properly.

    One possible reason I can think of is the unresolved library(jar) dependencies. Make sure you have all jar files in the class path.

    Check web.xml for your servlet name, and the Context definition(possibly in the tomcat's server.xml) for the Context name.

    ReplyDelete
  2. Hi Shameer,
    I am getting the following exception ... I made sure i added all the necessary jars.

    Here is the snapshot of the Exception:
    type Exception report

    message

    description The server encountered an internal error () that prevented it from fulfilling this request.

    exception

    javax.servlet.ServletException: Servlet.init() for servlet spring-ws threw exception
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Unknown Source)


    root cause

    java.lang.NoClassDefFoundError: org/springframework/asm/ClassVisitor
    org.springframework.context.support.AbstractRefreshableApplicationContext.customizeBeanFactory(AbstractRefreshableApplicationContext.java:218)
    org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
    org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:465)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:395)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:443)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:459)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:340)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:307)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
    javax.servlet.GenericServlet.init(GenericServlet.java:212)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Unknown Source)

    ReplyDelete
  3. The root cause of your exception is - java.lang.NoClassDefFoundError: org/springframework/asm/ClassVisitor. And it is present in the dependent jars, spring-2.5.6.jar and spring-core-2.5.6.jar.

    Can you tell me where have you placed these jar files(and other dependent jars) ? When deployed, it should come under the WEB-INF/lib folder to be auto-detected by the servlet container.

    Please make sure all required jar files(best is to copy all jar files from the Spring-WS libraries) are in the right place.

    ReplyDelete
  4. Hi Shameer,

    Thank you very much for the post. It made my work developing spring webservice much easier with clear explanation of each step in order. I am able to deploy it successfully on Tomcat 6.0 but getting connection timeout exception.

    wsdl was generated successfully and i created the project in soapUI providing generated wsdl URL. when i hit on execute of Request i am not getting the response back instead says Error getting Response: java.net.ConnectException.The endpoint i am using here is
    http://www.liverestaurant.com/OrderService/

    Also i have my service up and running on the Tomcat.

    Any kind of advice is appreciated.

    Thanks
    Pallavi

    ReplyDelete
  5. Hi Shameer, I am trying to learn Webservices for the first time, so kindly bear with me if i am doing any mistake.
    I added all the jar in the /WebContent/WEB-INF/lib so it can be picked up while server bootup.

    As you suggested, i copied all the jars from http://www.springsource.com/download/community
    "spring-ws-2.0.0-M2-with-dependencies.zip (sha1) 24.9 MB ". I have all the latest version of the jars .. all that end with **3.0.1.RELEASE.jar. I do not have the 2.5.6version of the spring jars. Do i have to replace the version 3.0 with the 2.5.6 jars as you mentioned above.

    I am sure, it is something to do with improper version of jars... In case you want me to replace the jars can you please tell me what jars would be needed so that i do not make a mistake again and waste your time :-) ..

    ReplyDelete
  6. Pallavi,

    Good to know that it helped you.

    http://www.liverestaurant.com/OrderService/ is just a names pace. It is not the URL you should use for the client. soapUI takes it as the default one. But you need to change the URL, to the one with which you can see the WSDL file, removing the .wsdl extension.

    Since I have deployed the service on a tomcat server on my local PC, at port 8080, my URL is http://localhost:8080/LiveRestaurant/spring-ws/OrderService. I guess it applies to you as well, if you have the same kind of setup.

    Namespace and the actual URL can be different, however, the general practice is that, we give a URL matching to the one when we go live, as the namespace. For example, if we host the service online with a URL http://www.liverestaurant.com, the namespace becomes exactly same as the real URL, hence it matches. And ours is a demo program, right :)

    ReplyDelete
  7. Sreecharan,

    This blog is created for you guys who are new to these technologies, to get programming easier and enjoyable. So feel free to ask any questions until your problem is solved. Try, err and try again.. until you succeed. That is the way to go.

    Let us find what exactly is going on there. I want to know the setup details of your environment.

    What is your IDE (Eclipse/IntelliJ/NetBeans/...)?
    What is your server (Tomcat/Weblogic/...)?
    How did you configure the server ? Is it an embedded server inside your IDE ?
    How do you deploy the application ? Are you copying the war/entire folder to the deploy (webapp dir in the case of tomcat) or you publish it from the IDE ?

    If you have configured the server inside the IDE, and publishing the app from the IDE, then you need to setup the Java Build Path properly, you need to have all those jars inside that path. Can you check it out ?

    Also, can you browse through the jar files(spring-xxx-xxx.jar) and locate the missing class, org/springframework/asm/ClassVisitor ?

    Please let me know.

    ReplyDelete
  8. Hi Shameer,

    Thanks for the reply. Here is my wsdl url
    http://localhost:8080/LiveRestaurant/spring-ws/OrderService.wsdl where i am able to see proper wsdl.

    So i changed endpoint URL to
    http://localhost:8080/LiveRestaurant/spring-ws/OrderService

    I am getting HTTP 405 error if i try to access it from browser.

    This is the response from SOAPUI:
    HTTP Status 404 - Status report The requested resource () is not available

    I tried using spring ws webserviceTemplate with same endpoint URL i am getting this error:
    org.springframework.ws.client.WebServiceTransportException: Not Found [404]

    Any suggestion of what i am doing wrong.

    Thanks again.
    Pallavi.

    ReplyDelete
  9. Hi,

    This is the exception i am getting in tomcat console when i hit on execute of request from Soap UI.

    WARNING: No endpoint mapping found for [SaajSoapMessage {http://www.liverestaurant.com/OrderService}placeOrderRequest]

    Any advice how to do this mapping.

    Thanks
    Pallavi.

    ReplyDelete
  10. Hi Murali,

    Thanks for pointing out that mistake(at step 14, about the URL), I think it was the same place where Pallavi is also stuck.

    I have corrected it in the blog, now you can see the right URL at step 14.

    ReplyDelete
  11. Murali,

    I will discuss the client program with Spring-WS soon after another post in construction, about the client program in WCF(Windows Communication Foundation) of the .Net platform.

    Mean while you can go through a newer post, discussing about the components of Spring-WS and how it works[Title: How does a Spring Web Service work ?] at http://justcompiled.blogspot.com/2010/10/how-does-spring-web-service-work.html.

    ReplyDelete
  12. Pallavi,

    I think you are using the wrong URL, as there was a small mistake in the URL given at step 14. I have corrected it now.

    Let me make it clear again.

    URL#1[WSDL URL]. The URL you can see the WSDL (in a browser or anywhere) is http://localhost:8080/LiveRestaurant/spring-ws/OrderService.wsdl

    URL#2[Endpoint URL]. The URL you should supply to client program [as the endpoint] to invoke the service is http://localhost:8080/LiveRestaurant/spring-ws/OrderService.

    The difference between both URL#1 and URL#2 is just the file name extension [.wsdl].

    You cannot use URL#2 in a browser, as it expects the SOAP message with the request, which you are not providing via a browser. So use URL#1 in a browser to see the WSDL.

    In your soapUI, you should supply URL#2, as the endpoint URL, in order to invoke the service.

    Hope this will make it clear.

    Let me know how it goes. Otherwise, I should think of another post on "how to test a web-service in soapUI" ;)

    ReplyDelete
  13. Hi Shameer,

    Finally i could make it work with soapUI and using Springws client. Thanks for the post.

    In OrderServicePayloadRootAnnotationEndPoint class namespace was specified as
    @PayloadRoot(localPart = "placeOrderRequest", namespace = "http://www.liverestaurant.com/OrderService/schema") which i changed to http://www.liverestaurant.com/OrderService as in OrderService.xsd.

    Now this is working fine.

    Thanks
    Pallavi.

    ReplyDelete
  14. Excellent, Pallavi.

    You found the problem, and it's all copy paste mistakes ;).

    I have made the correction in the schema itself, corrected the namespace(it is used in many other places). Better you take that correction, since that namespace is going to be used in the later posts, which are about client, and adding security with digital signatures.

    Thanks for pointing out the mistake, Pallavi.

    ReplyDelete
  15. Hi Shameer,

    I'm trying to do the same, but in a different way... I want to go from the Implementation class, directly to the wsdl.

    Please, can you check this question I wrote in stackoverflow and see if you can give me a hand?

    http://stackoverflow.com/questions/3909889/build-a-ws-with-spring

    Thanks in advance

    Neuquino

    ReplyDelete
  16. Hi, can someone post a working client for this service? When I tried, I am getting the following warning on the service side :
    [EndpointNotFound] No endpoint mapping found for [SaajSoapMessage placeOrderRequest]

    And, on the client side I get the following error:
    org.springframework.ws.client.WebServiceTransportException: Not Found [404]
    Thanks,
    Basheer.

    ReplyDelete
  17. Basheer,

    The WS client post is in progress, expect it soon.

    BTW, what was your URL ?

    ReplyDelete
  18. Thanks Shameer. I fixed the above problem by adding the namespace attribute to the @XmlRootElement annotation for the PlaceOrderRequest and PlaceOrderResponse classes on the client side. With this, the service side endpoint is invoked, but the payload object (Order) is null. Any help is appreciated. My email id is shaikbash@gmail.com.
    Thanks again,
    Basheer.

    ReplyDelete
  19. Basheer, Can you post your client code here ?

    ReplyDelete
  20. A new post, "Building a Web Service Client with Spring-WS" is added at
    http://justcompiled.blogspot.com/2010/11/web-service-client-with-spring-ws.html

    ReplyDelete
  21. I have this working, except when I test in SoapUI, I get no results. I included a log statement, prior to the return, and show that the data is there..
    Why does nothing show up in SoapUI?

    ReplyDelete
  22. nevermind.. figured it out. Had to include the saaj-impl.jar in my code.. For some reason, the jboss one does not work. I had this deployed to jboss.

    ReplyDelete
  23. Hi,

    Can you provide some details on how to return custom exception types? Basically the auto-generated WSDL file needs to contain the wsdl:fault tag defined inside wsdl:operation.

    Thanks.

    ReplyDelete
  24. Kamal,

    Please refer to the "Handling Exceptions" section of the official Spring-WS reference website @
    http://static.springsource.org/spring-ws/sites/1.5/reference/html/server.html#server-endpoint-exception-resolver

    This section describes how to return custom SOAP Faults to the client in case of an exception at the service.

    ReplyDelete
  25. Hi, I had placed the Jaxbpi plugin in the eclipse plugin folder and did a restart. But I am missing the options as mentioned in Step 4. Please assist ASAP. thanks

    ReplyDelete
  26. Shameer,
    I am having a terrible time trying to find this plugin. I have looked at both of the url's you posted and have looked elsewhere as well and all I'm finding are dead ends. Has something changed and I am just missing it?

    ReplyDelete
  27. You are right, the original link is broken, as it has been moved to somewhere else. You try this link - http://sourceforge.net/projects/jaxb-builder/files

    If it doesn't help, you send me your email address, I can send the plugin via email.

    ReplyDelete
  28. Shameer, I'd like to get a copy of the plugin you used in the article as well, I have sent you an email.

    @praveen
    I have read that when you are installing plugins by adding them to the Eclipse plugins directory that you should start Eclipse from the command line using the -clean switch in order to have the new plugins registered with the IDE.

    ReplyDelete
  29. Eben, The plugin is sent to your email now.

    ReplyDelete
  30. Hi Shameer , thanks for the post
    I am looking for web service as well as the client, with security by using some security framework like WSS4J, do you have any posts related to this?.

    ReplyDelete
  31. Shiva,

    Posts with security are in plan. I got busy with work here, that caused the delay.
    Expect them soon :)

    ReplyDelete
  32. Hi Shameer,
    Nice tutorial on Spring-WS. But I believe you should have gone for JAX-WS which is a part of JavaEE 5 onwards. Its quite easy to generate webservice/webservice client than any other webservice generator frameworks. You just have to place the annotation on the classes and declare your class as a servlet in web.xml.

    ReplyDelete
  33. Hi Shameer,

    Can you please email me the eclipse XJC JAXB plugin to dramakr@gmail.com.

    Thanks,
    Dinesh

    ReplyDelete
  34. Hi Shameer,
    I am running above example with JDK5.0, Tomcat 6.0 & Eclipse. I am getting an error:

    WSDLException: faultCode=CONFIGURATION_ERROR: No Java extensionType found to represent a '{http://www.w3.org/2001/XMLSchema}schema' element in the context of a 'javax.wsdl.Types'.:

    Please assist.

    ReplyDelete
  35. @Praveen

    It looks like a WSDL4J version problem. Take a look at this Spring JIRA bug.

    https://jira.springsource.org/browse/SWS-166

    It recommends using WSDL4J 1.6.2, look at Arjen Poustma's comments.

    ReplyDelete
  36. Hi Shameer,

    How the payload PayloadLoggingInterceptor work? Should the incoming SOAP message payload being logged?

    I use spring-ws 2.0.1 and tomcat 7.0.5.
    But did not see any payload logged in catalina.log.

    Please assist.

    Thanks!

    ReplyDelete
  37. Hi Shameer,

    I would like to follow this tutorial. Can you please send the JAXB plug-in for Eclipse to pablo.williams@gmail.com.

    Thanks.

    ReplyDelete
  38. Hello....
    I'm getting an error in OrderServicePayloadRootAnnotationEndPoint class for ObjectFactory not resolvable..
    obviously i'm not getting that class when doing xsd to java

    ReplyDelete
  39. Hi Pablo,

    you can download the JAXB plugin from this link.
    http://cid-4498153a7d374441.office.live.com/self.aspx/JustCompiled/org.jvnet.jaxbw.zip

    ReplyDelete
  40. Ravi,

    ObjectFactory is often generated when you execute the XJC command of the JAXB plugin on an XSD file, in the same folder as the generated classes.

    ReplyDelete
  41. Hello Shameer...
    ObjectFactory problem resolved..
    but got new error....

    java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory

    and i have commons.lang-2.6.jar in my lib folder

    ReplyDelete
  42. Hello Shameer...
    now also got solved java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory problem

    but got new problem

    org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/spring-ws-servlet.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/spring-ws-servlet.xml]


    coming on console...

    please help working on same example since last 1.5 days

    ReplyDelete
  43. Hello Shameer...
    also got previous error solved...

    as always got new error..

    org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.live.order.service.OrderServicePayloadRootAnnotationEndPoint] for bean with name 'orderServiceEndpoint' defined in ServletContext resource [/WEB-INF/spring-ws-servlet.xml]; nested exception is java.lang.ClassNotFoundException: com.live.order.service.OrderServicePayloadRootAnnotationEndPoint


    i checked all my packages and files they are appropriate place only

    don't know why it's not running...

    ReplyDelete
  44. The Spring DispatcherServlet looks for the configuration file, in the pattern, {servlet-name}-servlet.xml in the WEB-INF folder by default, if not specified otherwise. In your case, the servlet-name is 'spring-ws', hence it is looking for a resource [/WEB-INF/spring-ws-servlet.xml].

    Are you sure you have that file with the exactly same name(it is case sensitive), in your WEB-INF folder ?

    ReplyDelete
  45. yeah..i got it correct and error gone.

    but another problem arises that


    org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.live.order.service.endpoint.OrderServicePayloadRootAnnotationEndPoint] for bean with name 'orderServiceEndpoint' defined in ServletContext resource [/WEB-INF/spring-ws-servlet.xml]; nested exception is java.lang.ClassNotFoundException: com.live.order.service.endpoint.OrderServicePayloadRootAnnotationEndPoint


    it's not able to find endpoint class and i checked all my directories, it's perfect as suggested in this example

    ReplyDelete
  46. Check your Source folders configured properly on the Java Build Path of the Eclipse Project, by right clicking on it.

    You should see two source folders, src and resources. Add them if they are not already there, rebuild, redeploy, and see if it works.

    ReplyDelete
  47. Hello Shameer...
    Huge thanks man!!!!!

    Finally .wsdl on my browser screen...

    excellent post....

    Again Thanks...

    ReplyDelete
  48. javaeye,

    For the logged message to be seen, you need to configure log4j to your app.

    You may configure Log4J for the service app, and set the log level to debug, then you can see the MessageDispatcher logs the incoming SOAP request and the outgoing SOAP response.

    Easy way to configure Log4J, is these four steps.
    1) Add log4j jar file into your classpath/project
    2) Add a context-param in the web.xml, name = log4jConfigLocation, value = /WEB-INF/log4j.properties
    3) Add a log4j.properties file into the WEB-INF folder
    4) Add property, log4j.logger.org.springframework=DEBUG
    in the lof4j.properties

    Rebuild, redeploy the app, run the client program again, you should see the message in the console, among other spring debug messages.

    ReplyDelete
  49. Hey Shameer..it's only since 5 days i'm doing Spring.
    after getting this service
    now i want service to able to receive and expose in JSON format

    i searched quite a lot..if u can direct me a bit..it would be great..

    ReplyDelete
  50. Ravi,

    I haven't tried JSON instead of XMl in Webservices, but I found that XStream is a powerful API for XML marshalling, that supports JSON format. Visit - http://xstream.codehaus.org/json-tutorial.html.

    I could find a pointer for JSON marshalling using XStream API in Spring-WS.

    Hope it helps.

    http://www.oreillynet.com/onjava/blog/2007/11/xstream_and_spring_oxm_objectx.html

    ReplyDelete
  51. I got this working.. Thanks buddy :)

    ReplyDelete
  52. Hi Shameer , In XSD i am Using the minOccur and Maxoccur which gives JAXBElement
    JAXBElement
    , so can we use with spring this one

    ReplyDelete
  53. Hi Shameer,

    I got some questiones here, (plz execuse my ignorance).
    1) Is this wsdl will automatically generated once the service is deployed?
    2)If so(point 1),I am trying to test this example on RAD (WAS61) but i am getting notofication as ---
    "A WebGroup/Virtual Host to handle /LiveRestaurant/spring-ws/OrderService.wsdl has not been defined."

    and in browser it is throwing exceptions as

    Error 404: SRVE0203E: Servlet [spring-ws]: org.springframework.ws.transport.http.MessageDispatcherServlet was found, but is missing another required class. SRVE0206E: This error typically implies that the servlet was originally compiled with classes which cannot be located by the server. SRVE0187E: Check your classpath to ensure that all classes required by the servlet are present.SRVE0210I: This problem can be debugged by recompiling the servlet using only the classes in the application's runtime classpath SRVE0234I: Application classpath=[E:\Program Files\IBM\SDP\runtimes\base_v61\java\lib;E:\Program Files\IBM\SDP\runtimes\base_v61\java\lib\dt.jar;E:\Program Files\IBM\SDP\runtimes\base_v61\java\lib\htmlconverter.jar;E:\Program Files\IBM\SDP\runtimes\base_v61\java\lib\jardiff.jar;E:\Program Files\IBM\SDP\runtimes\base_v61\java\lib\jnlp-servlet.jar;E:\Program Files\IBM\SDP\runtimes etc....

    Please advise...

    ReplyDelete
  54. Hi I tried the example and it worked perfectly. But after integrating my application with struts2 and web services are not working. I am sure there is some configuration change has to be made in web.xml but not able to figure it out. If possible can you please check for error...


    org.springframework.web.context.ContextLoaderListener


    spring-ws
    org.springframework.ws.transport.http.MessageDispatcherServlet
    1


    spring-ws
    /spring-ws/*


    spring-ws
    *.wsdl



    org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG
    /WEB-INF/tiles.xml


    struts2
    org.apache.struts2.dispatcher.FilterDispatcher


    struts2
    /*


    org.apache.struts2.tiles.StrutsTilesListener

    ReplyDelete
  55. hi shammer,
    vry good post..i run it sucessfully without any difficulties..WSDL4j.jar is also need to run this example...
    Thanks!
    Amit

    ReplyDelete
  56. Hi Murali,

    I am fascinated by Spring and the way you have explained Spring WS example. Whenever I am lost with Spring WS. Your blog is my best source to revise my knowledge on Spring Ws... Brilliant Post!!

    ReplyDelete
  57. I think it would be also helpful if you can show us to create XML Schema file either from design diagram or some tool you used?

    ReplyDelete
  58. Could you please share the source code of this post.it will be really helpful

    ReplyDelete
  59. Thanks for the brilliant write up which actually helped me while working with spring-ws. I noticed an appealing domain model diagram above. May I know which tool did you use to generated these diagrams as I am in a search of one for drawing uml diagrams ~ class diagrams.

    ReplyDelete
  60. @3addc300-2a53-11e1-9c24-000f20980440,

    I have used Oracle JDeveloper for generating the UML diagrams out of the class files that I had generated by the JAXB Plugin in eclipse. Oracle JDeveloper UML plugin has more support for recent versions of Java, compared to other tools.

    For designing UML diagrams quickly out of nothing, I would recommend StarUML, which is very simple to me. I use Visual Paradigm and Enterprise Architect commercial versions for advanced uses.

    Let me know if you know a better tool which is easier and cost effective.

    Cheers,
    Shameer

    ReplyDelete
  61. Thanks Shameer !

    UMLLab[http://www.uml-lab.com/en/uml-lab/] is a good for UML diagrams but it commercial :(. I am not sure of the pricing to say if it is cost effective or not, but the diagrams generated are catchy.
    I will give a try to the tools you mentioned.

    - Sunil

    ReplyDelete
  62. Could you please upload the war including all dependent jars somewhere,so that we can deploy directly in tomcat,please?

    ReplyDelete
  63. help me out with specifying jars used for this tutorial.

    ReplyDelete
  64. Actually i am using RAD ide with WAS 7.5 and Spring 2.5.6 , Spring-WS 1.5.9 version jars, But unable to get rid of the class not found exceptions. So could you please provide the list of jars compatible along with all dependencies.

    ReplyDelete
  65. Hi Shameer,

    Really, I glad to wish for u created this blog spot.

    I run u r "Live Restauraunt program" (http://justcompiled.blogspot.in/2010/09/building-web-service-with-spring-ws.html) ,I got exception. I followed Properly till 14th step.

    Please make sure that How many jar files are needed for this project (Give the name of jars), Because, I can't get proper jar files from u r link(http://www.springsource.com/download/community.).

    Any kind of advice for successful run this project.

    My Project Configuration:::>>>>>

    Tool : Eclilpse Indigo,
    Server : Tomcat 7.
    Java : JDK, JRE 1.6
    Deploy : Weapps (Inside my project )


    My Exception:::::::>>>>>>>:


    HTTP Status 500 -

    type Exception report

    message

    description The server encountered an internal error () that prevented it from fulfilling this request.

    exception

    javax.servlet.ServletException: Servlet.init() for servlet spring-ws threw exception
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:269)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
    java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.lang.Thread.run(Unknown Source)
    root cause

    java.lang.NoSuchFieldError: APPLICATION_CONTEXT_ID_PREFIX
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:431)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:459)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:340)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:307)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
    javax.servlet.GenericServlet.init(GenericServlet.java:160)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:269)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
    java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.lang.Thread.run(Unknown Source)
    --

    ReplyDelete
  66. Please try to upload whole project by using tomcat server.

    ReplyDelete
  67. Many have requested for the classpath dependencies for the project. Here are the jar files I have added into the classpath, for the service project. Most of them are available from the Spring download(with dependencies) archive.


    aopalliance-1.0.jar
    commons-logging-1.1.1.jar
    log4j-1.2.9.jar
    spring-aop-3.0.5.RELEASE.jar
    spring-asm-3.0.5.RELEASE.jar
    spring-beans-3.0.5.RELEASE.jar
    spring-context-3.0.5.RELEASE.jar
    spring-context-support-3.0.5.RELEASE.jar
    spring-core-3.0.5.RELEASE.jar
    spring-expression-3.0.5.RELEASE.jar
    spring-oxm-3.0.5.RELEASE.jar
    spring-web-3.0.5.RELEASE.jar
    spring-webmvc-3.0.5.RELEASE.jar
    spring-ws-core-2.0.1.RELEASE.jar
    spring-xml-2.0.1.RELEASE.jar
    wsdl4j-1.6.1.jar

    ReplyDelete
  68. Hi Shammer,

    I am not able to find download the JAXB plugins from
    https://jaxb-workshop.dev.java.net/plugins/eclipse/xjc-plugin.html%20

    OR

    https://jaxb-workshop.dev.java.net/servlets/ProjectDocumentList?folderID=4962&expandFolder=4962&folderID=0 .

    Could you please tell me any other location?
    I am new to Spring WS. I downloaded the plugin from another location but for that I have to create a new Java Binding Project to generate the Java from XSD. I could not see the JAXB 2.1 option after right click on XSD file

    Thanks,
    Suraj

    ReplyDelete
  69. Hi Shammer,

    Is there any way to add the wsdl:fault element in the dynamic generated WSDL?.

    ReplyDelete
  70. Hi Shameer,

    It's great blog for us who are new to spring-ws.

    Please look into my wsdl file. The required message and operation is missing from this. Please suggest the problem...

    ReplyDelete
  71. Shameer
    I deployed exactly as described in the article. But http://localhost:8080/LiveRestaurant/spring-ws/OrderService?wsdl returns

    type Status report

    message /LiveRestaurant/spring-ws/OrderService

    description The requested resource (/LiveRestaurant/spring-ws/OrderService) is not available.

    I have verified the Web.xml file and its the same as you have above.

    Any idea what else could be the reason?

    ReplyDelete
  72. Hi Shameer , the post is really helpful to us. Thanks.
    I am looking for web service as well as the client, with security by using security XWSS, do you have any posts related to this?

    Thanks
    Satish

    ReplyDelete
  73. hi shameer, i was able to run both ur client and service c ode on tomcat.Thank you very much.It doesnt work on jboss5.1.I dint get any response. i.e my response object was null.:(

    ReplyDelete
  74. Hi,

    I unable to get the JAXB Eclipse plugin from mentioned links

    https://jaxb-workshop.dev.java.net/plugins/eclipse/xjc-plugin.html%20

    OR

    https://jaxb-workshop.dev.java.net/servlets/ProjectDocumentList?folderID=4962&expandFolder=4962&folderID=0 .

    ReplyDelete
  75. Hi Anantaraj,

    You can download the required jar files including the XJC plugin using maven if you create a pom file with the maven-jaxb2-plugin. Google for the HOW-TO, with maven-jaxb2-plugin as the key word.

    ReplyDelete
  76. Hi Anjz,

    Hope you have solved the issue already. Your jboss may have conflicting jar files in its module directories. You should resolve the dependenciesnd conflicts in order to get this running in JBoss.

    ReplyDelete
    Replies
    1. Hi Shameer,
      I implemented this example. The environment is
      Tomcat 6.0, Eclipse Europa IDE, Server configured in the IDE itself. I made the application run in Eclipse Alt+Shift+X, R
      I ended up with the below error.
      HTTP STATUS 405-
      The specified HTTP method is not allowed for the requested resource.
      Please help me to resolve this. I don't see any error in the server console.

      Delete
  77. Hi Shameer,

    Thanks for the post, it's been very helpful.
    Can you give some example also reg. SOAP envelopes, I mean if I want to send/receive messages in SOAP Env, what should I change/add to your example?? I'm looking for good examples but couldn't find ...

    Regards

    ReplyDelete
  78. Hi Anjiz,
    I have the same issue. Works with jboss4.0.2 but not in Jboss5.0
    Could please let me know what the fix is? In jboss5.0 i get no response.

    ReplyDelete
  79. Hi Shameer,

    Do you have an idea what causing below exception???

    org.springframework.ws.client.WebServiceTransportException: Not Found [404]
    org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:626)
    org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:550)


    I tried to search in the net but could not able to find possible solution.

    below is the content of my XSD.








    below is the content of my endpoint.

    @PayloadRoot(localPart = "eightBallRequest", namespace = "http://acompany.com/it/enterprise/DEPT/EightBall/v1")

    Please help...Thanks

    ReplyDelete
  80. Hi Shameer,
    Thanks a lot for this post. Very useful and easy to understand.

    ReplyDelete
  81. Hi Shameer

    Good post, it explained much and gave me the steer I needed to create my first ws-service, in case anyone is interested I have posted below an "No XML" configuration in line with Spring 3.2

    package com.live.order.service.configuration;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.Resource;
    import org.springframework.core.io.ResourceLoader;
    import org.springframework.oxm.Marshaller;
    import org.springframework.oxm.jaxb.Jaxb2Marshaller;
    import org.springframework.ws.server.EndpointInterceptor;
    import org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor;
    import org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor;
    import org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping;
    import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
    import org.springframework.xml.xsd.SimpleXsdSchema;

    import com.live.order.service.OrderServiceImpl;
    import com.live.order.service.endpoint.OrderServicePayloadRootAnnotationEndPoint;

    @Configuration
    public class Spring32Configuation {

    protected Log logger = LogFactory.getLog(getClass());

    @Bean(name="endpointMapping")
    public PayloadRootAnnotationMethodEndpointMapping annotationMethodEndpointMapping() {
    logger.info("instatiating : endpointMapping");
    PayloadRootAnnotationMethodEndpointMapping mapping = new PayloadRootAnnotationMethodEndpointMapping();
    mapping.setInterceptors(new EndpointInterceptor[] {new PayloadLoggingInterceptor()});
    return mapping;
    }

    @Bean(name="endpointAdapter")
    public MarshallingPayloadMethodProcessor endpointAdapter(Marshaller marshaller) {
    logger.info("instatiating : orderServiceSchema");
    return new MarshallingPayloadMethodProcessor(marshaller);
    }

    @Bean(name="marshaller")
    public Marshaller marshaller() {
    logger.info("instatiating : marshaller");
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setContextPath("com.live.order.domain");
    return marshaller;
    }

    @Bean(name="orderServiceEndpoint")
    public OrderServicePayloadRootAnnotationEndPoint orderServiceEndpoint() {
    logger.info("instatiating : orderServiceEndpoint");
    return new OrderServicePayloadRootAnnotationEndPoint(new OrderServiceImpl());
    }

    @Bean(name="orderServiceSchema")
    public SimpleXsdSchema orderServiceSchema(ResourceLoader resourceLoader) throws Exception {
    Resource resource = resourceLoader.getResource("/WEB-INF/conf/schema/OrderService.xsd");
    logger.info("instatiating : orderServiceSchema to process : " + resource.getURI().toASCIIString());
    return new SimpleXsdSchema(resource);
    }

    @Bean(name="OrderService")
    public DefaultWsdl11Definition wsdl11Definition(SimpleXsdSchema orderServiceSchema) {
    logger.info("instatiating : OrderService");
    DefaultWsdl11Definition wsdl = new DefaultWsdl11Definition();
    wsdl.setSchema(orderServiceSchema);
    wsdl.setPortTypeName("OrderService");
    wsdl.setLocationUri("http://www.liverestaurant.com/OrderService/");
    wsdl.setTargetNamespace("http://www.liverestaurant.com/OrderService/schema");
    return wsdl;
    }
    }

    Hope this helps

    ReplyDelete
  82. Thanks Chris,

    Wonderful code and a appreciate the contribution. Good way to go.

    Thanks Again,
    Shameer

    ReplyDelete
  83. Load Service
    Very Nice Post.
    Very Good information.
    Thanks for sharing with us.

    ReplyDelete
  84. Hi Shameer,

    Thank you very much for providing a great examples in this blog.Really it is the best blog for learning web services.Can you suggest few sites which are being used in real world applications to consume web services.I tried webservices.seekda.com but it is not connecting i dont know why they shutdown this server.It would be a great help for me if you provide some web services sites.

    Thank you,
    Sanjay

    ReplyDelete
  85. hi, im learning how to create java web services and ur tutorial is helpful. however, how do i deploy the webservice to tomcat? do i need to build with Ant? where should i deploy in tomcat ?

    ReplyDelete
    Replies
    1. hey shameer, i managed to deploy it on tomcat via eclipse. but im getting the following error:

      HTTP Status 500 - Error instantiating servlet class org.springframework.ws.transport.http.MessageDispatcherServlet

      type Exception report

      message Error instantiating servlet class org.springframework.ws.transport.http.MessageDispatcherServlet

      description The server encountered an internal error that prevented it from fulfilling this request.

      exception

      javax.servlet.ServletException: Error instantiating servlet class org.springframework.ws.transport.http.MessageDispatcherServlet
      org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
      org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
      org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
      org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
      org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
      org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
      org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
      java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
      java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
      java.lang.Thread.run(Thread.java:680)
      root cause

      java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
      org.springframework.web.servlet.HttpServletBean.(HttpServletBean.java:85)
      org.springframework.web.servlet.FrameworkServlet.(FrameworkServlet.java:221)
      org.springframework.ws.transport.http.MessageDispatcherServlet.(MessageDispatcherServlet.java:124)
      sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
      sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
      java.lang.reflect.Constructor.newInstance(Constructor.java:513)
      java.lang.Class.newInstance0(Class.java:357)
      java.lang.Class.newInstance(Class.java:310)
      org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
      org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
      org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
      org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
      org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
      org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
      org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
      java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
      java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
      java.lang.Thread.run(Thread.java:680)

      Delete
    2. this is another part of the error. too long, exceeded word count:

      root cause

      java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
      org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1713)
      org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1558)
      org.springframework.web.servlet.HttpServletBean.(HttpServletBean.java:85)
      org.springframework.web.servlet.FrameworkServlet.(FrameworkServlet.java:221)
      org.springframework.ws.transport.http.MessageDispatcherServlet.(MessageDispatcherServlet.java:124)
      sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
      sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
      java.lang.reflect.Constructor.newInstance(Constructor.java:513)
      java.lang.Class.newInstance0(Class.java:357)
      java.lang.Class.newInstance(Class.java:310)
      org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
      org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
      org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
      org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
      org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
      org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
      org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
      java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
      java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
      java.lang.Thread.run(Thread.java:680)

      Delete
    3. my list of jar files in lib folder are:
      commons-lang3-3.1.jar
      commons-logging-1.1.2-javadoc.jar
      commons-logging-1.1.2-sources.jar
      commons-logging-1.1.2-test-sources.jar
      commons-logging-1.1.2-tests.jar
      commons-logging-1.1.2.jar
      commons-logging-adapters-1.1.2.jar
      commons-logging-api-1.1.2.jar
      commons-logging-tests.jar
      log4j-1.2.17.jar
      pdfbox-app-1.8.1.jar
      spring-aop-3.2.2.RELEASE-javadoc.jar
      spring-aop-3.2.2.RELEASE-sources.jar
      spring-aop-3.2.2.RELEASE.jar
      spring-aspects-3.2.2.RELEASE-javadoc.jar
      spring-aspects-3.2.2.RELEASE-sources.jar
      spring-aspects-3.2.2.RELEASE.jar
      spring-beans-3.2.2.RELEASE-javadoc.jar
      spring-beans-3.2.2.RELEASE-sources.jar
      spring-beans-3.2.2.RELEASE.jar
      spring-build-src-3.2.2.RELEASE.jar
      spring-context-3.2.2.RELEASE-javadoc.jar
      spring-context-3.2.2.RELEASE-sources.jar
      spring-context-3.2.2.RELEASE.jar
      spring-context-support-3.2.2.RELEASE-javadoc.jar
      spring-context-support-3.2.2.RELEASE-sources.jar
      spring-context-support-3.2.2.RELEASE.jar
      spring-core-3.2.2.RELEASE-javadoc.jar
      spring-core-3.2.2.RELEASE-sources.jar
      spring-core-3.2.2.RELEASE.jar
      spring-expression-3.2.2.RELEASE-javadoc.jar
      spring-expression-3.2.2.RELEASE-sources.jar
      spring-expression-3.2.2.RELEASE.jar
      spring-instrument-3.2.2.RELEASE-javadoc.jar
      spring-instrument-3.2.2.RELEASE-sources.jar
      spring-instrument-3.2.2.RELEASE.jar
      spring-instrument-tomcat-3.2.2.RELEASE-javadoc.jar
      spring-instrument-tomcat-3.2.2.RELEASE-sources.jar
      spring-instrument-tomcat-3.2.2.RELEASE.jar
      spring-jdbc-3.2.2.RELEASE-javadoc.jar
      spring-jdbc-3.2.2.RELEASE-sources.jar
      spring-jdbc-3.2.2.RELEASE.jar
      spring-jms-3.2.2.RELEASE-javadoc.jar
      spring-jms-3.2.2.RELEASE-sources.jar
      spring-jms-3.2.2.RELEASE.jar
      spring-orm-3.2.2.RELEASE-javadoc.jar
      spring-orm-3.2.2.RELEASE-sources.jar
      spring-orm-3.2.2.RELEASE.jar
      spring-oxm-3.2.2.RELEASE-javadoc.jar
      spring-oxm-3.2.2.RELEASE-sources.jar
      spring-oxm-3.2.2.RELEASE.jar
      spring-struts-3.2.2.RELEASE-javadoc.jar
      spring-struts-3.2.2.RELEASE-sources.jar
      spring-struts-3.2.2.RELEASE.jar
      spring-test-3.2.2.RELEASE-javadoc.jar
      spring-test-3.2.2.RELEASE-sources.jar
      spring-test-3.2.2.RELEASE.jar
      spring-tx-3.2.2.RELEASE-javadoc.jar
      spring-tx-3.2.2.RELEASE-sources.jar
      spring-tx-3.2.2.RELEASE.jar
      spring-web-3.2.2.RELEASE-javadoc.jar
      spring-web-3.2.2.RELEASE-sources.jar
      spring-web-3.2.2.RELEASE.jar
      spring-webmvc-3.2.2.RELEASE-javadoc.jar
      spring-webmvc-3.2.2.RELEASE-sources.jar
      spring-webmvc-3.2.2.RELEASE.jar
      spring-webmvc-portlet-3.2.2.RELEASE-javadoc.jar
      spring-webmvc-portlet-3.2.2.RELEASE-sources.jar
      spring-webmvc-portlet-3.2.2.RELEASE.jar
      spring-ws-2.1.3.RELEASE-all.jar
      spring-ws-2.1.3.RELEASE-sources.jar
      spring-ws-core-2.1.3.RELEASE.jar
      spring-ws-security-2.1.3.RELEASE.jar
      spring-ws-support-2.1.3.RELEASE.jar
      spring-xml-2.1.3.RELEASE.jar

      Delete
    4. hey shameer, i managed to get wsdl displayed on http://localhost:8080/LiveRestaurant/spring-ws/OrderService.wsdl. apparently there were alot of other libs to download there were not included in spring-ws or core such as wsdl4j-1_6_3 and much more.

      Delete