Search code examples
javawsdljax-wsblocking

JAX-WS client side is hanging for 30 secs when WSDL is too large


I'm a little new to JAX-WS Webservices and Apache CXF. We're developing a simple client-server system, and the communication between them is through JAX-WS web service protocol. On the server side, we're using Apache CXF implementation (because of using interceptors), on the client side it is the normal reference implementation (jax-ws-rt).

My problem is the following: when the client creates the service first:

service = Service.create(uri.toURL(), new QName(targetNamespace, serviceName));

then it normally sends GET requests to the server, in order to get and process the WSDL. First is something like this:

GET .../services/ws/mainservice?wsdl

and then immediately after

GET .../services/ws/mainservice?wsdl=mainservice.wsdl

So far, so good. The third requests is the normal HTTP POST request, using SOAP, invoking the function what the client calls.

Everything worked fine until the WSDL got too large. I can check out the size from a web browser e.g., using the two GET links above. When the response for the second GET request reaches the 100K size (the XML response in the browser), because there are too many functions declared in the web service interface, then the following happens: the client is hanging about 30 secs during the second GET request, and then everything is fine, the function runs.

I debugged, which point is blocked in that case, it is in the RuntimeWSDLParser.java, createReader() function, when it calls:

private static XMLStreamReader createReader(URL wsdlLoc, Class<Service> serviceClass) throws IOException, XMLStreamException {
InputStream stream;
try {
    stream = wsdlLoc.openStream();
} catch (IOException io) {

}

and this file is in the jax-ws-rt.jar on the client side.

The strange thing is (at least for me, but I'm not really familiar with it) that if I reach to this row with the debugger, and immediately step over, then it is about 30 secs of blocking. If I wait 25 secs, and just then I step over, then it is 5 secs only. So it seems there is a counter for this hanging somewhere.

Another thing: this problem is only occurs when I use localhost connections. If I try to use a differenc client from another computer, and use inner IP address, there is no blocking. Nor when I try to use TCPMon and I redirect the port.

I hope I was specific enough. Any help would be appreciated, I'm stuck at this problem for days. Thanks in advance!


Solution

  • Today you're in luck! There is two options:

    1. Use a WSDL document file locally

      Save a copy of the WSDL document file and the schemma files to your project.

      ClassLoader classloader = Thread.currentThread().getContextClassLoader();
      URL wsdlLocation = classloader.getResource("MyHelloService.wsdl");
      QName serviceName= new QName("http://test.com/", "MyHelloService");
      
      MyHelloService service = new MyHelloService(wsdlLocation, serviceName);
      service.sayHello("Test");
      
    2. Without a WSDL document file

      QName qname = new QName("http://thenamespace", "FooService");
      FooService service = new FooService(null, qname); // null for ignore WSDL
      Foo port = service.getFooPort();
      BindingProvider bindingProvider = (BindingProvider) port;
      bindingProvider.getRequestContext()
          .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
          "http://foo.com/soap/fooBean");
      
      // Use the service
      Object obj = port.doSomething(param);
      

    See also: