JBossWS - Native User Guide


Secure endpoints

Securing an endpoint requires you to set the authentication configuration.

Then you might want to secure the communication between service provider and consumer. This can be done at different levels:


JBossWS Native WS-* extensions

WS-Addressing

This section describes how WS-Addressing can be used to provide a stateful service endpoint.

Specifications

WS-Addressing is defined by a combination of the following specifications from the W3C Candidate Recommendation 17 August 2005. The WS-Addressing API is standardized by JSR-261 - Java API for XML Web Services Addressing

Addressing Endpoint

The following endpoint implementation has a set of operation for a typical stateful shopping chart application.

    @WebService(name = "StatefulEndpoint", targetNamespace = "http://org.jboss.ws/samples/wsaddressing", serviceName = "TestService")
    @EndpointConfig(configName = "Standard WSAddressing Endpoint")
    @HandlerChain(file = "WEB-INF/jaxws-handlers.xml")
    @SOAPBinding(style = SOAPBinding.Style.RPC)
    public class StatefulEndpointImpl implements StatefulEndpoint, ServiceLifecycle
    {
       @WebMethod
       public void addItem(String item)
       { ... }
   
       @WebMethod
       public void checkout()
       { ... }
   
       @WebMethod
       public String getItems()
       { ... }
    }

It uses the Standard WSAddressing Endpoint to enable the server side addressing handler. It processes the incomming WS-Addressing header elements and provides access to them through the JSR-261 API.

The endpoint handler chain

<handler-chains 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 javaee_web_services_1_2.xsd">


  <handler-chain>
    <protocol-bindings>##SOAP11_HTTP</protocol-bindings>
    <handler>
      <handler-name>Application Server Handler</handler-name>
      <handler-class>org.jboss.test.ws.jaxws.samples.wsaddressing.ServerHandler</handler-class>
    </handler>
  </handler-chain>

</handler-chains>

defines an application specific hander that assignes/processes stateful client ids.

Addressing Client

On the client side there are similar handlers that does the reverse. It uses the JSR-261 API to add WS-Addressing header elements including the clientid association.


   The client sets a custom handler chain in the binding

         Service service = Service.create(wsdlURL, serviceName);
         port1 = (StatefulEndpoint)service.getPort(StatefulEndpoint.class);
         BindingProvider bindingProvider = (BindingProvider)port1;

         List<Handler> customHandlerChain = new ArrayList<Handler>();
         customHandlerChain.add(new ClientHandler());
         customHandlerChain.add(new WSAddressingClientHandler());
         bindingProvider.getBinding().setHandlerChain(customHandlerChain);

The WSAddressingClientHandler is provided by JBossWS and reads/writes the addressing properties and puts then into the message context.

A client connecting to the stateful endpoint

    public class AddressingStatefulTestCase extends JBossWSTest
    {
       public void testAddItem() throws Exception
       {
          port1.addItem("Ice Cream");
          port1.addItem("Ferrari");
         
          port2.addItem("Mars Bar");
          port2.addItem("Porsche");
       }
      
       public void testGetItems() throws Exception
       {
          String items1 = port1.getItems();
          assertEquals("[Ice Cream, Ferrari]", items1);
         
          String items2 = port2.getItems();
          assertEquals("[Mars Bar, Porsche]", items2);
       }
    }

SOAP message exchange

Below you see the SOAP messages that are being exchanged.

<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
<env:Header xmlns:wsa='http://schemas.xmlsoap.org/ws/2004/08/addressing'>
  <wsa:To>uri:jbossws-samples-wsaddr/TestService</wsa:To>
  <wsa:Action>http://org.jboss.ws/addressing/stateful/action</wsa:Action>
  <wsa:ReferenceParameters>
   <ns1:clientid xmlns:ns1='http://somens'>clientid-1</ns1:clientid>
  </wsa:ReferenceParameters>
</env:Header>
<env:Body>
  <ns1:addItem xmlns:ns1='http://org.jboss.ws/samples/wsaddr'>
   <String_1>Ice Cream</String_1>
  </ns1:addItem>
</env:Body>
</env:Envelope>
   
<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
<env:Header xmlns:wsa='http://schemas.xmlsoap.org/ws/2004/08/addressing'>
  <wsa:To>http://www.w3.org/2005/08/addressing/anonymous</wsa:To>
  <wsa:Action>http://org.jboss.ws/addressing/stateful/actionReply</wsa:Action>
  <ns1:clientid xmlns:ns1='http://somens'>clientid-1</ns1:clientid>
</env:Header>
<env:Body>
  <ns1:addItemResponse xmlns:ns1='http://org.jboss.ws/samples/wsaddr'/>
</env:Body>
</env:Envelope>
       
    ...
   
<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
  <env:Header xmlns:wsa='http://schemas.xmlsoap.org/ws/2004/08/addressing'>
    <wsa:To>uri:jbossws-samples-wsaddr/TestService</wsa:To>
    <wsa:Action>http://org.jboss.ws/addressing/stateful/action</wsa:Action>
    <wsa:ReferenceParameters>
      <ns1:clientid xmlns:ns1='http://somens'>clientid-1</ns1:clientid>
    </wsa:ReferenceParameters>
  </env:Header>
  <env:Body>
    <ns1:getItems xmlns:ns1='http://org.jboss.ws/samples/wsaddr'/>
  </env:Body>
</env:Envelope>
   
<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
  <env:Header xmlns:wsa='http://schemas.xmlsoap.org/ws/2004/08/addressing'>
    <wsa:To>http://www.w3.org/2005/08/addressing/anonymous</wsa:To>
    <wsa:Action>http://org.jboss.ws/addressing/stateful/actionReply</wsa:Action>
    <ns1:clientid xmlns:ns1='http://somens'>clientid-1</ns1:clientid>
  </env:Header>
  <env:Body>
    <ns1:getItemsResponse xmlns:ns1='http://org.jboss.ws/samples/wsaddr'>
      <result>[Ice Cream, Ferrari]</result>
    </ns1:getItemsResponse>
  </env:Body>
</env:Envelope>

Tutorial

For further details please take a look at our WS-Addressing Tutorial.

 

WS-BPEL

WS-BPEL is not supported with JAX-WS, please refer to JAX-RPC User Guide#WS-BPEL.

 

WS-Eventing

WS-Eventing specifies a set of operations that allow an event consumer to register (subscribe) with an event producer (source) to receive events (notifications) in an asynchronous fashion.

Specifications

WS-Eventing is defined by the combination of the following specifications:

The following section will introduce the main eventing actors and their responsiblities.

Note

The original eventing specification builds upon WS-Addressing 2004/08. JBossWS however decided to stick to the latest version, which is the W3C candidate release.

 

Collaboration


