How to configure a timeout for a SOAP Client

This article walks through the configuration of a JAX-WS Client timeout for applications running on WildFly or JBoss Enterprise application Platform

Pre-requisites: You should be able to deploy a JAX-WS Web Service on WildFly. Read this article to learn more: SOAP Web services on WildFly made simple

There are two types of time-out in relation to SOAP Clients:

  • ConnectionTimeout: this is the amount of time (in ms) that the client will attempt to establish a connection. The default is 30000 (30 seconds). 0 specifies that the client will have no timeout.
  • ReceiveTimeout: this is the amount of time (in s) that the client will wait for a response before it times out. The default is 60000. 0 specifies that the client will have no timeout.

To set the above time-outs, you can use the following properties:

# Jakarta EE 8
javax.xml.ws.client.connectionTimeout 
javax.xml.ws.client.receiveTimeout

# Jakarta EE 9/10
jakarta.xml.ws.client.connectionTimeout
jakarta.xml.ws.client.receiveTimeout

An example code

The following code example, shows how to set a 5 minutes Receive Timeout to connect to a SOAP Web service:

  @Test
    public void testTimeoutConfigutation() throws Exception {

        SOAPService service = new SOAPService();
        assertNotNull(service);

        Greeter greeter = service.getPort(portName, Greeter.class);
        updateAddressPort(greeter, PORT);
        ((javax.xml.ws.BindingProvider)greeter).getRequestContext().put("javax.xml.ws.client.receiveTimeout",
                                                                        5 * 60 * 1000);
        try {
            greeter.greetMe("test");
            // remove fail() check to let this test pass in the powerful machine
        } catch (Throwable ex) {
            Object cause = null;
            if (ex.getCause() != null) {
                cause = ex.getCause();
            }
            assertTrue("Timeout cause is expected", cause instanceof java.net.SocketTimeoutException);
        }
    }

If a time-out occurs, you will see the following exception at Runtime:

2016-07-20 07:24:01 - Error getting response; java.net.SocketTimeoutException: Read timed out

Setting the Timeout globally

The above example, applies the timeout for a single application. To set them globally, you can use the following System Properties:

  • cxf.client.connectionTimeout for ConnectionTimeout
  • cxf.client.receiveTimeout for ReceiveTimeout

For example, you can add them to your standalone.xml configuration as follows:

<system-properties>
  <property name="cxf.client.connectionTimeout" value="90000"/>
  <property name="cxf.client.receiveTimeout" value="120000"/>
</system-properties>

Configuring the timeout with Apache CXF

If you are using directly the Apache CXF API for your Clients, then you can use the org.apache.cxf.transports.http.configuration.HTTPClientPolicy to set the Client Timeout. Example:

public static WebClient createWebClient( String url, long connectTimeout, long receiveTimeout, int maxRetries )
{
	WebClient client = WebClient.create( url );

	HTTPConduit httpConduit = ( HTTPConduit ) WebClient.getConfig( client ).getConduit();

	HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
	httpClientPolicy.setConnectionTimeout( connectTimeout );
	httpClientPolicy.setReceiveTimeout( receiveTimeout );
	httpClientPolicy.setMaxRetransmits( maxRetries );

	httpConduit.setClient( httpClientPolicy );
	return client;
}

Finally, remember that in order to use Apache CXF libraries in your applications you need to add the dependencies for org.apache.cxf and org.apache.cxf.impl. For example, you can do that in jboss-deployment-structure.xml:

<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <deployment>
        <dependencies>
            <module name="org.apache.cxf" />
            <module name="org.apache.cxf.impl" />
        </dependencies>
    </deployment>
</jboss-deployment-structure>