JBoss 5中POST请求间歇性出现RESTEASY000100错误排查求助
JBoss 5下POST请求间歇性Stream Closed问题排查
问题背景
在JBoss 5环境中,POST请求出现间歇性错误,多数请求可正常执行,仅部分请求触发报错,错误日志如下:
2024-09-10 11:46:15,389 ERROR [org.jboss.resteasy.core.SynchronousDispatcher] RESTEASY000100: Failed executing POST /rest/demo org.jboss.resteasy.spi.ReaderException: java.io.IOException: Stream closed at org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:201) at org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:137) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:160) at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:269) at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:227) at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:216) at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:541) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:523) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:125) at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208) at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55) at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190) at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92) at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126) at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Thread.java:662) Caused by: java.io.IOException: Stream closed at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:362) at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:193) at java.io.FilterInputStream.read(FilterInputStream.java:116) at org.codehaus.jackson.impl.ByteSourceBootstrapper.ensureLoaded(ByteSourceBootstrapper.java:507) at org.codehaus.jackson.impl.ByteSourceBootstrapper.detectEncoding(ByteSourceBootstrapper.java:129) at org.codehaus.jackson.impl.ByteSourceBootstrapper.constructParser(ByteSourceBootstrapper.java:224) at org.codehaus.jackson.JsonFactory._createJsonParser(JsonFactory.java:785) at org.codehaus.jackson.JsonFactory.createJsonParser(JsonFactory.java:561) at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:405) at org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl.proceed(MessageBodyReaderContextImpl.java:106) at org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingInterceptor.read(GZIPDecodingInterceptor.java:63) at org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl.proceed(MessageBodyReaderContextImpl.java:109) at org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:168) ... 32 more
本人怀疑该问题由Jackson依赖冲突导致,想咨询Restlet是否会对RESTEasy产生影响,以及有哪些排查方向可以定位问题?
问题解答
Restlet对RESTEasy的影响
Restlet和RESTEasy同属JAX-RS规范实现,若项目中同时引入两者,必然触发类加载与组件竞争问题:
- 两者都会注册JAX-RS相关的Provider、Servlet,容器启动时会出现优先级竞争,可能导致请求被错误路由到Restlet组件处理,其MessageBodyReader提前读取并关闭请求流,后续RESTEasy处理时就会抛出
Stream closed错误。 - 即便间接引入Restlet依赖,在JBoss 5这种类加载机制复杂的容器中,也会干扰RESTEasy的正常运行逻辑。
排查方向
1. 依赖冲突排查(核心)
- 用
mvn dependency:tree或gradle dependencies生成依赖树,检查:- 是否同时存在Restlet与RESTEasy的依赖,若有则通过
<exclusions>移除Restlet相关依赖。 - Jackson版本冲突:JBoss 5默认自带
codehaus.jackson,若项目引入com.fasterxml.jackson,会导致序列化组件不兼容,需统一版本或排除冲突依赖。
- 是否同时存在Restlet与RESTEasy的依赖,若有则通过
- 检查JBoss部署目录
server/default/lib下是否存在Restlet相关JAR,若有直接移除,避免容器级别的类加载干扰。
2. 请求流重复读取排查
- 排查项目中的Filter、Interceptor:若自定义日志、权限校验组件提前调用
request.getInputStream()读取请求体但未重置流,会导致后续RESTEasy处理时流已关闭。 - 可通过
HttpServletRequestWrapper包装请求,缓存请求体内容,实现流的重复读取。
3. 容器与线程安全排查
- 检查JBoss 5的Connector配置(
server/default/deploy/jbossweb.sar/server.xml),确认maxThreads、connectionTimeout等参数是否合理,避免线程池耗尽或连接超时导致流被强制关闭。 - 排查自定义的RESTEasy MessageBodyReader是否存在线程不安全的共享状态,这类问题极易引发间歇性错误。
4. 日志与调试增强
- 开启RESTEasy和Jackson的DEBUG日志,添加如下配置:
跟踪请求体读取的完整流程,定位流被关闭的具体时机。log4j.logger.org.jboss.resteasy=DEBUG log4j.logger.org.codehaus.jackson=DEBUG - 在可疑的Filter、Interceptor中添加日志,记录流的读取状态,确认是否存在提前关闭流的操作。
内容的提问来源于stack exchange,提问作者Nivid
相关产品推荐
相关产品推荐