Eventing collaboration
  1. An event sink (web service client) sends a subscription request to the event source endpoint. This includes the event sink endpoint address where notifications should delivered. Upon successful subscription the sink receives a leased subscription ID that can be used to identify the client in subsequent requests.
  2. A successfully registered event sink directs management requests (Renew, GetStatus, Unsubscribe) to the subscription manager endpoint using the previously received subscription ID. The subscription manager endpoint address was returned as part of the subscription response in the first place.
  3. The actual event source (application) emits notification messages through the JBossWS-Eventing module. JBossWS-Eventing dispatches the notification to any subscriber endpoint that is registered with a particular event source.s
  4. Besides notifications JBossWS-Eventing may emit lifecycle events at any time, i.e. to inform an event sink that a subscription was canceled. This can be the case when the subscription expired or the event source was undeployed.

It is the users responsibility to supply the web service endpoints (EventSourceEndpoint, SubscriptionManagerEndpoint) that are required for a complete event source deployment. Fortunatly JBossWS-Eventing already ships with a implementation that can be used right away. All that's left todo is packaging of standard JSR-109 deployment archive that includes the event source specific WSDL and points to the JBossWS-Eventing endpoint implementations.

The relevant steps are:

  • Create a custom WSDL that describes your event source, in respect to the notification schema (1) and the fact that is actually contains an event source port (2)
  • Use the JBossWS SEI (3) and endpoint (4) implementations (web.xml).

 

Setup an event source endpoint

With JAX-WS the event source setup has actually become quite easy. All you need to do is  to subclass your endpoint implementation from AbstractEventSourceEndpoint and a subscription manager  from AbstractSubscriptionManagerEndpoint and finally point that implementation to a event source specific WSDL.

package org.jboss.test.ws.jaxws.samples.wseventing;

import javax.jws.WebService;

import org.jboss.logging.Logger;
import org.jboss.ws.annotation.EndpointConfig;
import org.jboss.ws.extensions.eventing.jaxws.AbstractEventSourceEndpoint;

/**
* @author Heiko.Braun@jboss.org
* @version $Id$
* @since 18.01.2007
*/

@WebService(                                                                   (1)
   name = "EventSource",
   portName = "EventSourcePort",
   targetNamespace = "http://schemas.xmlsoap.org/ws/2004/08/eventing",
   wsdlLocation = "/WEB-INF/wsdl/sysmon.wsdl",                                 (2)
   endpointInterface = "org.jboss.ws.extensions.eventing.jaxws.EventSourceEndpoint")
@EndpointConfig(configName = "Standard WSAddressing Endpoint")                 (3)
public class SysmonRegistrationEndpoint extends AbstractEventSourceEndpoint {  (4)

   private static final Logger log = Logger.getLogger(SysmonRegistrationEndpoint.class);

   protected Logger getLogger()
   {
      return log;
   }
}

  1. Of course we need a @WebService annotation
  2. It's important to override the WSDL here
  3. You need to tell JBossWS that it requires WS-Addressing for this endpoint
  4. Subclass a predefined implementation that knows how to delegate to the actual eventing service implementation

The WSDL that describes an event source

Even though we are already using the annotation driven approach, JBossWS eventing still requires an event source specific WSDL.

The following excerpt shows the relevant WSDL details that describe an event source.

  <?xml version="1.0" encoding="UTF-8"?>

   <wsdl:definitions
      targetNamespace="http://www.jboss.org/sysmon"
      xmlns:tns="http://www.jboss.org/sysmon"
      xmlns:wse='http://schemas.xmlsoap.org/ws/2004/08/eventing'
      xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
      xmlns:wsa10='http://www.w3.org/2005/08/addressing'
      xmlns:xs='http://www.w3.org/2001/XMLSchema'
      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">


   <wsdl:import
(1)        namespace='http://schemas.xmlsoap.org/ws/2004/08/eventing'
           location='jbwse.wsdl' />


   <wsdl:types>

      <xs:schema targetNamespace='http://schemas.xmlsoap.org/ws/2004/08/eventing'>
(2)      <xs:include schemaLocation='jbwse.xsd'/>
      </xs:schema>

(3)   <xs:schema
            targetNamespace="http://www.jboss.org/sysmon"
            elementFormDefault="qualified"
            blockDefault="#all">

         <xs:element name="SystemStatus">
            <xs:complexType>
               <xs:sequence>
                  <xs:element name="Time " type="xs:dateTime"/>
                  <xs:element name="HostName" type="xs:string"/>
                  <xs:element name="HostAddress" type="xs:string"/>
                  <xs:element name="ActiveThreadCount" type="xs:int"/>
                  <xs:element name="FreeMemory" type="xs:string"/>
                  <xs:element name="MaxMemory" type="xs:string"/>
               </xs:sequence>
            </xs:complexType>
         </xs:element>
      </xs:schema>

   </wsdl:types>

   <wsdl:message name='SystemInfoMsg'>
      <wsdl:part name='body' element='tns:SystemStatus'/>
   </wsdl:message>

(4) <wsdl:portType name='SystemInfo' wse:EventSource='true'>
       <wsdl:operation name='SysmonOp'>
          <wsdl:output message='tns:SystemInfoMsg'/>
       </wsdl:operation>
    </wsdl:portType>

   <wsdl:binding name="SystemInfoBinding" type="tns:SystemInfo">
      <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="SysmonOp">
         <soap:operation soapAction=""/>
         <wsdl:output>
            <soap:body use="literal"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>

</wsdl:definitions>
  1. Import the default eventing WSDL, that includes service and port declarations.
  2. Include the default eventing Types
  3. Specifiy the notitification message schema.
  4. Declare a port type, attributed "wse:EventSource='true'" that points to your notification message schema.

Emitting notifications

JBossWS-Eventing registeres a event dispatcher within local JNDI tree that can be used to emit notifications from applications.

     java:/EventDispatcher

The event dispatcher interface:

           public interface EventDispatcher
           {
               void dispatch(URI eventSourceNS, Element payload);
           }

Example notification

(1)   URI eventSourceURI = new URI("http://http://www.jboss.org/sysmon/SystemInfo");
(2)   Element payload = DOMUtils.parse("SOME XML STRING");
      try
      {
         InitialContext iniCtx = getInitialContext();
(3)      EventDispatcher delegate = (EventDispatcher)
               iniCtx.lookup(EventingConstants.DISPATCHER_JNDI_NAME);
(4)      delegate.dispatch(eventSourceURI, payload);
      }
      catch (Exception e)
      {
         //
      }

  1. Address your event source correctly (TargetNamespace+PortTypeName)
  2. Create your payload
  3. Lookup dispatcher from JNDI
  4. Dispatch notification.

 

The SubscriptionManager MBean is the actual core component that drives the JBossWS-Eventing implementation. It can be accessed through the jmx-console.

            jboss.ws.eventing:service=SubscriptionManager

Management operations exist to monitor and maintain active subscritions and deployed event sources. The current implementation is backed by a ThreadPoolExecutor, that asynchronously delivers messages to event sink endpoints. It can be configured through the following attributes:

  • corePoolSize - average number of idle threads
  • maximumPoolSize - maximum number of threads
  • eventKeepAlive - keep alive before an undelivered event message is discarded.

 

 

