title: Eclipse Generated Web Service Client Extremely Slow
body: <p>A little up front info:</p>
  
  <p>I have a SOAP service (hosted using JAX-WS (Endpoint class), but I don't think that is important).</p>
  
  <p>I can connect to and use the web service just fine with Visual Studio generating the client (C#).</p>
  
  <p>I generated a java client using Eclipse Web Tools (new --> other --> web services --> web services client).  </p>
  
  <p>Then I wrote a JUnit test to test the client.  The test passes, but it takes an extremely long time to run.  Each service call takes 300 seconds (give or take a couple seconds).  Furthermore, it doesn't matter how fast the computer is.  If I run this on my very slow work laptop it takes the same amount of time as if I run it on my fast home machine.  </p>
  
  <p>I have debugged into the axis code to the following function within org.apache.axis.encoding.DeserializationContext:</p>
  
  <pre><code>public void parse() throws SAXException
      {
          if (inputSource != null) {
              SAXParser parser = XMLUtils.getSAXParser();
              try {
                  parser.setProperty("http://xml.org/sax/properties/lexical-handler", this);
                  parser.parse(inputSource, this);
  
                  try {
                      // cleanup - so that the parser can be reused.
                      parser.setProperty("http://xml.org/sax/properties/lexical-handler", nullLexicalHandler);
                  } catch (Exception e){
                      // Ignore.
                  }
  </code></pre>
  
  <p>no suprise, but the call to parser.parse() is taking up the 300 seconds.  The from the web service is very short, so it shouldn't take much time to parse.</p>
  
  <p>In case anyone is wondering, the actual type of parser is <code>com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl</code></p>
  
  <p>I can't debug into it because I don't have the source (and I'm tired up debugging 50 calls deep into commonly used libraries).   </p>
  
  <p>I'm currently running the profiler to include packages from Sun.  I'll post my findings for that once it completes (adding all those packages significantly slows down the test)</p>
  
  <p>I'm running <code>Eclipse 3.5.1</code> and I'm using <code>axis 1.4</code></p>
  
  <p>Edit:</p>
  
  <p>Here is the JUnit test:</p>
  
  <pre><code>@Test
  public void testExecuter() throws IOException, InterruptedException, RemoteException, ServiceException
  {
      //Listener l = new Listener(3456);
      //l.start();
      Executer exec = new ExecuterServiceLocator().getExecuterPort();
      //Executer exec = new ExecuterProxy("http://localhost:3456/Executer");
      System.out.println("executer created");
      _return remote = exec.execute("perl -e \"print 5\"", new EvAction[0]);
      System.out.println("after call 1");
      assertEquals("5", remote.getStdout());
      assertEquals("", remote.getStderr());
      assertEquals(0, remote.getReturnCode());
  }
  </code></pre>
  
  <p>NOTE: Both ways of creating the Executer have the same thing happen</p>
  
  <p>Edit2:</p>
  
  <p>Here is the code I'm using to start the service:</p>
  
  <pre><code>public static void main(String[] args) {
      Endpoint.create(new Executer()).publish("http://localhost:3456/Executer");
  }
  </code></pre>
  
  <p>I can't post the URL since I am just developping it on a single machine right now.  However, here is the WSDL that is generated if I go to <a href="http://localhost:3456/Executer?WSDL" rel="noreferrer">http://localhost:3456/Executer?WSDL</a></p>
  
  <pre><code>&lt;!--
   Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. 
  --&gt;
  −
  &lt;!--
   Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. 
  --&gt;
  −
  &lt;definitions targetNamespace="http://executer/" name="ExecuterService"&gt;
  −
  &lt;types&gt;
  −
  &lt;xsd:schema&gt;
  &lt;xsd:import namespace="http://executer/" schemaLocation="http://localhost:3456/Executer?xsd=1"/&gt;
  &lt;/xsd:schema&gt;
  &lt;/types&gt;
  −
  &lt;message name="Execute"&gt;
  &lt;part name="parameters" element="tns:Execute"/&gt;
  &lt;/message&gt;
  −
  &lt;message name="ExecuteResponse"&gt;
  &lt;part name="parameters" element="tns:ExecuteResponse"/&gt;
  &lt;/message&gt;
  −
  &lt;message name="IOException"&gt;
  &lt;part name="fault" element="tns:IOException"/&gt;
  &lt;/message&gt;
  −
  &lt;message name="InterruptedException"&gt;
  &lt;part name="fault" element="tns:InterruptedException"/&gt;
  &lt;/message&gt;
  −
  &lt;portType name="Executer"&gt;
  −
  &lt;operation name="Execute"&gt;
  &lt;input message="tns:Execute"/&gt;
  &lt;output message="tns:ExecuteResponse"/&gt;
  &lt;fault message="tns:IOException" name="IOException"/&gt;
  &lt;fault message="tns:InterruptedException" name="InterruptedException"/&gt;
  &lt;/operation&gt;
  &lt;/portType&gt;
  −
  &lt;binding name="ExecuterPortBinding" type="tns:Executer"&gt;
  &lt;soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/&gt;
  −
  &lt;operation name="Execute"&gt;
  &lt;soap:operation soapAction=""/&gt;
  −
  &lt;input&gt;
  &lt;soap:body use="literal"/&gt;
  &lt;/input&gt;
  −
  &lt;output&gt;
  &lt;soap:body use="literal"/&gt;
  &lt;/output&gt;
  −
  &lt;fault name="IOException"&gt;
  &lt;soap:fault name="IOException" use="literal"/&gt;
  &lt;/fault&gt;
  −
  &lt;fault name="InterruptedException"&gt;
  &lt;soap:fault name="InterruptedException" use="literal"/&gt;
  &lt;/fault&gt;
  &lt;/operation&gt;
  &lt;/binding&gt;
  −
  &lt;service name="ExecuterService"&gt;
  −
  &lt;port name="ExecuterPort" binding="tns:ExecuterPortBinding"&gt;
  &lt;soap:address location="http://localhost:3456/Executer"/&gt;
  &lt;/port&gt;
  &lt;/service&gt;
  &lt;/definitions&gt;
  </code></pre>
  
  <p>Edit:</p>
  
  <p>I think this might be causing a problem:</p>
  
  <p>I used TCPMonitor to look at the SOAP requests and I noticed that the client was speaking HTTP/1.0 and the server is speaking HTTP/1.1, but I don't know if this is causing the problem.  I'm currently trying to figure out how to make the client speak HTTP/1.1. </p>
  
  <p>Here are the SOAP messages in case anyone was wondering:</p>
  
  <pre><code>POST /Executer HTTP/1.0
  Content-Type: text/xml; charset=utf-8
  Accept: application/soap+xml, application/dime, multipart/related, text/*
  User-Agent: Axis/1.4
  Host: USENBOONETL1C:2222
  Cache-Control: no-cache
  Pragma: no-cache
  SOAPAction: ""
  Content-Length: 354
  
  &lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;&lt;soapenv:Body&gt;&lt;Execute xmlns="http://executer/"&gt;&lt;arg0 xmlns=""&gt;perl -e &amp;quot;print 5&amp;quot;&lt;/arg0&gt;&lt;/Execute&gt;&lt;/soapenv:Body&gt;&lt;/soapenv:Envelope&gt;
  </code></pre>
  
  <p>and the response:</p>
  
  <pre><code>HTTP/1.1 200 OK
  Content-type: text/xml;
  charset="utf-8"
  Content-length: 266
  
  &lt;?xml version="1.0" ?&gt;&lt;S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"&gt;&lt;S:Body&gt;&lt;ns2:ExecuteResponse xmlns:ns2="http://executer/"&gt;&lt;return&gt;&lt;stdout&gt;5&lt;/stdout&gt;&lt;stderr&gt;&lt;/stderr&gt;&lt;returnCode&gt;0&lt;/returnCode&gt;&lt;/return&gt;&lt;/ns2:ExecuteResponse&gt;&lt;/S:Body&gt;&lt;/S:Envelope&gt;
  </code></pre>
  
  <p>Edit:</p>
  
  <p>Finally!  turns out changing the HTTP client to CommonsHTTPClient and using HTTP/1.1 fixed the issue:</p>
  
  <p>Here is the code I added to the client which fixed it:</p>
  
  <pre><code>BasicClientConfig basicClientConfig = new BasicClientConfig();
  SimpleChain simpleChain = new SimpleChain();
  
  simpleChain.addHandler(new CommonsHTTPSender());
  basicClientConfig.deployTransport("http", simpleChain);
  
  ExecuterServiceLocator l = new ExecuterServiceLocator(basicClientConfig);
  ...
  </code></pre>
  
  <p>note:   You have to add <code>common-httpclient.jar</code> and <code>common.codec.jar</code> to the classpath.</p>