Wygenerowany przez Eclipse klient sieci Web bardzo wolno

Trochę informacji z przodu:

Mam usługę SOAP (hostowaną za pomocą JAX-WS (klasa punktu końcowego), ale nie sądzę, aby to było ważne).

Mogę połączyć się z serwisem WWW i korzystać z niego w prosty sposób dzięki programowi Visual Studio generującemu klienta (C #).

Wygenerowałem klienta Java przy użyciu Eclipse Web Tools (nowy -> inny -> serwisy internetowe -> klient usług internetowych).

Następnie napisałem test JUnit, aby przetestować klienta. Test kończy się sukcesem, ale bieganie trwa bardzo długo. Każde zgłoszenie serwisowe trwa 300 sekund (podaj lub poświęć kilka sekund). Co więcej, nie ma znaczenia, jak szybki jest komputer. Jeśli uruchomię to na moim bardzo powolnym laptopie, zajmuje to tyle samo czasu, co na moim szybkim komputerze domowym.

W kodzie osi debugowałem następującą funkcję w org.apache.axis.encoding.DeserializationContext:

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

nie ma niespodzianki, ale wywołanie parser.parse () zajmuje 300 sekund. Usługa internetowa jest bardzo krótka, więc analizowanie jej nie powinno zająć dużo czasu.

Jeśli ktoś się zastanawia, rzeczywisty typ parsera tocom.sun.org.apache.xerces.internal.jaxp.SAXParserImpl

Nie mogę go debugować, ponieważ nie mam źródła (i jestem zmęczony debugowaniem 50 wywołań głęboko w powszechnie używanych bibliotekach).

Obecnie używam programu profilującego, aby dołączyć pakiety od firmy Sun. Po zakończeniu opublikuję moje ustalenia na ten temat (dodanie wszystkich tych pakietów znacznie spowolni test)

biegnęEclipse 3.5.1 i używamaxis 1.4

Edytować:

Oto test JUnit:

@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());
}

UWAGA: Oba sposoby tworzenia Executera mają to samo

Edit2:

Oto kod, którego używam do uruchomienia usługi:

public static void main(String[] args) {
    Endpoint.create(new Executer()).publish("http://localhost:3456/Executer");
}

Nie mogę opublikować adresu URL, ponieważ właśnie teraz rozwijam go na jednym komputerze. Jednak tutaj jest WSDL, który jest generowany, gdy idę dohttp: // localhost: 3456 / Executer? WSDL

<!--
 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. 
-->
−
<!--
 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. 
-->
−
<definitions targetNamespace="http://executer/" name="ExecuterService">
−
<types>
−
<xsd:schema>
<xsd:import namespace="http://executer/" schemaLocation="http://localhost:3456/Executer?xsd=1"/>
</xsd:schema>
</types>
−
<message name="Execute">
<part name="parameters" element="tns:Execute"/>
</message>
−
<message name="ExecuteResponse">
<part name="parameters" element="tns:ExecuteResponse"/>
</message>
−
<message name="IOException">
<part name="fault" element="tns:IOException"/>
</message>
−
<message name="InterruptedException">
<part name="fault" element="tns:InterruptedException"/>
</message>
−
<portType name="Executer">
−
<operation name="Execute">
<input message="tns:Execute"/>
<output message="tns:ExecuteResponse"/>
<fault message="tns:IOException" name="IOException"/>
<fault message="tns:InterruptedException" name="InterruptedException"/>
</operation>
</portType>
−
<binding name="ExecuterPortBinding" type="tns:Executer">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
−
<operation name="Execute">
<soap:operation soapAction=""/>
−
<input>
<soap:body use="literal"/>
</input>
−
<output>
<soap:body use="literal"/>
</output>
−
<fault name="IOException">
<soap:fault name="IOException" use="literal"/>
</fault>
−
<fault name="InterruptedException">
<soap:fault name="InterruptedException" use="literal"/>
</fault>
</operation>
</binding>
−
<service name="ExecuterService">
−
<port name="ExecuterPort" binding="tns:ExecuterPortBinding">
<soap:address location="http://localhost:3456/Executer"/>
</port>
</service>
</definitions>

Edytować:

Myślę, że może to powodować problem:

Użyłem TCPMonitor do sprawdzenia żądań SOAP i zauważyłem, że klient mówi HTTP / 1.0, a serwer mówi HTTP / 1.1, ale nie wiem, czy to powoduje problem. Obecnie próbuję dowiedzieć się, jak sprawić, by klient mówił HTTP / 1.1.

Oto wiadomości SOAP na wypadek, gdyby ktoś się zastanawiał:

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

<?xml version="1.0" encoding="UTF-8"?><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"><soapenv:Body><Execute xmlns="http://executer/"><arg0 xmlns="">perl -e &quot;print 5&quot;</arg0></Execute></soapenv:Body></soapenv:Envelope>

i odpowiedź:

HTTP/1.1 200 OK
Content-type: text/xml;
charset="utf-8"
Content-length: 266

<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:ExecuteResponse xmlns:ns2="http://executer/"><return><stdout>5</stdout><stderr></stderr><returnCode>0</returnCode></return></ns2:ExecuteResponse></S:Body></S:Envelope>

Edytować:

Wreszcie! okazuje się, że zmiana klienta HTTP na CommonsHTTPClient i użycie HTTP / 1.1 rozwiązało problem:

Oto kod, który dodałem do klienta, który go naprawił:

BasicClientConfig basicClientConfig = new BasicClientConfig();
SimpleChain simpleChain = new SimpleChain();

simpleChain.addHandler(new CommonsHTTPSender());
basicClientConfig.deployTransport("http", simpleChain);

ExecuterServiceLocator l = new ExecuterServiceLocator(basicClientConfig);
...

uwaga: musisz dodaćcommon-httpclient.jar icommon.codec.jar do ścieżki klasy.

questionAnswers(4)

yourAnswerToTheQuestion