JAX-WS Client timeout Example
1. Introduction
In this post, we feature a comprehensive Example on JAX-WS Client timeout. Java API for XML Web Services (JAX-WS) specification was introduced in 2005. There are several tools that implement JAX-WS specification: JDK (since version 6), Apache CXF, Apache Axis, JBossWS, IBM WebSphere, and Oracle Weblogic. There are two common timeouts in client-server architecture:
- Read timeout – the timeout while waiting for the data from the server. Specifically, if the server fails to send the last byte within the read timeout setting, a read timeout error will be raised.
- Connection timeout – the timeout while making the initial connection between the client and server.
In this example, I will demonstrate how to set up these two timeout properties for JAX-WS clients.
2. Technologies Used
The example code in this article was built and run using:
- Java 1.8.101
- Maven 3.3.9
- Apache CXF 3.2.6
- Eclipse Oxygen
- Logback 1.2.3
3. Maven Project
In this step, I will create a Maven project which generates Java stubs from a calculator service.
3.1 Dependencies
The project contains several dependencies, the most important one is the JAX-WS JDK runtime library.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jcg.zheng.demo</groupId>
<artifactId>jax-ws-client-timeout</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.sun.xml.ws/jaxws-rt -->
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.1.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- logback -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>jaxws-calculator_wsdl</id>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlUrls>
<wsdlUrl>http://www.dneonline.com/calculator.asmx?wsdl</wsdlUrl>
</wsdlUrls>
<keep>true</keep>
<packageName>jcg.zheng.demo.jaxws.client.calculator</packageName>
<sourceDestDir>${basedir}/src/main/jaxws</sourceDestDir>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.2.6</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${basedir}/src/main/cxf</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>http://www.dneonline.com/calculator.asmx?wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>4. Generated Java Stubs
Execute mvn clean install to generate the Java stubs from http://www.dneonline.com/calculator.asmx?wsdl.
We should not modify the generated files.
4.1 Generated Files from wsimport
Use wsimport from jaxws-maven-plugin to generate files at /src/main/jaxws.
List of Java Files Generated
C:\gitworkspace\jax-ws-client-timeout\src\main\jaxws\jcg\zheng\demo\jaxws\client\calculator>dir
Volume in drive C is OSDisk
Volume Serial Number is 3A10-C6D4
Directory of C:\gitworkspace\jax-ws-client-timeout\src\main\jaxws\jcg\zheng\demo\jaxws\client\calculator
09/08/2018 08:31 AM <DIR> .
09/08/2018 08:31 AM <DIR> ..
09/08/2018 08:31 AM 1,622 Add.java
09/08/2018 08:31 AM 1,367 AddResponse.java
09/08/2018 08:31 AM 2,976 Calculator.java
09/08/2018 08:31 AM 3,806 CalculatorSoap.java
09/08/2018 08:31 AM 1,628 Divide.java
09/08/2018 08:31 AM 1,403 DivideResponse.java
09/08/2018 08:31 AM 1,632 Multiply.java
09/08/2018 08:31 AM 1,427 MultiplyResponse.java
09/08/2018 08:31 AM 2,290 ObjectFactory.java
09/08/2018 08:31 AM 190 package-info.java
09/08/2018 08:31 AM 1,632 Subtract.java
09/08/2018 08:31 AM 1,427 SubtractResponse.java
12 File(s) 21,400 bytes
2 Dir(s) 22,013,812,736 bytes free4.2 Generated Files from wsdl2java
Use wsdl2java from cxf-codegen-plugin to generate stubs at /src/main/cxf.
List of Java Files Generated
C:\gitworkspace\jax-ws-client-timeout\src\main\cxf\org\tempuri>dir
Volume in drive C is OSDisk
Volume Serial Number is 3A10-C6D4
Directory of C:\gitworkspace\jax-ws-client-timeout\src\main\cxf\org\tempuri
09/09/2018 08:39 AM <DIR> .
09/09/2018 08:39 AM <DIR> ..
09/09/2018 08:39 AM 1,625 Add.java
09/09/2018 08:39 AM 1,367 AddResponse.java
09/09/2018 08:39 AM 3,629 Calculator.java
09/09/2018 08:39 AM 3,178 CalculatorSoap.java
09/09/2018 08:39 AM 1,631 Divide.java
09/09/2018 08:39 AM 1,403 DivideResponse.java
09/09/2018 08:39 AM 1,635 Multiply.java
09/09/2018 08:39 AM 1,427 MultiplyResponse.java
09/09/2018 08:39 AM 2,209 ObjectFactory.java
09/09/2018 08:39 AM 163 package-info.java
09/09/2018 08:39 AM 1,635 Subtract.java
09/09/2018 08:39 AM 1,427 SubtractResponse.java
12 File(s) 21,329 bytes
2 Dir(s) 22,013,902,848 bytes free
C:\gitworkspace\jax-ws-client-timeout\src\main\cxf\org\tempuri>5. Calculator Service Clients
We can set the JAX-WS clients’ read and connection timeout values via the BindingProviderPropertie's two constants: CONNECT_TIMEOUT and REQUEST_TIMEOUT.
5.1 JAX-WS Client
In this step, I will create the JAXWS_CalculatorServiceClient class. It has a constructor which sets the read and connection timeouts.
JAXWS_CalculatorServiceClient.java
package jcg.zheng.jaxws.client.timeoutdemo;
import java.util.Map;
import javax.xml.ws.BindingProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.xml.ws.client.BindingProviderProperties;
import jcg.zheng.demo.jaxws.client.calculator.Calculator;
import jcg.zheng.demo.jaxws.client.calculator.CalculatorSoap;
public class JAXWS_CalculatorServiceClient {
private final Logger lOG = LoggerFactory.getLogger(this.getClass());
private CalculatorSoap service;
public JAXWS_CalculatorServiceClient() {
super();
Calculator calculator = new Calculator();
service = calculator.getCalculatorSoap();
}
public JAXWS_CalculatorServiceClient(Integer connectTimeoutInMS, Integer readTimeoutInMS) {
this();
if (readTimeoutInMS != null || connectTimeoutInMS != null) {
Map requestCtx = ((BindingProvider) service).getRequestContext();
lOG.info("JAX_WS Client Read_Timeout=" + readTimeoutInMS + " Connect_Timeout=" + connectTimeoutInMS);
requestCtx.put(BindingProviderProperties.REQUEST_TIMEOUT, readTimeoutInMS);
requestCtx.put(BindingProviderProperties.CONNECT_TIMEOUT, connectTimeoutInMS);
}
}
public int addTwoNumber(int num1, int num2) {
return service.add(num1, num2);
}
}
5.2 CXF Client
In this step, I will create the CXF_CalculatorServiceClient class similar to JAXWS_CalculatorServiceClient but with the stubs generated from the CXF plugin.
CXF_CalculatorServiceClient.java
package jcg.zheng.jaxws.client.timeoutdemo;
import java.util.Map;
import javax.xml.ws.BindingProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tempuri.*;
import com.sun.xml.ws.client.BindingProviderProperties;
public class CXF_CalculatorServiceClient {
private final Logger lOG = LoggerFactory.getLogger(this.getClass());
private CalculatorSoap service;
public CXF_CalculatorServiceClient() {
super();
Calculator calculator = new Calculator();
service = calculator.getCalculatorSoap();
}
public CXF_CalculatorServiceClient(Integer connectTimeoutInMS, Integer readTimeoutInMS) {
this();
if (readTimeoutInMS != null || connectTimeoutInMS != null) {
Map requestCtx = ((BindingProvider) service).getRequestContext();
lOG.info("CXF JAX_WS Client Read_Timeout=" + readTimeoutInMS + " Connect_Timeout=" + connectTimeoutInMS);
requestCtx.put(BindingProviderProperties.REQUEST_TIMEOUT, readTimeoutInMS);
requestCtx.put(BindingProviderProperties.CONNECT_TIMEOUT, connectTimeoutInMS);
}
}
public int timesTwoNumber(int num1, int num2) {
return service.multiply(num1, num2);
}
}
5.3 Demo Client Timeout with Junit Test
In this step, I will create a ServiceClientTimeoutTestto test the timeout settings.
ServiceClientTimeoutTest.java
package jcg.zheng.jaxws.client.timeoutdemo;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class ServiceClientTimeoutTest {
private static final int READ_TIMEOUT_OK = 1000;
private static final int READ_TIMEOUT_EXCEPTION = 10;
private static final int CONNECT_TIMEOUT_OK = 10;
private JAXWS_CalculatorServiceClient jaxCalculatorService;
private CXF_CalculatorServiceClient cxfCalculatorService;
@Test
public void jaxwsClient_returns_data_happyPath() {
jaxCalculatorService = new JAXWS_CalculatorServiceClient(CONNECT_TIMEOUT_OK, READ_TIMEOUT_OK);
int sum = jaxCalculatorService.addTwoNumber(3, 4);
assertEquals(7, sum);
}
@Test
public void cxfClient_returns_data_happyPath() {
cxfCalculatorService = new CXF_CalculatorServiceClient(CONNECT_TIMEOUT_OK, READ_TIMEOUT_OK);
int product = cxfCalculatorService.timesTwoNumber(3, 4);
assertEquals(12, product);
}
@Test(expected = javax.xml.ws.WebServiceException.class)
public void jaxwsClient_throw_Exception_when_fails_to_read() {
jaxCalculatorService = new JAXWS_CalculatorServiceClient(CONNECT_TIMEOUT_OK, READ_TIMEOUT_EXCEPTION);
jaxCalculatorService.addTwoNumber(3, 4);
}
@Test(expected = javax.xml.ws.WebServiceException.class)
public void cxfClient_throw_Exception_when_fails_to_read() {
cxfCalculatorService = new CXF_CalculatorServiceClient(CONNECT_TIMEOUT_OK, READ_TIMEOUT_EXCEPTION);
cxfCalculatorService.timesTwoNumber(3, 4);
}
}
6. JDK Timeout
JDK provides a list of network properties. We are interested in the defaultConnectionTimeout and the defaultReadTimeout, which specifies the default connection and read timeout for the protocol handler used by java.net.URLConnection.
sun.net.client.defaultConnectTimeout– the timeout in milliseconds to establish the connection to the host.sun.net.client.defaultReadTimeout– the timeout in milliseconds when reading from input stream when a connection is established to a resource.
In this step, I will create a Java application which sets up the JDK network connection timeout properties.
TimeoutDemo .java
package jcg.zheng.jaxws.client.timeoutdemo;
import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TimeoutDemo {
private static final Logger LOG = LoggerFactory.getLogger(TimeoutDemo.class);
private static final String JDK_READ_TIMEOUT = "sun.net.client.defaultReadTimeout";
private static final String JDK_CONNECTION_TIMEOUT = "sun.net.client.defaultConnectTimeout";
public static void main(String[] args) {
JAXWS_CalculatorServiceClient calculator = null;
CXF_CalculatorServiceClient calculator_cxf = null;
Scanner scanIn = new Scanner(System.in);
displayJVMTimeout();
System.out.println("Enter JVM Timeout in Milliseconds: (-1 to ignore) ");
String jvmTimeoutInput = scanIn.nextLine();
System.out.println("Enter JAX-WS Client Timeout in Milliseconds: (-1 to ignore) ");
String clientTimeoutInput = scanIn.nextLine();
if( jvmTimeoutInput.equalsIgnoreCase("-1")) {
LOG.info("Ingore JVM Timeout setting.");
}
else {
setTimeOutWithJVMProperties(jvmTimeoutInput);
displayJVMTimeout();
}
if (clientTimeoutInput.equalsIgnoreCase("-1")) {
LOG.info("Ingore Client Timeout setting.");
calculator = new JAXWS_CalculatorServiceClient();
calculator_cxf = new CXF_CalculatorServiceClient();
} else {
Integer timeoutInt = Integer.parseInt(clientTimeoutInput);
calculator = new JAXWS_CalculatorServiceClient(timeoutInt, timeoutInt);
calculator_cxf = new CXF_CalculatorServiceClient(timeoutInt, timeoutInt);
}
try {
int sum = calculator.addTwoNumber(3, 4);
LOG.info("Calculator.add returns: " + sum + " for 3 + 4");
} catch (Exception e) {
e.printStackTrace();
}
try {
int product = calculator_cxf.timesTwoNumber(4, 5);
LOG.info("Calculator.multiply returns: " + product + " for 4 x 5 ");
} catch (Exception e) {
e.printStackTrace();
}
scanIn.close();
}
private static void setTimeOutWithJVMProperties(String timeoutValue) {
LOG.info("Update the JVM timeout setting:" + timeoutValue);
System.setProperty(JDK_CONNECTION_TIMEOUT, timeoutValue);
System.setProperty(JDK_READ_TIMEOUT, timeoutValue);
}
private static void displayJVMTimeout() {
System.out.println("Current JDK Connection Timeout setting:" + System.getProperty(JDK_CONNECTION_TIMEOUT));
System.out.println("Current JDK Read Timeout setting:" + System.getProperty(JDK_READ_TIMEOUT));
}
}
6.1 Demo 1
Execute TimeoutDemo as a Java application. Use the default value by ignoring the timeout setting.
Console Output
Current JDK Connection Timeout setting:null Current JDK Read Timeout setting:null Enter JVM Timeout in Milliseconds: (-1 to ignore) -1 Enter JAX-WS Client Timeout in Milliseconds: (-1 to ignore) -1 11:47:51.422 [main] INFO jcg.zheng.jaxws.client.timeoutdemo.TimeoutDemo - Ingore JVM Timeout setting. 11:47:51.433 [main] INFO jcg.zheng.jaxws.client.timeoutdemo.TimeoutDemo - Ingore Client Timeout setting. 11:47:52.886 [main] INFO jcg.zheng.jaxws.client.timeoutdemo.TimeoutDemo - Calculator.add returns: 7 for 3 + 4 11:47:52.981 [main] INFO jcg.zheng.jaxws.client.timeoutdemo.TimeoutDemo - Calculator.multiply returns: 20 for 4 x 5
6.2 Demo 2
Execute TimeoutDemo as a Java application. Set the JVM timeout to 10 seconds and ignore the client’s timeout setting.
Console Output
Current JDK Connection Timeout setting:null Current JDK Read Timeout setting:null Enter JVM Timeout in Milliseconds: (-1 to ignore) 10000 Enter JAX-WS Client Timeout in Milliseconds: (-1 to ignore) -1 11:52:38.623 [main] INFO jcg.zheng.jaxws.client.timeoutdemo.TimeoutDemo - Update the JVM timeout setting:10000 Current JDK Connection Timeout setting:10000 Current JDK Read Timeout setting:10000 11:52:38.635 [main] INFO jcg.zheng.jaxws.client.timeoutdemo.TimeoutDemo - Ingore Client Timeout setting. 11:52:40.098 [main] INFO jcg.zheng.jaxws.client.timeoutdemo.TimeoutDemo - Calculator.add returns: 7 for 3 + 4 11:52:40.239 [main] INFO jcg.zheng.jaxws.client.timeoutdemo.TimeoutDemo - Calculator.multiply returns: 20 for 4 x 5
6.3 Demo 3
Execute TimeoutDemo as a Java application. Set the client’s timeout to 10 seconds and JVM timeout to 1 ms.
Console Output
Current JDK Connection Timeout setting:null Current JDK Read Timeout setting:null Enter JVM Timeout in Milliseconds: (-1 to ignore) 1 Enter JAX-WS Client Timeout in Milliseconds: (-1 to ignore) 10000 11:53:41.421 [main] INFO jcg.zheng.jaxws.client.timeoutdemo.TimeoutDemo - Update the JVM timeout setting:1 Current JDK Connection Timeout setting:1 Current JDK Read Timeout setting:1 Exception in thread "main" javax.xml.ws.WebServiceException: Failed to access the WSDL at: http://www.dneonline.com/calculator.asmx?wsdl. It failed with: connect timed out. at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:162) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:144) at com.sun.xml.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:263) at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:226) at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:174) at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:104) at javax.xml.ws.Service.(Service.java:77) at jcg.zheng.demo.jaxws.client.calculator.Calculator.(Calculator.java:42) at jcg.zheng.jaxws.client.timeoutdemo.JAXWS_CalculatorServiceClient.(JAXWS_CalculatorServiceClient.java:22) at jcg.zheng.jaxws.client.timeoutdemo.JAXWS_CalculatorServiceClient.(JAXWS_CalculatorServiceClient.java:27) at jcg.zheng.jaxws.client.timeoutdemo.TimeoutDemo.main(TimeoutDemo.java:39) Caused by: java.net.SocketTimeoutException: connect timed out at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at sun.net.NetworkClient.doConnect(NetworkClient.java:178) at sun.net.www.http.HttpClient.openServer(HttpClient.java:432) at sun.net.www.http.HttpClient.openServer(HttpClient.java:527) at sun.net.www.http.HttpClient.(HttpClient.java:211) at sun.net.www.http.HttpClient.New(HttpClient.java:308) at sun.net.www.http.HttpClient.New(HttpClient.java:326) at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1168) at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1104) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:998) at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:932) at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1512) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440) at java.net.URL.openStream(URL.java:1038) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:805) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:262) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:129) ... 9 more
7. JAX-WS Client timeout – Summary
In this article, I demonstrated how to generate JAX-WS clients and set the client read and connection timeout values. There are timeout setting at JVM, OS, and Socket. You should consider these settings when troubleshooting the timeout issues.
8. Download the Source Code
This tutorial consists of a Maven project which demonstrated how to set JAX-WS Client connection and request timeout values.
You can download the full source code of this example here: JAX-WS Client Timeout Example

