Setting a JAX-WS web service client timeout – why is the answer so dang elusive??

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/2592303/how-do-i-set-the-jax-ws-client-request-timeout-programatically-on-jboss

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://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Frwbs_trbclientruntime.html

http://chamerling.org/2009/09/23/setting-timeout-on-generated-jaxws-cxf-clients/

https://forums.oracle.com/forums/thread.jspa?threadID=1666087

10 thoughts on “Setting a JAX-WS web service client timeout – why is the answer so dang elusive??

  1. 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

  2. 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

  3. 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);

  4. 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

  5. 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

  6. 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….

  7. 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

Leave a reply to Prudentis Cancel reply