Version 1
    Since 3.0.2 (Native)

    JBossWS-Native comes with support for both WS-RM 1.0 and WS-RM 1.1. In this sample we will show how to create client and endpoint communicating each other using WS-RM 1.1 The sample uses WS-Policy specification to configure WS-RM.

    Creating the WS-RM based service and client is very simple. User needs to create regular JAX-WS service and client first. The last step is to configure WSRM.

     

    The service

    We will start with the following endpoint implementation (bottom-up approach):

    package org.jboss.test.ws.jaxws.samples.wsrm.service;
    
    import javax.jws.Oneway;
    import javax.jws.WebMethod;
    import javax.jws.WebService;
    
    @WebService
    (
       name = "SimpleService",
       serviceName = "SimpleService",
       wsdlLocation = "WEB-INF/wsdl/SimpleService.wsdl"
       targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsrm"
    )
    public class SimpleServiceImpl
    {
       @Oneway
       @WebMethod
       public void ping()
       {
          System.out.println("ping()");
       }
    
       @WebMethod
       public String echo(String s)
       {
          System.out.println("echo(" + s + ")");
          return s;
       }
    }
    

    Let's say that compiled endpoint class is in directory /home/username/wsrm/native/classes. Our next step is to generate JAX-WS artifacts and WSDL.

     

    Generating WSDL and JAX-WS Endpoint Artifacts

    We will use wsprovide commandline tool to generate WSDL and JAX-WS artifacts. Here's the command:

    cd $JBOSS_HOME/bin
    
    ./wsprovide.sh --keep --wsdl \
       --classpath=/home/username/wsrm/native/classes \
       --output=/home/username/wsrm/native/wsprovide/generated/classes \
       --resource=/home/username/wsrm/native/wsprovide/generated/wsdl \
       --source=/home/username/wsrm/native/wsprovide/generated/src \
       org.jboss.test.ws.jaxws.samples.wsrm.service.SimpleServiceImpl
    

    The above command generates the following artifacts:

    # compiled classes
    ls /home/username/wsrm/native/wsprovide/generated/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/
    Echo.class  EchoResponse.class  Ping.class
    
    # java sources
    ls /home/username/wsrm/native/wsprovide/generated/src/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/
    Echo.java EchoResponse.java Ping.java
    
    # contract artifacts
    ls /home/username/wsrm/native/wsprovide/generated/wsdl/
    SimpleService.wsdl
    

    All aforementioned generated artifacts will be part of endpoint archive. The endpoint archive consists of the following files:

    jar -tvf jaxws-samples-wsrm.war 
         0 Tue Apr 15 19:06:14 CEST 2008 META-INF/
       106 Tue Apr 15 19:06:12 CEST 2008 META-INF/MANIFEST.MF
         0 Tue Apr 15 19:06:14 CEST 2008 WEB-INF/
       591 Tue Apr 15 19:05:42 CEST 2008 WEB-INF/web.xml
         0 Tue Apr 15 19:06:14 CEST 2008 WEB-INF/classes/
         0 Tue Apr 15 19:04:50 CEST 2008 WEB-INF/classes/org/
         0 Tue Apr 15 19:04:50 CEST 2008 WEB-INF/classes/org/jboss/
         0 Tue Apr 15 19:04:50 CEST 2008 WEB-INF/classes/org/jboss/test/
         0 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/
         0 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/
         0 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
         0 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/
         0 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/
         0 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/
      1385 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/SimpleServiceImpl.class
       995 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/Echo.class
      1043 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/EchoResponse.class
       679 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/Ping.class
         0 Tue Apr 15 19:06:14 CEST 2008 WEB-INF/wsdl/
      2934 Tue Apr 15 19:05:36 CEST 2008 WEB-INF/wsdl/SimpleService.wsdl
    

    The content of web.xml file is:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app
       version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
       <servlet>
          <servlet-name>SimpleService</servlet-name>
          <servlet-class>org.jboss.test.ws.jaxws.samples.wsrm.service.SimpleServiceImpl</servlet-class>
       </servlet>
       <servlet-mapping>
          <servlet-name>SimpleService</servlet-name>
          <url-pattern>/*</url-pattern>
       </servlet-mapping>
    </web-app>

    Generating JAX-WS Client Artifacts

    Before we will write regular JAX-WS client we need to generate client artifacts from WSDL. Here's the command to achieve that:

    cd $JBOSS_HOME
    
    ./wsconsume.sh --keep \
       --package=org.jboss.test.ws.jaxws.samples.wsrm.generated \
       --output=/home/username/wsrm/native/wsconsume/generated/classes \
       --source=/home/username/wsrm/native/wsconsume/generated/src \
       /home/username/wsrm/native/wsprovide/generated/wsdl/SimpleService.wsdl
    

    The above command generates the following artifacts:

    # compiled classes
    ls /home/username/wsrm/native/wsconsume/generated/classes/org/jboss/test/ws/jaxws/samples/wsrm/generated/
    Echo.class  EchoResponse.class  ObjectFactory.class  package-info.class  Ping.class  SimpleService.class  SimpleService_Service.class
    
    # java sources
    ls /home/username/wsrm/native/wsconsume/generated/src/org/jboss/test/ws/jaxws/samples/wsrm/generated/
    Echo.java  EchoResponse.java  ObjectFactory.java  package-info.java  Ping.java  SimpleService.java  SimpleService_Service.java
    

    Now the last step is to write the regular JAX-WS client using generated artifacts.

     

    Writing Regular JAX-WS Client

    The following is the regular JAX-WS client using generated artifacts:

    package org.jboss.test.ws.jaxws.samples.wsrm.client;
    
    import java.net.URL;
    import javax.xml.namespace.QName;
    import javax.xml.ws.Service;
    import org.jboss.test.ws.jaxws.samples.wsrm.generated.SimpleService;
    
    public final class SimpleServiceTestCase
    {
    
       private static final String serviceURL = "http://localhost:8080/jaxws-samples-wsrm/SimpleService";
       
       public static void main(String[] args) throws Exception
       {
          QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wsrm", "SimpleService");
          URL wsdlURL = new URL(serviceURL + "?wsdl");
          Service service = Service.create(wsdlURL, serviceName);
          SimpleService proxy = (SimpleService)service.getPort(SimpleService.class);
          
          proxy.ping(); // one way call
          proxy.echo("Hello World!"); // request responce call
       }
       
    }
    

    Now we have both endpoint and client implementation but without WSRM in place. Our next goal is to turn on WS-RM feature.

     

    Turning on WS-RM 1.1

    In order to turn on WS-RM in JBossWS-Native four steps are necessary:

    • extend WSDL with WS-Policy containing both WSRM and WS-Addressing policy
    • provide both endpoint and client jaxws configuration files
    • update endpoint implementation to use endpoint jaxws file
    • update client to use client jaxws file and close the sequence

     

     

    Extending WSDL Using WS-Policy

    To activate WSRM we need to extend WSDL with WSRM and addressing policy. Here is how it looks like:

    <?xml version="1.0" encoding="UTF-8"?>
    <definitions name='SimpleService' targetNamespace='http://www.jboss.org/jbossws/ws-extensions/wsrm' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://www.jboss.org/jbossws/ws-extensions/wsrm' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
      <!-- - - - - - - - - - - - - - - - - - - - - - - - - - -->
      <!-- Created WS-Policy with WSRM addressing assertions -->
      <!-- - - - - - - - - - - - - - - - - - - - - - - - - - -->
      <wsp:UsingPolicy/>
      <wsp:Policy
        wsu:Id="wsrm11policy"
        xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsp:All>
          <wsp:ExactlyOne>
             <wsp:All>
                <ns1:RMAssertion xmlns:ns1="http://docs.oasis-open.org/ws-rx/wsrmp/200702"/>
                <ns2:UsingAddressing xmlns:ns2="http://www.w3.org/2006/05/addressing/wsdl"/>
             </wsp:All>
          </wsp:ExactlyOne>
        </wsp:All>
      </wsp:Policy>
     <types>
      <xs:schema targetNamespace='http://www.jboss.org/jbossws/ws-extensions/wsrm' version='1.0' xmlns:tns='http://www.jboss.org/jbossws/ws-extensions/wsrm' xmlns:xs='http://www.w3.org/2001/XMLSchema'>
       <xs:element name='echo' type='tns:echo'/>
       <xs:element name='echoResponse' type='tns:echoResponse'/>
       <xs:element name='ping' type='tns:ping'/>
       <xs:complexType name='ping'>
        <xs:sequence/>
       </xs:complexType>
       <xs:complexType name='echo'>
        <xs:sequence>
         <xs:element minOccurs='0' name='arg0' type='xs:string'/>
        </xs:sequence>
       </xs:complexType>
       <xs:complexType name='echoResponse'>
        <xs:sequence>
         <xs:element minOccurs='0' name='return' type='xs:string'/>
        </xs:sequence>
       </xs:complexType>
      </xs:schema>
     </types>
     <message name='SimpleService_echo'>
      <part element='tns:echo' name='echo'/>
     </message>
     <message name='SimpleService_echoResponse'>
      <part element='tns:echoResponse' name='echoResponse'/>
     </message>
     <message name='SimpleService_ping'>
      <part element='tns:ping' name='ping'/>
     </message>
     <portType name='SimpleService'>
      <operation name='echo' parameterOrder='echo'>
       <input message='tns:SimpleService_echo'/>
       <output message='tns:SimpleService_echoResponse'/>
      </operation>
      <operation name='ping'>
       <input message='tns:SimpleService_ping'/>
      </operation>
     </portType>
     <binding name='SimpleServiceBinding' type='tns:SimpleService'>
      <!-- - - - - - - - - - - - - - - - - - - - -->
      <!-- Associated WS-Policy with the binding -->
      <!-- - - - - - - - - - - - - - - - - - - - -->
      <wsp:PolicyReference URI="#wsrm11policy"/>
      <soap:binding style='document' transport='http://schemas.xmlsoap.org/soap/http'/>
      <operation name='echo'>
       <soap:operation soapAction=''/>
       <input>
        <soap:body use='literal'/>
       </input>
       <output>
        <soap:body use='literal'/>
       </output>
      </operation>
      <operation name='ping'>
       <soap:operation soapAction=''/>
       <input>
        <soap:body use='literal'/>
       </input>
      </operation>
     </binding>
     <service name='SimpleService'>
      <port binding='tns:SimpleServiceBinding' name='SimpleServicePort'>
       <soap:address location='REPLACE_WITH_ACTUAL_URL'/>
      </port>
     </service>
    </definitions>
    

    We added wsp:UsingPolicy, wsp:Policy and wsp:PolicyReference elements to WSDL.

     

    Providing Endpoint and Client JAX-WS Configuration Files

    In order to activate WSRM in JBossWS-Native integration user have to provide both endpoint and client jaxws configuration files containing both addressing and WSRM handlers in the processing chain.

    The endpoint jaxws configuration file, in our case we will call it wsrm-jaxws-endpoint-config.xml has the following content:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <jaxws-config
      xmlns="urn:jboss:jaxws-config:2.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:javaee="http://java.sun.com/xml/ns/javaee"
      xsi:schemaLocation="urn:jboss:jaxws-config:2.0 jaxws-config_2_0.xsd">
    
      <endpoint-config>
        <config-name>Standard WSRM Endpoint</config-name>
        <post-handler-chains>
          <javaee:handler-chain>
            <javaee:protocol-bindings>##SOAP11_HTTP</javaee:protocol-bindings>
            <javaee:handler>
              <javaee:handler-name>WSAddressing Handler</javaee:handler-name>
              <javaee:handler-class>org.jboss.ws.extensions.addressing.jaxws.WSAddressingServerHandler</javaee:handler-class>
            </javaee:handler>
            <javaee:handler>
              <javaee:handler-name>WSRM Handler</javaee:handler-name>
              <javaee:handler-class>org.jboss.ws.extensions.wsrm.jaxws.RMServerHandler</javaee:handler-class>
            </javaee:handler>
          </javaee:handler-chain>
        </post-handler-chains>
      </endpoint-config>
    
    </jaxws-config>
    

    The client jaxws configuration file, in our case we will call it wsrm-jaxws-client-config.xml has the following content:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <jaxws-config
      xmlns="urn:jboss:jaxws-config:2.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:javaee="http://java.sun.com/xml/ns/javaee"
      xsi:schemaLocation="urn:jboss:jaxws-config:2.0 jaxws-config_2_0.xsd">
    
      <client-config>
        <config-name>Standard Anonymous WSRM Client</config-name>
        <reliable-messaging>
          <message-retransmission attempts="50" interval="10" timeout="10"/>
        </reliable-messaging>     
        <post-handler-chains>
          <javaee:handler-chain>
            <javaee:protocol-bindings>##SOAP11_HTTP</javaee:protocol-bindings>
            <javaee:handler>
              <javaee:handler-name>WSAddressing Handler</javaee:handler-name>
              <javaee:handler-class>org.jboss.ws.extensions.addressing.jaxws.WSAddressingClientHandler</javaee:handler-class>
            </javaee:handler>
            <javaee:handler>
              <javaee:handler-name>WSRM Handler</javaee:handler-name>
              <javaee:handler-class>org.jboss.ws.extensions.wsrm.jaxws.RMClientHandler</javaee:handler-class>
            </javaee:handler>
          </javaee:handler-chain>
        </post-handler-chains>
      </client-config>
    
    </jaxws-config>
    

    Note

    Both client and endpoint jaxws configuration files are available in native WSRM tests. Users can copy them from there.

    The next step is to include jaxws endpoint configuration file in META-INF directory of the endpoint archive.

    jar -tvf jaxws-samples-wsrm.war 
         0 Tue Apr 15 19:06:14 CEST 2008 META-INF/
       106 Tue Apr 15 19:06:12 CEST 2008 META-INF/MANIFEST.MF
         0 Tue Apr 15 19:06:14 CEST 2008 WEB-INF/
       591 Tue Apr 15 19:05:42 CEST 2008 WEB-INF/web.xml
         0 Tue Apr 15 19:06:14 CEST 2008 WEB-INF/classes/
         0 Tue Apr 15 19:04:50 CEST 2008 WEB-INF/classes/org/
         0 Tue Apr 15 19:04:50 CEST 2008 WEB-INF/classes/org/jboss/
         0 Tue Apr 15 19:04:50 CEST 2008 WEB-INF/classes/org/jboss/test/
         0 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/
         0 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/
         0 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
         0 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/
         0 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/
         0 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/
      1385 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/SimpleServiceImpl.class
       995 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/Echo.class
      1043 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/EchoResponse.class
       679 Tue Apr 15 19:05:10 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/Ping.class
         0 Tue Apr 15 19:06:14 CEST 2008 WEB-INF/wsdl/
      2934 Tue Apr 15 19:05:36 CEST 2008 WEB-INF/wsdl/SimpleService.wsdl
      2033 Tue Apr 15 19:05:52 CEST 2008 META-INF/wsrm-jaxws-endpoint-config.xml
    

    What about client side, the client jaxws configuration file must be available on the client classpath, in our case it will be available as META-INF/wsrm-jaxws-client-config.xml resource.

     

    Updating Endpoint Code to Reference Custom JAX-WS Config File

    Now we need to update endpoint implementation to reference custom JAX-WS configuration file. Here's the updated endpoint code:

    package org.jboss.test.ws.jaxws.samples.wsrm.service;
    
    import javax.jws.Oneway;
    import javax.jws.WebMethod;
    import javax.jws.WebService;
    
    import org.jboss.ws.annotation.EndpointConfig;
    
    @WebService
    (
       name = "SimpleService",
       serviceName = "SimpleService",
       wsdlLocation = "WEB-INF/wsdl/SimpleService.wsdl",
       targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsrm"
    )
    @EndpointConfig
    (
       configFile = "META-INF/wsrm-jaxws-endpoint-config.xml",
       configName = "Standard WSRM Endpoint"
    )
    public class SimpleServiceImpl
    {
       @Oneway
       @WebMethod
       public void ping()
       {
          System.out.println("ping()");
       }
    
       @WebMethod
       public String echo(String s)
       {
          System.out.println("echo(" + s + ")");
          return s;
       }
    }
    

    As users can see we added JBossWS proprietary EndpointConfig annotation to reference the endpoint config.

     

    Updating Client Code to Reference Custom JAX-WS Config File and Close the Sequence

    Now we need to update client implementation as well to reference custom JAX-WS configuration file. We will also add the call to close the created sequence there. Here's the updated client code:

    package org.jboss.test.ws.jaxws.samples.wsrm.client;
    
    import java.net.URL;
    import javax.xml.namespace.QName;
    import javax.xml.ws.Service;
    import org.jboss.ws.core.StubExt;
    import org.jboss.ws.extensions.wsrm.api.RMProvider;
    import org.jboss.test.ws.jaxws.samples.wsrm.generated.SimpleService;
    
    public final class SimpleServiceTestCase
    {
    
       private static final String serviceURL = "http://localhost:8080/jaxws-samples-wsrm/SimpleService";
       
       public static void main(String[] args) throws Exception
       {
          QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wsrm", "SimpleService");
          URL wsdlURL = new URL(serviceURL + "?wsdl");
          Service service = Service.create(wsdlURL, serviceName);
          SimpleService proxy = (SimpleService)service.getPort(SimpleService.class);
          ((StubExt)proxy).setConfigName("Standard Anonymous WSRM Client", "META-INF/wsrm-jaxws-client-config.xml");
          
          proxy.ping(); // one way call
          proxy.echo("Hello World!"); // request responce call
          ((RMProvider)proxy).closeSequence();
       }
       
    }
    

    And that's all. Now user have both endpoint and client using WS-RM 1.1 when communicating each other.

     

    Sample Sources

    All sources from this tutorial are part of JBossWS-Native distribution.