Alex
Alex

Reputation: 505

JAXWS - help required to set WSDL request timeout

Im using Metro 2.0 and J2SE5. The application I have written does not know about the external WebService at compile time, it finds them at runtime based on a business logic XML file, therefore I perform a WSDL request.

The sample code I have written is as follows:

String wsdlServiceName = ...; String wsdlURL = ...; Document payload = ...;

final String nsURI = ...;
final QName serviceName = new QName(nsURI, wsdlServiceName + "Service");
final QName servicePort = new QName(nsURI, wsdlServiceName + "Port");

// Create service and the dispatcher for the SOAP message
Service service = Service.create(new URL(wsdlURL), serviceName);
dispatch = service.createDispatch(servicePort, SOAPMessage.class, Service.Mode.MESSAGE);

// Set timeouts
dispatch.getRequestContext().put("com.sun.xml.internal.ws.request.timeout", 3000);
dispatch.getRequestContext().put("com.sun.xml.internal.ws.connect.timeout", 3000);

// Create the outgoing SOAP request
SOAPBinding soapBinding = (SOAPBinding) dispatch.getBinding();
request = soapBinding.getMessageFactory().createMessage();

SOAPBody requestBody = request.getSOAPBody();
requestBody.addDocument(payload);

// Invoke web service operation 
SOAPMessage response = dispatch.invoke(request);

The timeout works correctly when the Web Service is invoked ( dispatcher.invoke(request) )

HOWEVER the WSDL is requested before the timeouts are set, and if the Web Service is not responding it takes 90 seconds before the connection is timed-out.

Is it possible to set the timeouts before the WSDL is requested ? You need a dispatcher to set the timeouts, but that is done AFTER the Service is created that requests the WSDL?! (ie. Service.create() )

Upvotes: 5

Views: 9254

Answers (2)

Scott A Miller
Scott A Miller

Reputation: 686

We just ran into this same issue, and tried all of the settings mentioned above - likewise, to no avail.

Our solution was to download the WSDL to a temporary file first, using URL.openConnection() (setting the timeouts on the connection with: URLConnection.setConnectionTimeout(), and URLConnection.setReadTimeout()). We then generate a url for this file with: File.toURI().toURL(), which we pass to the service constructor that takes a URL.

This approach lets you dynamically fetch the current WSDL, while explicitly controlling the timeout. We then set the timeout for subsequent calls to the service as you show in the original post.

Upvotes: 2

Cratylus
Cratylus

Reputation: 54074

Try the setting system property

sun.net.client.defaultConnectTimeout 

but from Networking Properties it says it may not be supported for in future releases

However I would suggest to cache the WSDL and not access it remotely.
It is better performance wise especially if you are working with a WSDL that is not expected to change frequently.

Upvotes: 3

Related Questions