Trying to set a connection/read timeout in a WS client… can’t and found this post? Welcome to the club.
Does ANYONE OUT THERE have a proven, easy to implement, somewhat universal way, to simple set connect and read timeouts for JAX-WS web-service clients? I can’t seem to find them, and neither can tons of others out there by the looks for dozens of posts/blogs I have read in forums etc.
This is one of the most insidious problems with an application. Timeouts, or the lack thereof causing a thread in your application to mysteriously (or not) hang up sitting there forever. Is my app deadlocked? Why is this thread hung? Then after a while your app’s thread pool may be exhausted etc leading to harder to diagnose and worthless artifact error symptoms being spewed into a log file.
In an enterprise app, one of the common things we do is use a web-service to send or receive data from some other application out there… and a lot of people use some sort of JAX-WS generated variant of clients.
Here is my question. HOW can I reliably set a jax-ws client timeout for both connect and read operations? I seem to see various answers to this, often time they don’t work for folks. Other times I suspect folks are getting confused with regards to the actual JAX-WS client implementation executing their code (jboss, glassfish, websphere etc).. and I guess these settings vary based on where you code is deployed, which is SUPER convenient because there is not abstract definition of this in the spec itself to allow developers to specify their timeouts in a portable way??
Hey Oracle: Why can’t Java just support a simple solution to this stupid time-wasting problem?? @see Axis clients and how easy it is to do there!
PLEASE POST YOUR SOLUTIONS IN THE COMMENTS SECTION OF THIS POST TO HELP OTHERS (and me!)
Here are some examples I’ve seen out there of threads that have random answers that often go unanswered.
http://www.coderanch.com/t/537394/Web-Services/java/JBoss-Jax-ws-Timeout-Configuration
https://community.jboss.org/message/607864
http://stackoverflow.com/questions/3130913/setting-jax-ws-client-timeout
http://www.java.net/node/676074
http://www.websphere-world.com/modules.php?name=News&file=article&sid=2058
http://chamerling.org/2009/09/23/setting-timeout-on-generated-jaxws-cxf-clients/
https://forums.oracle.com/forums/thread.jspa?threadID=1666087
In IBM WebSphere Application Server (WAS), there are three ways to set the read-timeout in a jax-ws client: (This assumes you are using the IBM jax-ws implementation and your client is running in WAS)
1.) (easiest, no code change, no JVM property to manage) Use a policy set
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=compass&product=was-express-dist&topic=uwbs_wsspshttp
2.) programitacally on the message context (MC)
import javax.xml.ws.BindingProvider;
import com.ibm.wsspi.websvcs.Constants;
…
javax.xml.ws.Service service= …; Printer myPrinterProxy = service.getPort(portName, Printer.class);
javax.xml.ws.BindingProvider bp = (javax.xml.ws.BindingProvider)myPrinterProxy;
// Retrieve the request context for the BindingProvider object Map rc = myBindingProvider.getRequestContext(); rc.put(REQUEST_TIMEOUT_PROPERTY, 30); // 30 seconds
###
3.) use the “timeout” JVM custom property. That’s correct, just “timeout”, without the quotes of course.
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=compass&product=was-nd-mp&topic=rwbs_httptransportprop
###
Rules of precedence in WAS: Policy set -> MC -> JVM property -> then default
Excellent contribution Mike – thanks!
Hi,
the best answer I have found is the following, directly from redhat support:
Timeout Configuration
Two different properties control the timeout behavior of the HTTP connection and the timeout of a client which is waiting to receive a message. The first is javax.xml.ws.client.connectionTimeout and the second is javax.xml.ws.client.receiveTimeout. Each is expressed in milliseconds, and the correct syntax is shown below.
public void testConfigureTimeout() throws Exception
{
//Set timeout until a connection is established
((BindingProvider)port).getRequestContext().put(“javax.xml.ws.client.connectionTimeout”, “6000”);
//Set timeout until the response is received
((BindingProvider) port).getRequestContext().put(“javax.xml.ws.client.receiveTimeout”, “1000”);
port.echo(“testTimeout”);
}
This is for EAP 6 and should also work for AS 7+
Don’t know about other Application Servers
Hi, for me worked this solution, but it is probably JBOSS only :
(BindingProvider)wsPort).getRequestContext().put(“org.jboss.ws.timeout”, yourTimeoutInMillisec);
which is equivalent to
(BindingProvider)wsPort).getRequestContext().put(StubExt.PROPERTY_CLIENT_TIMEOUT, yourTimeoutInMillisec);
According to IBM website:
“timeout properties for JAX-WS clients must not be set on the client binding file, as the runtime environment ignores timeout properties set this way.”
http://pic.dhe.ibm.com/infocenter/wasinfo/v8r5/index.jsp?topic=%2Fcom.ibm.websphere.nd.doc%2Fae%2Frwbs_jaxwstimeouts.html
The IBM documentation is correct. All the means is you can not set jax-ws timeouts in deployment descriptor (ibm-webservicesclient-bnd.xmi) like you do for a jax-rpc application.
“JAX-WS timeout properties”
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=phil&product=was-nd-dist&topic=rwbs_jaxwstimeouts
Further reference:
Configuring the JAX-RPC web services client bindings in the ibm-webservicesclient-bnd.xmi deployment descriptor
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=phil&product=was-base-dist&topic=twbs_configibmclientdd
I needed to set request timeout on Jboss 6.2EAP when using soap over jms (soapjms). Jboss uses org.apacge.cxf internally. After some struggle I finally used directly the cxf classes to set the timeout.
final Client cl = ClientProxy.getClient(wsClient);
final JMSConduit jmsConduit = (JMSConduit) cl.getConduit();
jmsConduit.getJmsConfig().setReceiveTimeout(30000L); // milliseconds
To get this working I had to add a dependency to Jboss cxf internal module by adding
org.apache.cxf.impl with “export” keyword to MANIFEST.MF dependencies section.
Manifest-Version: 1.0
Dependencies: org.apache.cxf.impl export, foo.bar // foo.bar is just other dependency
This allowed access to Jboss private cxf implementation classes in rune-time. In project I use maven org.apache.cxf dependencies with scope “provided” so they are not packed to ear.
e.g.
org.apache.cxf
cxf-rt-transports-http
2.7.10
provided
org.apache.cxf
cxf-rt-transports-jms
2.7.10
provided
org.apache.cxf
cxf-rt-frontend-jaxws
2.7.10
provided
for JAX-WS RI:here is official doc:
https://metro.java.net/nonav/1.2/guide/HTTP_Timeouts.html
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
public class somehing
private static final String CONNECTION_TIMEOUT = “javax.xml.ws.client.connectionTimeout”;
private static final String RECEIVE_TIMEOUT = “javax.xml.ws.client.receiveTimeout”;
//example method
public String doGet(String url, Object body, Map headers) {
Client client = ClientBuilder.newClient();
client.property(CONNECTION_TIMEOUT, 240000); //4 minutes
client.property(RECEIVE_TIMEOUT, 240000);
WebTarget target = client.target(url);
…………………………..
property field is public on javax.ws.rs.core.Configurable which is extended by javax.ws.rs.client.Client soooo….
I’ve just seen that, if you have a client which doesn’t include code strictly dependent from any implementation, and you want set timeouts without knowing if your client will execute in a container where it will find CXF or the default jdk implementation (JDK JAX-WS RI), then you have to put both pairs of properties, for example for request timeout:
((BindingProvider) port).getRequestContext().put(CXF_REQUEST_TIMEOUT, requestTimeout);
((BindingProvider) port).getRequestContext().put(JAXWS_REQUEST_TIMEOUT, requestTimeout);
where:
CXF_REQUEST_TIMEOUT = “javax.xml.ws.client.receiveTimeout”
and
JAXWS_REQUEST_TIMEOUT = “com.sun.xml.internal.ws.request.timeout”
give a look to this https://github.com/javaee/metro-jax-ws/issues/1166
bye