Tengo un hilo atascado en un contenedor Tomcat, me gustaría encontrar la causa para evitar este problema.
Usando jstack , descubrí que está atascado después de una llamada de servicio web SOAP:
pool-2-thread-1" #27 prio=5 os_prio=0 tid=0x00007fd2315ce800 nid=0x39 runnable [0x00007fd2415d2000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:171) at java.net.SocketInputStream.read(SocketInputStream.java:141) at java.io.BufferedInputStream.fill(BufferedInputStream.java:246) at java.io.BufferedInputStream.read1(BufferedInputStream.java:286) at java.io.BufferedInputStream.read(BufferedInputStream.java:345) - locked <0x0000000087eb10e0> (a java.io.BufferedInputStream) at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:735) at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678) at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587) - locked <0x0000000087eb1138> (a sun.net.www.protocol.http.HttpURLConnection) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492) - locked <0x0000000087eb1138> (a sun.net.www.protocol.http.HttpURLConnection) at java.net.URL.openStream(URL.java:1045) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:999) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:400) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:231) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:209) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:178) at com.sun.xml.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:364) at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:322) at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:231) at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:212) at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:208) at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:119) at javax.xml.ws.Service.<init>(Service.java:77)¿Qué tiempo de espera falta en la configuración? Estoy usando las opciones estándar.
Su cliente intenta descargar el archivo WDSL del servicio SOAP desde una URL remota. HttpURLConnection s tiene por defecto un tiempo de espera de lectura de socket infinito y un tiempo de espera de conexión infinito. En su caso, la conexión parece estar atascada mientras lee del servidor. Dado que el tiempo de espera de lectura es infinito, estará atascado para siempre o al menos hasta que se restablezca la conexión (por ejemplo, por un enrutador o el servidor).
Como ya se mencionó en uno de los comentarios, los tiempos de espera predeterminados se pueden configurar a través de las propiedades del sistema sun.net.client.defaultReadTimeout y sun.net.client.defaultConnectTimeout (como se documenta aquí ). También podría establecer estas propiedades en tiempo de ejecución, pero tendría que hacerlo antes de que se lean las propiedades. Desafortunadamente, las propiedades se leen solo una vez cuando se carga la clase NetworkClient interna. No lo he probado, pero es muy poco probable que pueda establecer las propiedades dentro de un contenedor Tomcat, antes de que se cargue esta clase. Si tiene la oportunidad de cambiar el script de inicio de Tomcat, le recomiendo encarecidamente que establezca tiempos de espera explícitos (especialmente en el caso de una configuración de producción).
Establecer tiempos de espera explícitos es, en general, un buen enfoque. Pero los tiempos de espera solo resolverán el síntoma descrito, pero no su problema real: su cliente SOAP depende de la descarga exitosa de un archivo WSDL desde una ubicación remota. En lugar de descargar el archivo WSDL desde una ubicación remota, puede cargarlo desde un recurso local. Hay dos maneras posibles de hacer esto:
R) Si debe tener acceso al código de cliente (generado), puede reemplazar la URL remota de la ubicación WSDL con la URL de un archivo de recursos en su classpath. Ver esta respuesta para un ejemplo.
B) Si la adaptación manual del código del cliente no es una opción, puede usar un archivo de catálogo, como se documenta aquí .