WS-Security

WS-Security addresses message level security. It standardizes authorization, encryption, and digital signature processing of web services. Unlike transport security models, such as SSL, WS-Security applies security directly to the elements of the web service message. This increases the flexibility of your web services, by allowing any message model to be used (point to point, multi-hop relay, etc).

This chapter describes how to use WS-Security to sign and encrypt a simple SOAP message.

Specifications

WS-Security is defined by the combination of the following specifications:

Endpoint configuration

JBossWS uses handlers to identify ws-security encoded requests and invoke the security components to sign and encrypt messages. In order to enable security processing, the client and server side need to include a corresponding handler configuration. The preferred way is to reference a predefined JAX-WS_Endpoint_Configuration or JAX-WS_Client_Configuration respectively.

Note

You need to setup both the endpoint configuration and the WSSE declarations. That's two separate steps.

Server side WSSE declaration (jboss-wsse-server.xml)

In this example we configure both the client and the server to sign the message body. Both also require this from each other. So, if you remove either the client or the server security deployment descriptor, you will notice that the other party will throw a fault explaining that the message did not conform to the proper security requirements.

    <jboss-ws-security xmlns="http://www.jboss.com/ws-security/config" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.jboss.com/ws-security/config
                    http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">

  (1)  <key-store-file>WEB-INF/wsse.keystore</key-store-file>
  (2)  <key-store-password>jbossws</key-store-password>
  (3)  <trust-store-file>WEB-INF/wsse.truststore</trust-store-file>
  (4)  <trust-store-password>jbossws</trust-store-password>
  (5)  <config>
  (6)    <sign type="x509v3" alias="wsse"/>
  (7)    <requires>
  (8)      <signature/>
        </requires>
      </config>
    </jboss-ws-security>

 

  1. This specifies that the key store we wish to use is WEB-INF/wsse.keystore, which is located in our war file.
  2. This specifies that the store password is "jbossws". Password can be encypted using the {EXT} and {CLASS} commands. Please see samples for their usage.
  3. This specifies that the trust store we wish to use is WEB-INF/wsse.truststore, which is located in our war file.
  4. This specifies that the trust store password is also "jbossws". Password can be encrypted using the {EXT} and {CLASS} commands. Please see samples for their usage.
  5. Here we start our root config block. The root config block is the default configuration for all services in this war file.
  6. This means that the server must sign the message body of all responses. Type means that we are to use a X.509v3 certificate (a standard certificate). The alias option says that the certificate/key pair to use for signing is in the key store under the "wsse" alias
  7. Here we start our optional requires block. This block specifies all security requirements that must be met when the server receives a message.
  8. This means that all web services in this war file require the message body to be signed.

By default an endpoint does not use the WS-Security configuration.  Use the proprietary @EndpointConfig annotation to set the config name. See JAX-WS_Endpoint_Configuration for the list of available config names.

@WebService
@EndpointConfig(configName = "Standard WSSecurity Endpoint")
public class HelloJavaBean
{
   ...
}

Client side WSSE declaration (jboss-wsse-client.xml)

    <jboss-ws-security xmlns="http://www.jboss.com/ws-security/config" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.jboss.com/ws-security/config
            http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">

  (1)  <config>
  (2)    <sign type="x509v3" alias="wsse"/>
  (3)    <requires>
  (4)      <signature/>
        </requires>
      </config>
    </jboss-ws-security>

 

  1. Here we start our root config block. The root config block is the default configuration for all web service clients (Call, Proxy objects).
  2. This means that the client must sign the message body of all requests it sends. Type means that we are to use a X.509v3 certificate (a standard certificate). The alias option says that the certificate/key pair to use for signing is in the key store under the "wsse" alias
  3. Here we start our optional requires block. This block specifies all security requirements that must be met when the client receives a response.
  4. This means that all web service clients must receive signed response messages.

 

Client side key store configuration

We did not specify a key store or trust store, because client app uses the WSSE System properties instead. If this was a Web or EJB client (meaning a webservice client in a war or EJB jar file), then we would have to specify them in the client descriptor.

Here is an excerpt from the JBossWS samples:

<sysproperty key="org.jboss.ws.wsse.keyStore"
   value="${tests.output.dir}/resources/jaxrpc/samples/wssecurity/wsse.keystore"/>
<sysproperty key="org.jboss.ws.wsse.trustStore"
   value="${tests.output.dir}/resources/jaxrpc/samples/wssecurity/wsse.truststore"/>
<sysproperty key="org.jboss.ws.wsse.keyStorePassword" value="jbossws"/>
<sysproperty key="org.jboss.ws.wsse.trustStorePassword" value="jbossws"/>
<sysproperty key="org.jboss.ws.wsse.keyStoreType" value="jks"/>
<sysproperty key="org.jboss.ws.wsse.trustStoreType" value="jks"/>

SOAP message exchange

Below you see the incomming SOAP message with the details of the security headers ommited. The idea is, that the SOAP body is still plain text, but it is signed in the security header and can therefore not manipulated in transit.

Incomming SOAPMessage

    <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
      <env:Header>
        <wsse:Security env:mustUnderstand="1" ...>
          <wsu:Timestamp wsu:Id="timestamp">...</wsu:Timestamp>
          <wsse:BinarySecurityToken ...>
          ...
          </wsse:BinarySecurityToken>
          <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
          ...
          </ds:Signature>
        </wsse:Security>
      </env:Header>
      <env:Body wsu:Id="element-1-1140197309843-12388840" ...>
        <ns1:echoUserType xmlns:ns1="http://org.jboss.ws/samples/wssecurity">
          <UserType_1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <msg>Kermit</msg>
          </UserType_1>
        </ns1:echoUserType>
      </env:Body>
    </env:Envelope>

Installing the BouncyCastle JCE provider (JDK 1.4)

The information below has originaly been provided by The Legion of the Bouncy Castle.

The provider can be configured as part of your environment via static registration by adding an entry to the java.security properties file (found in $JAVA_HOME/jre/lib/security/java.security, where $JAVA_HOME is the location of your JDK/JRE distribution). You'll find detailed instructions in the file but basically it comes down to adding a line:

  security.provider.<n>=org.bouncycastle.jce.provider.BouncyCastleProvider

Where <n> is the preference you want the provider at.

Note

Issues may arise if the Sun providers are not first.

Where you put the jar is mostly up to you, although with jdk1.4 the best (and in some cases only) place to have it is in $JAVA_HOME/jre/lib/ext. Under Windows there will normally be a JRE and a JDK install of Java if you think you have installed it correctly and it still doesn't work chances are you have added the provider to the installation not being used.

Keystore, truststore - What?

Note

If you having a hard time understanding how the different trust- and keystore configurations are used for signature and encryption, then read this thread first: http://www.jboss.org/index.html?module=bb&op=viewtopic&t=94406

Advanced configuration

