java.io.IOException:流关闭 - 在 Tomcat 8 - JavaMelody - JAX WS
java.io.IOException: Stream closed - on Tomcat 8 - JavaMelody - JAX WS
我已将 Tomcat 从版本 7 升级到版本 8.0.30。在调用 WebService 方法之前一切正常,这应该 return 结果。
[Edit: 25.01.2016] 似乎响应是空的,连根标签都找不到。
当我切换回 Tomcat 7 时一切正常。
我不知道在哪里寻找这些想法。你能帮我解决我的问题吗?
SEVERE: Servlet.service() for servlet [Dynamic JAXWS Servlet] in
context with path [/edmwas] threw exception
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
at java.io.BufferedInputStream.reset(BufferedInputStream.java:446)
at net.bull.javamelody.PayloadNameRequestWrapper.resetBufferedInputStream(PayloadNameRequestWrapper.java:139)
at net.bull.javamelody.PayloadNameRequestWrapper.initialize(PayloadNameRequestWrapper.java:118)
at net.bull.javamelody.MonitoringFilter.createRequestWrapper(MonitoringFilter.java:278)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:185)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:178)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
at org.apache.coyote.ajp.AbstractAjpProcessor.process(AbstractAjpProcessor.java:850)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:664)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
这是 javamelody PayloadNameRequestWrapper 的摘录
protected void initialize() throws IOException {
//name on a best-effort basis
name = null;
requestType = null;
final HttpServletRequest request = (HttpServletRequest) getRequest();
final String contentType = request.getContentType();
if (contentType == null) {
//don't know how to handle this content type
return;
}
if (!"POST".equalsIgnoreCase(request.getMethod())) {
//no payload
return;
}
//Try look for name in payload on a best-effort basis...
try {
if (contentType.startsWith("text/x-gwt-rpc")) {
//parse GWT-RPC method name
name = parseGwtRpcMethodName(getBufferedInputStream(), getCharacterEncoding());
requestType = "GWT-RPC";
} else if (contentType.startsWith("application/soap+xml") //SOAP 1.2
|| contentType.startsWith("text/xml") //SOAP 1.1
&& request.getHeader("SOAPAction") != null) {
//parse SOAP method name
name = parseSoapMethodName(getBufferedInputStream(), getCharacterEncoding());
requestType = "SOAP";
} else {
//don't know how to name this request based on payload
//(don't parse if text/xml for XML-RPC, because it is obsolete)
name = null;
requestType = null;
}
} catch (final Exception e) {
LOG.debug("Error trying to parse payload content for request name", e);
//best-effort - couldn't figure it out
name = null;
requestType = null;
} finally {
//reset stream so application is unaffected
resetBufferedInputStream();
}
}
protected BufferedInputStream getBufferedInputStream() throws IOException {
if (bufferedInputStream == null) {
//workaround Tomcat issue with form POSTs
//see
final ServletRequest request = getRequest();
request.getParameterMap();
//buffer the payload so we can inspect it
bufferedInputStream = new BufferedInputStream(request.getInputStream());
// and mark to allow the stream to be reset
bufferedInputStream.mark(Integer.MAX_VALUE);
}
return bufferedInputStream;
}
protected void resetBufferedInputStream() throws IOException {
if (bufferedInputStream != null) {
bufferedInputStream.reset(); // Exception happens here
}
}
此问题与 AJP 连接器有关,不会出现在每个 tomcat 版本中。错误报告已经存在:
https://bz.apache.org/bugzilla/show_bug.cgi?id=58481
在错误报告中,您可以找到一个 post,其中写着
- Tomcat 7 应该可以工作到版本 7.0.59。错误出现在
版本 7.0.61
- Tomcat 8 应该可以工作到 8.0.20 版。错误出现在
版本 8.0.21
我已将 Tomcat 从版本 7 升级到版本 8.0.30。在调用 WebService 方法之前一切正常,这应该 return 结果。
[Edit: 25.01.2016] 似乎响应是空的,连根标签都找不到。
当我切换回 Tomcat 7 时一切正常。 我不知道在哪里寻找这些想法。你能帮我解决我的问题吗?
SEVERE: Servlet.service() for servlet [Dynamic JAXWS Servlet] in
context with path [/edmwas] threw exception
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
at java.io.BufferedInputStream.reset(BufferedInputStream.java:446)
at net.bull.javamelody.PayloadNameRequestWrapper.resetBufferedInputStream(PayloadNameRequestWrapper.java:139)
at net.bull.javamelody.PayloadNameRequestWrapper.initialize(PayloadNameRequestWrapper.java:118)
at net.bull.javamelody.MonitoringFilter.createRequestWrapper(MonitoringFilter.java:278)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:185)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:178)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
at org.apache.coyote.ajp.AbstractAjpProcessor.process(AbstractAjpProcessor.java:850)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:664)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
这是 javamelody PayloadNameRequestWrapper 的摘录
protected void initialize() throws IOException {
//name on a best-effort basis
name = null;
requestType = null;
final HttpServletRequest request = (HttpServletRequest) getRequest();
final String contentType = request.getContentType();
if (contentType == null) {
//don't know how to handle this content type
return;
}
if (!"POST".equalsIgnoreCase(request.getMethod())) {
//no payload
return;
}
//Try look for name in payload on a best-effort basis...
try {
if (contentType.startsWith("text/x-gwt-rpc")) {
//parse GWT-RPC method name
name = parseGwtRpcMethodName(getBufferedInputStream(), getCharacterEncoding());
requestType = "GWT-RPC";
} else if (contentType.startsWith("application/soap+xml") //SOAP 1.2
|| contentType.startsWith("text/xml") //SOAP 1.1
&& request.getHeader("SOAPAction") != null) {
//parse SOAP method name
name = parseSoapMethodName(getBufferedInputStream(), getCharacterEncoding());
requestType = "SOAP";
} else {
//don't know how to name this request based on payload
//(don't parse if text/xml for XML-RPC, because it is obsolete)
name = null;
requestType = null;
}
} catch (final Exception e) {
LOG.debug("Error trying to parse payload content for request name", e);
//best-effort - couldn't figure it out
name = null;
requestType = null;
} finally {
//reset stream so application is unaffected
resetBufferedInputStream();
}
}
protected BufferedInputStream getBufferedInputStream() throws IOException {
if (bufferedInputStream == null) {
//workaround Tomcat issue with form POSTs
//see
final ServletRequest request = getRequest();
request.getParameterMap();
//buffer the payload so we can inspect it
bufferedInputStream = new BufferedInputStream(request.getInputStream());
// and mark to allow the stream to be reset
bufferedInputStream.mark(Integer.MAX_VALUE);
}
return bufferedInputStream;
}
protected void resetBufferedInputStream() throws IOException {
if (bufferedInputStream != null) {
bufferedInputStream.reset(); // Exception happens here
}
}
此问题与 AJP 连接器有关,不会出现在每个 tomcat 版本中。错误报告已经存在: https://bz.apache.org/bugzilla/show_bug.cgi?id=58481
在错误报告中,您可以找到一个 post,其中写着
- Tomcat 7 应该可以工作到版本 7.0.59。错误出现在 版本 7.0.61
- Tomcat 8 应该可以工作到 8.0.20 版。错误出现在 版本 8.0.21