18

I have a program that uses javax.xml.ws.Service to call a remote service defined by a WSDL. This program runs on the Google App Engine which, by default, sets the HTTP connection timeout to 5 seconds{1}. I need to increase this timeout value since this service often takes a long time to respond, but since this request is not being made with URLConnection, I cannot figure out how to call URLConnection.setReadTimeout(int){2}, or otherwise change the timeout.

Is there any way to globally set the HTTP connection timeout on the App Engine? And, for purposes of sharing knowledge, how would one go about solving this sort of problem generally?

{1}: https://developers.google.com/appengine/docs/java/urlfetch/overview#Requests

{2}: http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URLConnection.html#setReadTimeout(int)

Travis Webb
  • 14,688
  • 7
  • 55
  • 109

4 Answers4

17

You could try setting the sun.net.client.defaultConnectTimeout and sun.net.client.defaultReadTimeout system properties documented here, e.g.

System.setProperty("sun.net.client.defaultReadTimeout", "30000");
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");

EDIT

Sorry, just re-read and noticed this is on Google App Engine. I don't know for sure, but given the litigious relationship Google and Oracle have lately, I'm guessing GAE doesn't run the Oracle JVM. I'll leave this here in case someone else runs into a similar problem.

Justin Garrick
  • 14,767
  • 7
  • 41
  • 66
9

Try this:

Port port = service.getPort(endPointInterface);  //or another "getPort(...)"
((BindingProvider) port).getRequestContext()
    .put(BindingProviderProperties.REQUEST_TIMEOUT, 30);
elias
  • 15,010
  • 4
  • 40
  • 65
  • I haven't tried this yet, but you get the bounty for providing an answer that I haven't seen anywhere else yet. – Travis Webb May 23 '12 at 15:04
5

See https://developers.google.com/appengine/docs/java/urlfetch/usingjavanet

You can do something like this to get a URLConnection:

    URL url = new URL("http://www.example.com/atom.xml");
    URLConnection tempConnection = url.openConnection();
    tempConnection.setReadTimeout(10);
iein valdez
  • 660
  • 4
  • 11
  • The entire issue is that a `URLConnection` object is never available to me. The request is made in an opaque way that uses `javax.xml.ws.Service` – Travis Webb May 05 '12 at 00:11
1

For App Engine with JAX-WS you have to set the request context (tested today with SDK 1.9.15). For normal machines you cannot go higher than 60s and would have to switch to the bigger machines (Bx) for better use a task queue.

For local testing you would normally use BindingProviderProperties.CONNECT_TIMEOUT and BindingProviderProperties.REQUEST_TIMEOUT, but they are not on the App Engine JRE White List and your code inspection might constantly warn you about that. The equivalent strings can be used though:

com.sun.xml.internal.ws.connect.timeout
com.sun.xml.internal.ws.connect.timeout

For deployment to App Engine:

com.sun.xml.ws.connect.timeout
com.sun.xml.ws.request.timeout

A full example how to apply that to auto-generated code from JAX-WS 2.x, values have to be provided in milliseconds:

@WebEndpoint(name = "Your.RandomServicePort")
public YourServiceInterface getYourRandomServicePort() {
    YourRandomServiceInterface port = super.getPort(YOURRANDOMSERVICE_QNAME_PORT, YourRandomServiceInterface.class);
    Map<String, Object> requestContext = ((BindingProvider)port).getRequestContext();
    requestContext.put("com.sun.xml.ws.connect.timeout", 10000);
    requestContext.put("com.sun.xml.ws.request.timeout", 10000);
    return port;
}
Anton Kaiser
  • 713
  • 6
  • 11