Further information and examples covering advanced WS-Security configuration options are available. Those might help when specific settings are required to obtain interoperability with other vendors' WS-Security implementation.

WS-Reliable Messaging

WS-Reliable Messaging specifies how a reliable web service communication can be achieved.

Please take a look at our WS-Reliable Messaging Tutorial for configuration details.

WS-Transaction

Support for the WS-Coordination, WS-AtomicTransaction and WS-BusinessActivity specifications will be provided by technology recently acquired from Arjuna Technologies Ltd. This technology will be present within the JBoss Transactions 4.2.1 release. Further information can be obtained from the JBoss Transactions Project

XML Registries

J2EE 1.4 mandates support for Java API for XML Registries (JAXR). Inclusion of a XML Registry with the J2EE 1.4 certified Application Server is optional. Starting jboss-4.0.2, JBoss ships a UDDI v2.0 compliant registry, the Apache jUDDI registry. We also provide support for JAXR Capability Level 0 (UDDI Registries) via integration of Apache Scout.

This chapter describes how to configure the jUDDI registry in JBoss and some sample code outlines for using JAXR API to publish and query the jUDDI registry.

Apache jUDDI Configuration

Configuration of the jUDDI registry happens via an MBean Service that is deployed in the juddi-service.sar archive in the "all" configuration. The configuration of this service can be done in the jboss-service.xml of the META-INF directory in the juddi-service.sar

Let us look at the individual configuration items that can be changed.

DataSources configuration

      <!-- Datasource to Database-->
      <attribute name="DataSourceUrl">java:/DefaultDS</attribute>

Database Tables (Should they be created on start, Should they be dropped on stop, Should they be dropped on start etc)

      <!-- Should all tables be created on Start-->
      <attribute name="CreateOnStart">false</attribute>
      <!-- Should all tables be dropped on Stop-->
      <attribute name="DropOnStop">true</attribute>
      <!-- Should all tables be dropped on Start-->

      <attribute name="DropOnStart">false</attribute>

JAXR Connection Factory to be bound in JNDI. (Should it be bound? and under what name?)

      <!-- Should I bind a Context to which JaxrConnectionFactory bound-->
      <attribute name="ShouldBindJaxr">true</attribute>

      <!-- Context to which JaxrConnectionFactory to bind to. If you have remote clients, please bind it to the global namespace(default behavior).
           To just cater to clients running on the same VM as JBoss, change to java:/JAXR -->

      <attribute name="BindJaxr">JAXR</attribute>

 

Other common configuration:

Add authorized users to access the jUDDI registry. (Add a sql insert statement in a single line)

      Look at the script META-INF/ddl/juddi_data.ddl for more details. Example for a user 'jboss'

      INSERT INTO PUBLISHER (PUBLISHER_ID,PUBLISHER_NAME,
      EMAIL_ADDRESS,IS_ENABLED,IS_ADMIN)
      VALUES ('jboss','JBoss User','jboss@xxx','true','true');

JBoss JAXR Configuration

In this section, we will discuss the configuration needed to run the JAXR API. The JAXR configuration relies on System properties passed to the JVM. The System properties that are needed are:

   javax.xml.registry.ConnectionFactoryClass=org.apache.ws.scout.registry.ConnectionFactoryImpl 
   jaxr.query.url=http://localhost:8080/juddi/inquiry
   jaxr.publish.url=http://localhost:8080/juddi/publish
   juddi.proxy.transportClass=org.jboss.jaxr.juddi.transport.SaajTransport

Please remember to change the hostname from "localhost" to the hostname of the UDDI service/JBoss Server.

You can pass the System Properties to the JVM in the following ways:

  • When the client code is running inside JBoss (maybe a servlet or an EJB). Then you will need to pass the System properties in the run.sh/run.bat scripts to the java process via the "-D" option.
  • When the client code is running in an external JVM. Then you can pass the properties either as "-D" options to the java process or explicitly set them in the client code(not recommended).
      System.setProperty(propertyname, propertyvalue);

JAXR Sample Code

There are two categories of API: JAXR Publish API and JAXR Inquiry API. The important JAXR interfaces that any JAXR client code will use are the following.

  • javax.xml.registry.RegistryService From J2EE 1.4 JavaDoc: "This is the principal interface implemented by a JAXR provider. A registry client can get this interface from a Connection to a registry. It provides the methods that are used by the client to discover various capability specific interfaces implemented by the JAXR provider."
  • javax.xml.registry.BusinessLifeCycleManager From J2EE 1.4 JavaDoc: "The BusinessLifeCycleManager interface, which is exposed by the Registry Service, implements the life cycle management functionality of the Registry as part of a business level API. Note that there is no authentication information provided, because the Connection interface keeps that state and context on behalf of the client."
  • javax.xml.registry.BusinessQueryManager From J2EE 1.4 JavaDoc: "The BusinessQueryManager interface, which is exposed by the Registry Service, implements the business style query interface. It is also referred to as the focused query interface."

Let us now look at some of the common programming tasks performed while using the JAXR API:

Getting a JAXR Connection to the registry.

      String queryurl = System.getProperty("jaxr.query.url", "http://localhost:8080/juddi/inquiry");
      String puburl = System.getProperty("jaxr.publish.url", "http://localhost:8080/juddi/publish");

      Properties props = new Properties();
      props.setProperty("javax.xml.registry.queryManagerURL", queryurl);
      props.setProperty("javax.xml.registry.lifeCycleManagerURL", puburl);

      String transportClass = System.getProperty("juddi.proxy.transportClass", "org.jboss.jaxr.juddi.transport.SaajTransport");
      System.setProperty("juddi.proxy.transportClass", transportClass);

      // Create the connection, passing it the configuration properties
      factory = ConnectionFactory.newInstance();
      factory.setProperties(props);
      connection = factory.createConnection();

Authentication with the registry.

   /**
    * Does authentication with the uddi registry
    */

   protected void login() throws JAXRException
   {
      PasswordAuthentication passwdAuth = new PasswordAuthentication(userid, passwd.toCharArray());
      Set creds = new HashSet();
      creds.add(passwdAuth);

      connection.setCredentials(creds);
   }

Save a Business

   /**
    * Creates a Jaxr Organization with 1 or more services
    */

   protected Organization createOrganization(String orgname) throws JAXRException
   {
      Organization org = blm.createOrganization(getIString(orgname));
      org.setDescription(getIString("JBoss Inc"));
      Service service = blm.createService(getIString("JBOSS JAXR Service"));
      service.setDescription(getIString("Services of XML Registry"));
      //Create serviceBinding
      ServiceBinding serviceBinding = blm.createServiceBinding();
      serviceBinding.setDescription(blm.createInternationalString("Test Service Binding"));

      //Turn validation of URI off
      serviceBinding.setValidateURI(false);
      serviceBinding.setAccessURI("http://testjboss.org");

      // Add the serviceBinding to the service
      service.addServiceBinding(serviceBinding);

      User user = blm.createUser();
      org.setPrimaryContact(user);
      PersonName personName = blm.createPersonName("Anil S");
      TelephoneNumber telephoneNumber = blm.createTelephoneNumber();
      telephoneNumber.setNumber("111-111-7777");
      telephoneNumber.setType(null);
      PostalAddress address = blm.createPostalAddress("111", "My Drive", "BuckHead", "GA", "USA", "1111-111", "");
      Collection postalAddresses = new ArrayList();
      postalAddresses.add(address);
      Collection emailAddresses = new ArrayList();
      EmailAddress emailAddress = blm.createEmailAddress("anil@apache.org");
      emailAddresses.add(emailAddress);

      Collection numbers = new ArrayList();
      numbers.add(telephoneNumber);
      user.setPersonName(personName);
      user.setPostalAddresses(postalAddresses);
      user.setEmailAddresses(emailAddresses);
      user.setTelephoneNumbers(numbers);

      ClassificationScheme cScheme = getClassificationScheme("ntis-gov:naics", "");
      Key cKey = blm.createKey("uuid:C0B9FE13-324F-413D-5A5B-2004DB8E5CC2");
      cScheme.setKey(cKey);
      Classification classification = blm.createClassification(cScheme, "Computer Systems Design and Related Services", "5415");
      org.addClassification(classification);
      ClassificationScheme cScheme1 = getClassificationScheme("D-U-N-S", "");
      Key cKey1 = blm.createKey("uuid:3367C81E-FF1F-4D5A-B202-3EB13AD02423");
      cScheme1.setKey(cKey1);
      ExternalIdentifier ei = blm.createExternalIdentifier(cScheme1, "D-U-N-S number", "08-146-6849");
      org.addExternalIdentifier(ei);
      org.addService(service);
      return org;
   }

Query a Business

   /**
    * Locale aware Search a business in the registry
    */

   public void searchBusiness(String bizname) throws JAXRException
   {
      try
      {
         // Get registry service and business query manager
         this.getJAXREssentials();

         // Define find qualifiers and name patterns
         Collection findQualifiers = new ArrayList();
         findQualifiers.add(FindQualifier.SORT_BY_NAME_ASC);
         Collection namePatterns = new ArrayList();
         String pattern = "%" + bizname + "%";
         LocalizedString ls = blm.createLocalizedString(Locale.getDefault(), pattern);
         namePatterns.add(ls);

         // Find based upon qualifier type and values
         BulkResponse response = bqm.findOrganizations(findQualifiers, namePatterns, null, null, null, null);

         // check how many organisation we have matched
         Collection orgs = response.getCollection();
         if (orgs == null)
         {
            log.debug(" -- Matched 0 orgs");

         }
         else
         {
            log.debug(" -- Matched " + orgs.size() + " organizations -- ");

            // then step through them
            for (Iterator orgIter = orgs.iterator(); orgIter.hasNext();)
            {
               Organization org = (Organization)orgIter.next();
               log.debug("Org name: " + getName(org));
               log.debug("Org description: " + getDescription(org));
               log.debug("Org key id: " + getKey(org));
               checkUser(org);
               checkServices(org);
            }
         }
      }
      finally
      {
         connection.close();
      }
   }

For more examples of code using the JAXR API, please refer to the resources in the Resources Section.

 

Trouble Shooting

  • I cannot connect to the registry from JAXR. Please check the inquiry and publish url passed to the JAXR ConnectionFactory.
  • I cannot connect to the jUDDI registry. Please check the jUDDI configuration and see if there are any errors in the server.log. And also remember that the jUDDI registry is available only in the "all" configuration.
  • I cannot authenticate to the jUDDI registry. Have you added an authorized user to the jUDDI database, as described earlier in the chapter?
  • I would like to view the SOAP messages in transit between the client and the UDDI Registry. Please use the tcpmon tool to view the messages in transit. TCPMon

Resources

 

WS-Policy

Since 2.1 (Native)

The Web Services Policy Framework (WS-Policy) provides a general purpose model and corresponding syntax to describe the policies of a Web Service.

WS-Policy defines a base set of constructs that can be used and extended by other Web services specifications to describe a broad range of service requirements and capabilities.

Current JBoss implementation can instrument a webservice with policies attached at endpoint, port or port-type scope level only. There are two different methods to attach policies: providing a wsdl decorated with policies and policy attachments as defined by specifications, or using JBoss proprietary annotations. The first way has the advantage of being standard, while the second one is much more simple to implement. Of course the wsdl generated by these annotations conforms to standard defined in specifications and can be used with any ws-policy compliant client.

Please note that ws-policy specifications only define policy requirements and their attachment method to wsdl through specific extensions. It is out of the scope of ws-policy specifications and thus implementation to define and use the content of assertions. The way these assertions (called domain assertions or domain policies) have to be deployed and used is left to other specification like WS-Security-Policy or more generally to domain specific implementation.

Specification

WS-Policy is defined by the combination of the following specifications:

   * WS-Policy specification
   * WS-Policy-Attachment specification

WS-Policy Example

Please take a look to our WS-Reliable Messaging Tutorial to see how to combine WS-Policy specification with other technologies.

Using policies in a user provided wsdl

To attach policies in this manner, the only thing you have to do in a webservice class is to provide a custom wsdl. This will cause JBossws to skip wsdl generation at deploy time, since the wsdl file you provided will be published. Please refer to specification (WS-Policy-Attachment) to learn how to modify wsdl to attach a policy.

Here you find an example of a webservice class and provided wsdl with a policy containing a domain assertion for JBoss wssecurity.

@WebService(name = "Hello", 
targetNamespace = "http://org.jboss.ws/samples/wssecuritypolicy",
wsdlLocation="WEB-INF/wsdl/HelloService.wsdl")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class HelloJavaBean
{
   private Logger log = Logger.getLogger(HelloJavaBean.class);

   @WebMethod
   public UserType echoUserType(@WebParam(name = "user") UserType in0)
   {
      log.info(in0);
      return in0;
   }
}
<?xml version="1.0" encoding="UTF-8"?>
<definitions name='HelloService' targetNamespace='http://org.jboss.ws/samples/wssecuritypolicy' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:ns1='http://org.jboss.ws/samples/wssecurity' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://org.jboss.ws/samples/wssecuritypolicy' xmlns:wsp='http://schemas.xmlsoap.org/ws/2004/09/policy' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<types>
  <xs:schema targetNamespace='http://org.jboss.ws/samples/wssecurity' version='1.0' xmlns:xs='http://www.w3.org/2001/XMLSchema'>
   <xs:complexType name='UserType'>
    <xs:sequence>
     <xs:element minOccurs='0' name='msg' type='xs:string'/>
    </xs:sequence>
   </xs:complexType>
  </xs:schema>
</types>
<wsp:Policy wsu:Id='X509EndpointPolicy' xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'>
  <wsp:All>
   <sp:jboss-ws-security xmlns:sp='http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd'>
    <sp:key-store-file>WEB-INF/wsse.keystore</sp:key-store-file>
    <sp:key-store-password>jbossws</sp:key-store-password>
    <sp:trust-store-file>WEB-INF/wsse.truststore</sp:trust-store-file>
    <sp:trust-store-password>jbossws</sp:trust-store-password>
    <sp:config>
     <sp:encrypt alias='wsse' type='x509v3'/>
     <sp:requires>
      <sp:encryption/>
     </sp:requires>
    </sp:config>
   </sp:jboss-ws-security>
  </wsp:All>
</wsp:Policy>
<message name='Hello_echoUserType'>
  <part name='user' type='ns1:UserType'/>
</message>
<message name='Hello_echoUserTypeResponse'>
  <part name='return' type='ns1:UserType'/>
</message>
<portType name='Hello'>
  <operation name='echoUserType' parameterOrder='user'>
   <input message='tns:Hello_echoUserType'/>
   <output message='tns:Hello_echoUserTypeResponse'/>
  </operation>
</portType>
<binding name='HelloBinding' type='tns:Hello'>
  <wsp:PolicyReference URI='#X509EndpointPolicy'/>
  <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/>
  <operation name='echoUserType'>
   <soap:operation soapAction=''/>
   <input>
    <soap:body namespace='http://org.jboss.ws/samples/wssecuritypolicy' use='literal'/>
   </input>
   <output>
    <soap:body namespace='http://org.jboss.ws/samples/wssecuritypolicy' use='literal'/>
   </output>
  </operation>
</binding>
<service name='HelloService'>
  <port binding='tns:HelloBinding' name='HelloPort'>
   <soap:address location='REPLACE_WITH_ACTUAL_URL'/>
  </port>
</service>
</definitions>

Please note in the wsdl file the wsp:Policy element and the wsp:PolicyReference in 'HelloBinding' binding Element.

 

Using policies with JBoss annotations

Using JBoss proprietary annotation you only have to provide the policy xml, leaving wsdl generation to the JBossWS deployer.

There are two annotations to use, the first one (@PolicyAttachment) containing an array of the second one (@Policy): this lets you have many policies attached to a class or method. In future domain policy implementations might ship domain annotations extending the @Policy annotation to provide needed metadata directly as annotation parameters. The current @Policy annotation takes a reference to a xml file containing a generic policy description written respecting ws-policy specification rules.

 

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME)
public @interface PolicyAttachment {
   Policy[] value();
}

@Retention(RetentionPolicy.RUNTIME)
public @interface Policy {
  
   public String policyFileLocation();
  
   public PolicyScopeLevel scope();
}

And here you have the previous section example re-implemented using annotations and xml policy file:

@WebService(name = "Hello", targetNamespace = "http://org.jboss.ws/samples/wssecurityAnnotatedpolicy")
@PolicyAttachment({@Policy( policyFileLocation="WEB-INF/Policy.xml", scope = PolicyScopeLevel.WSDL_PORT ) })
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class HelloJavaBean
{
   private Logger log = Logger.getLogger(HelloJavaBean.class);

   @WebMethod
   public UserType echoUserType(@WebParam(name = "user") UserType in0)
   {
      log.info(in0);
      return in0;
   }
}
<?xml version="1.0" encoding="UTF-8"?>

<wsp:Policy wsu:Id="X509EndpointPolicy"  xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
          xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

      <wsp:ExactlyOne>
          <wsp:All>
                 <sp:jboss-ws-security xmlns:sp="http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">
                <sp:key-store-file>WEB-INF/wsse.keystore</sp:key-store-file>
                <sp:key-store-password>jbossws</sp:key-store-password>
                <sp:trust-store-file>WEB-INF/wsse.truststore</sp:trust-store-file>
                <sp:trust-store-password>jbossws</sp:trust-store-password>
                <sp:config>
                <sp:encrypt type="x509v3" alias="wsse"/>
                <sp:requires>
                        <sp:encryption/>
                </sp:requires>
                </sp:config>
                 </sp:jboss-ws-security>
            </wsp:All>
     </wsp:ExactlyOne>           
</wsp:Policy>

 

 

 

JMS Transport Clients

Since 2.0.3 (Native)

Since jbossws-2.0.3 we support JAX-WS clients that use JMS transport.

JMS transport is activated on the client side when the endpoint location uses the 'jms' URL schema

  <binding name='JMSBinding' type='tns:OrganizationJMSEndpoint'>
    <soap:binding style='rpc' transport='http://www.example.org/2006/06/soap/bindings/JMS/'/>
    <operation name='getContactInfo'>
      <soap:operation soapAction=''/>
      <input>
        <soap:body namespace='http://org.jboss.ws/samples/jmstransport' use='literal'/>
      </input>
      <output>
        <soap:body namespace='http://org.jboss.ws/samples/jmstransport' use='literal'/>
      </output>
    </operation>
  </binding>
  
  <service name='OrganizationJMSEndpointService'>
    <port binding='tns:JMSBinding' name='JMSEndpointPort'>
      <soap:address location='jms://queue/RequestQueue?replyToName=queue/ResponseQueue'/>
    </port>
  </service>

The service that implements the JMS remote connection is loaded using the key

   org.jboss.ws.core.client.RemoteConnection.jms

Like any other service, this can be overwritten using a system property.

The JAX-WS client code is essentially no different from a client using HTTP as transport

   public void testJMSEndpointPort() throws Exception
   {
      URL wsdlURL = new File("resources/jaxws/samples/jmstransport/jmsservice.wsdl").toURL();
      QName serviceName = new QName("http://org.jboss.ws/samples/jmstransport", "OrganizationJMSEndpointService");
      QName portName = new QName("http://org.jboss.ws/samples/jmstransport", "JMSEndpointPort");
      
      Service service = Service.create(wsdlURL, serviceName);
      Organization port = service.getPort(portName, Organization.class);
      
      String res = port.getContactInfo("mafia");
      assertEquals("The 'mafia' boss is currently out of office, please call again.", res);
   }

 

 

DataBinding

Using JAXB with non annotated classes

Since 2.0.2 (Native)

JAXB is heavily driven by Java Annotations on the Java Bindings. It currently doesn't support an external binding configuration. This recently became an issue for us on JBossESB since the JBossWS 2.0.0 native SOAP stack uses JAXB to perform the SOAP to Java bindings (see 1, 2). It's an issue for JBossESB simply because it needs to be able to support user definition of JBossWS native Webservice Endpoints (e.g. JSR 181) using Java typesets that have not been "JAXB Annotated" (see JAXB Introductions On JBossWS).

In order to support this, we built on a JAXB RI feature whereby it allows you to specify a RuntimeInlineAnnotationReader implementation during JAXBContext creation (see JAXBRIContext).

We call this feature "JAXB Annotation Introduction" and we've made it available for general consumption i.e. it can be checked out, built and used from SVN:

Complete documentation can be found here:

  Mapping of xsd:any

 

Attachments

MTOM/XOP

This chapter describes Message Transmission Optimization Mechanism (MTOM) and XML-binary Optimized Packaging (XOP), a means of more efficiently serializing XML Infosets that have certain types of content. The related specifications are

 

Supported MTOM parameter types

image/jpegjava.awt.Image
text/xmljavax.xml.transform.Source
application/xmljavax.xml.transform.Source
application/octet-streamjavax.activation.DataHandler

The above table shows a list of supported endpoint parameter types. The recommended approach is to use the  javax.activation.DataHandler classes to represent binary data as service endpoint parameters.

Note

Microsoft endpoints tend to send any data as application/octet-stream. The only Java type that can easily cope with this  ambiguity is javax.activation.DataHandler

Enabling MTOM per endpoint

On the server side MTOM processing is enabled through the @BindingType annotation. JBossWS does handle SOAP1.1 and SOAP1.2. Both come with or without MTOM flavours:

MTOM enabled service implementations

package org.jboss.test.ws.jaxws.samples.xop.doclit;

import javax.ejb.Remote;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.BindingType;

@Remote
@WebService(targetNamespace = "http://org.jboss.ws/xop/doclit")
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT, parameterStyle = SOAPBinding.ParameterStyle.BARE)
@BindingType(value="http://schemas.xmlsoap.org/wsdl/soap/http?mtom=true")                         (1)
public interface MTOMEndpoint {

   [...]
}
  1. The MTOM enabled SOAP 1.1 binding ID

MTOM enabled clients

Web service clients can use the same approach described above or rely on the Binding API to enable MTOM (Excerpt taken from the org.jboss.test.ws.jaxws.samples.xop.doclit.XOPTestCase):

[...]
Service service = Service.create(wsdlURL, serviceName);
port = service.getPort(MTOMEndpoint.class);

// enable MTOM
binding = (SOAPBinding)((BindingProvider)port).getBinding();
binding.setMTOMEnabled(true);

 

Note

You might as well use the JBossWS configuration templates to setup deployment defaults.

SwaRef

Since 2.0 (Native)

WS-I Attachment Profile 1.0 defines mechanism to reference MIME attachment parts using swaRef. In this mechanism the content of XML element of type wsi:swaRef is sent as MIME attachment and the element inside SOAP Body holds the reference to this attachment in the CID URI scheme as defined by RFC 2111.

Using SwaRef with JAX-WS endpoints

JAX-WS endpoints delegate all marshalling/unmarshalling to the JAXB API.  The most simple way to enable SwaRef encoding for DataHandler types is to annotate a payload bean with the @XmlAttachmentRef annotation as shown below:

/**
* Payload bean that will use SwaRef encoding
*/
@XmlRootElement
public class DocumentPayload
{
   private DataHandler data;

   public DocumentPayload()
   {
   }

   public DocumentPayload(DataHandler data)
   {
      this.data = data;
   }
      
   @XmlElement
   @XmlAttachmentRef
   public DataHandler getData()
   {
      return data;
   }

   public void setData(DataHandler data)
   {
      this.data = data;
   }
}

With document wrapped endpoints you may even specify the @XmlAttachmentRef annotation on the service endpoint interface:

@WebService
public interface DocWrappedEndpoint
{
   @WebMethod
   DocumentPayload beanAnnotation(DocumentPayload dhw, String test);

   @WebMethod
   @XmlAttachmentRef
   DataHandler parameterAnnotation(@XmlAttachmentRef DataHandler data, String test);

}

The message would then refer to the attachment part by CID:

<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
 <env:Header/>
 <env:Body>
  <ns2:parameterAnnotation xmlns:ns2='http://swaref.samples.jaxws.ws.test.jboss.org/'>
   <arg0>cid:0-1180017772935-32455963@ws.jboss.org</arg0>
   <arg1>Wrapped test</arg1>
  </ns2:parameterAnnotation>
 </env:Body>
</env:Envelope>

Starting from WSDL

If you chose the contract first approach then you need to ensure that any  element declaration that should use SwaRef encoding simply refers to wsi:swaRef schema type:

<element name="data" type="wsi:swaRef" 
xmlns:wsi="http://ws-i.org/profiles/basic/1.1/xsd"/>

Any wsi:swaRef schema type would then be mapped to DataHandler.

Tools

JAX-WS tools

Please refer to JBossWS_JAX-WS_Tools for details. This covers directions on web service contract generation (bottom-up development) and consumption (top-down and client development).

Management tools

JBoss and its web service framework come with some tools allowing WS endpoint management.

Please refer the JBossWS - Endpoint management page for an overview of the available tools. In particular the JBossWS - Records management gives administrators a means of performing custom analysis of their web service traffic as well as exporting communication logs.

 

Standard Annotations

PostConstruct and PreDestroy annotations

Since 3.0.5 (Native)

Users can use standard Java javax.annotation.PostConstruct and javax.annotation.PreDestroy annotations for service lifecycle notification on all POJO endpoints. Here's the sample POJO bean:

@WebService(
   serviceName = "EndpointService",
   targetNamespace = "http://yourorganization.com/service",
   endpointInterface="com.yourorganization.EndpointInterface"
)
public final class EndpointImpl
{

   @PostConstruct
   protected void init()
   {
      // lifecycle method for initialization
   }
   
   @WebMethod
   public String echo(String msg)
   {
      return msg;
   }
   
   @PreDestroy
   private void cleanUp()
   {
      // lifecycle method for cleanup
   }
   
}

JBossWS-Native JAX-WS Extensions

This section describes propriatary JBoss extensions to JAX-WS, provided for JBossWS-Native stack only. Please refer to the JBossWS - User Guide for further JBossWS Extensions.

 

Proprietary Annotations

For the set of standard annotations, please have a look at JAX-WS_Annotations.

EndpointConfig

/**
 * Defines an endpoint or client configuration. 
 * This annotation is valid on an endpoint implementaion bean or a SEI.
 * 
 * @author Heiko.Braun@jboss.org
 * @since 16.01.2007
 */
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.TYPE })
public @interface EndpointConfig {

   /**
    * The optional config-name element gives the configuration name that must be present in
    * the configuration given by element config-file.
    *
    * Server side default: Standard Endpoint
    * Client side default: Standard Client
    */
   String configName() default "";

   /**
    * The optional config-file element is a URL or resource name for the configuration.
    *
    * Server side default: standard-jaxws-endpoint-config.xml
    * Client side default: standard-jaxws-client-config.xml
    */
   String configFile() default "";
}

 

Documentation

Since 2.0.3 (Native)
package org.jboss.ws.annotation;

/**
 * Annotation to be used to add wsdl:documentation elements to the generated wsdl.
 *
 * @author alessio.soldano@jboss.org
 * @since 15-Jan-2008
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Documentation
{
   public String content();
}

SchemaValidation

Since 3.0.1 (Native)
/**
 * This feature represents the use of schema validation with a 
 * web service.
 * 
 * @author Thomas.Diesler@jboss.com
 * @since 29-Feb-2008
 */
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.TYPE })
public @interface SchemaValidation 
{
   /**
    * Optional property for the schema location. If this is not specified the schema
    * will be attempted to extract from the WSDL.
    * 
    * The syntax is the same as for schemaLocation attributes in instance documents: e.g, "http://www.example.com file_name.xsd".
    */
   String schemaLocation() default "";
   
   /**
    * Optional property for the error handler. 
    * If this is not specified the @{ValidationErrorHandler} will be used.
    */
   Class errorHandler() default StrictlyValidErrorHandler.class;
   
   /**
    * Specifies if the feature is enabled or disabled
    */
   boolean enabled() default true;
}

FastInfoset

Since 3.0.1 (Native)
/**
 * This feature represents the use of FastInfoset
 * 
 * @author Thomas.Diesler@jboss.com
 * @since 29-Feb-2008
 */
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.TYPE })
public @interface FastInfoset {
   
   /**
    * Specifies if the feature is enabled or disabled
    */
   boolean enabled() default true;
}

JsonEncoding

Since 3.0.1 (Native)
/**
 * This feature represents the use of JSON encoding
 * 
 * @author Thomas.Diesler@jboss.com
 * @since 29-Feb-2008
 */
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.TYPE })
public @interface JsonEncoding {

   /**
    * Specifies if the feature is enabled or disabled
    */
   boolean enabled() default true;
}

Proprietary WebServiceFeatures

Schema validation for incoming/outgoing messages

Since 3.0.1 (Native)

On the client, schema validation can be enabled using the SchemaValidationFeature

import javax.xml.ws.Service21;
import org.jboss.ws.feature.SchemaValidationFeature;

Service21 service = Service21.create(wsdlURL, SERVICE_NAME);
SchemaValidationFeature feature = new SchemaValidationFeature(xsdURL.toString());
MyTest port = service.getPort(MyTest.class, feature);

You can explicitly set the schema location and the error handler.  If the schema location is not set, the schema will be extracted from the WSDL.

The default error handler is strict and causes a SAX exception when the message does not conform to the schema.

The SchemaValidationFeature has an equivalent @SchemaValidation annotation that can be used on the endpoint.

Support for FastInfoset

Since 3.0.1 (Native)

On the client, FastInfoset can be enabled using the FastInfosetFeature

import javax.xml.ws.Service21;
import org.jboss.ws.feature.FastInfosetFeature;

Service21 service = Service21.create(wsdlURL, serviceName);
FastInfosetFeature feature = new FastInfosetFeature();
FastInfoset port = service.getPort(FastInfoset.class, feature);

The FastInfosetFeature has an equivalent @FastInfoset annotation that can be used on the endpoint.

Support for JSON data binding

Since 3.0.1 (Native)

On the client, JSON data binding can be enabled using the JsonEncodingFeature

import javax.xml.ws.Service21;
import org.jboss.ws.feature.SchemaValidationFeature;

Service21 service = Service21.create(wsdlURL, SERVICE_NAME);
JsonEncodingFeature feature = new JsonEncodingFeature();
JsonPort port = service.getPort(JsonPort.class, feature);

The JsonEncodingFeature has an equivalent @JsonEncoding annotation that can be used on the endpoint.

Disable Xerces Deferred Node Expansion

Since 3.0.5 (Native)

To optimise the parsing of messages Xerces has a feature called deferred node expansion which defers the expansion of the nodes until they are actually accessed. For messages where not all of the nodes will be visited this improves performance but the cost is increased memory overheads which can be considerable for very large messages.

To disable this feature the following system property can be set so that the nodes are eagerly expanded.

  -Dorg.jboss.ws.disable_deferred_node_expansion=true

Deployment descriptor attributes

JSE Endpoints

The following is taken from http://anonsvn.jboss.org/repos/jbossas/projects/metadata/trunk/src/main/resources/dtd/jboss-web_5_0.dtd and shows an excerpt of the jboss-web_5_0.dtd The most important bits are:

  • config-name: JBossWS endpoint config name (see JBossWS - JAX-WS Endpoint Configuration)
  • config-file: JBossWS endpoint config file
  • wsdl-publish-location: Where to publish the runtime gnerated WSDL
<!--
Runtime information about a web service.

wsdl-publish-location is optionally used to specify
where the final wsdl and any dependent files should be stored.  This location
resides on the file system from which deployment is initiated.

-->
<!ELEMENT webservice-description ( webservice-description-name, config-name?,
 config-file?, wsdl-publish-location? )>

<!--
Unique name of a webservice within a module
-->
<!ELEMENT webservice-description-name ( #PCDATA )>

<!--
file: URL of a directory to which a web-service-description's wsdl should be
published during deployment.  Any required files will be published to this
directory, preserving their location relative to the module-specific
wsdl directory(META-INF/wsdl or WEB-INF/wsdl).

Example :

  For an ejb.jar whose webservices.xml wsdl-file element contains
    META-INF/wsdl/a/Foo.wsdl

  <wsdl-publish-location>file:/home/user1/publish
  </wsdl-publish-location>

  The final wsdl will be stored in /home/user1/publish/a/Foo.wsdl

-->
<!ELEMENT wsdl-publish-location ( #PCDATA )>

 

EJB3 endpoints

EJB deployment descriptor attributes are quite the same. You can specify a top level webservices element along with your ejb declaration that allows you to override certain deployment aspects. The following excerpt is taken from https://anonsvn.jboss.org/repos/jbossas/projects/metadata/trunk/src/main/resources/dtd/jboss_5_0.dtd

In addition to the default properties that are customizable like in JSE deployments, the EJB descriptor allows you to specify:

  • context-root: A custom web context root. Applies to all beans in this deployment unit
<!ELEMENT webservices (context-root?, webservice-description*)>

<!-- The context-root element specifies the context root of the web
application that the EJB service endpoints are deployed to.
If it is not specified it will be derived from the deployment short name.
-->
<!ELEMENT context-root (#PCDATA)>

<!--
Runtime information about a web service.
wsdl-publish-location is optionally used to specify
where the final wsdl and any dependent files should be stored.  This location
resides on the file system from which deployment is initiated.
-->
<!ELEMENT webservice-description ( webservice-description-name, config-name?,
 config-file?, wsdl-publish-location? )>

 

Appendix A

JBossWS - JAX-WS Endpoint Configuration

JBossWS - JAX-WS Client Configuration

JBossWS - JAX-WS Annotations

 

References

[1] JSR-224 - Java API for XML-Based Web Services (JAX-WS) 2.0

[2] JSR 222 - Java Architecture for XML Binding (JAXB) 2.0

[3] JSR-261 - Java API for XML Web Services Addressing

[4] SOAP-1.2 - Messaging Framework

[5] JSR-250 - Common Annotations for the Java Platform

[6] JSR 181 - Web Services Metadata for the Java Platform