代码之家  ›  专栏  ›  技术社区  ›  kraftan

在tomcat请求的parseparameters期间间歇性npe

  •  1
  • kraftan  · 技术社区  · 14 年前

    在org.apache.catalina.connector.request中的ParsePareters期间,我们有间歇性NPE。在线用户越多,npe发生的次数就越多。在jboss重启之后,npe会消失一段时间。在24小时内,我们将收到其中一个到400多个NPE。调用哪个服务并不重要。任何服务请求都可以在此npe中结束。

    java.lang.NullPointerException
            at org.apache.catalina.connector.Request.parseParameters(Request.java:2517)
            at org.apache.catalina.connector.Request.getParameterNames(Request.java:1102)
            at org.apache.catalina.connector.Request.getParameterMap(Request.java:1082)
            at org.apache.catalina.connector.RequestFacade.getParameterMap(RequestFacade.java:414)
            at javax.servlet.ServletRequestWrapper.getParameterMap(ServletRequestWrapper.java:166)
            at org.jboss.seam.mock.MockExternalContext.getRequestParameterValuesMap(MockExternalContext.java:307)
            at org.jboss.seam.faces.Parameters.getRequestParameters(Parameters.java:61)
            at org.jboss.seam.Component.injectParameters(Component.java:1586)
            at org.jboss.seam.Component.inject(Component.java:1556)
            at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:61)
            at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
            at org.jboss.seam.transaction.TransactionInterceptor$1.work(TransactionInterceptor.java:97)
            at org.jboss.seam.util.Work.workInTransaction(Work.java:61)
            at org.jboss.seam.transaction.TransactionInterceptor.aroundInvoke(TransactionInterceptor.java:91)
            at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
            at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
            at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
            at org.jboss.seam.security.SecurityInterceptor.aroundInvoke(SecurityInterceptor.java:163)
            at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
            at ExceptionInterceptor.aroundInvoke(ExceptionInterceptor.java:51)
            at sun.reflect.GeneratedMethodAccessor289.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:597)
            at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
            at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:187)
            at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:72)
            at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
            at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:185)
            at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:103)
            at TaskService_$$_javassist_seam_7.getNumberOfUpdatedTasks(TaskService_$$_javassist_seam_7.java)
            at sun.reflect.GeneratedMethodAccessor319.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:597)
            at org.jboss.seam.remoting.gwt.GWTToSeamAdapter.callWebRemoteMethod(GWTToSeamAdapter.java:100)
            at org.jboss.seam.remoting.gwt.GWTService.RPC_invokeAndEncodeResponse(GWTService.java:550)
            at org.jboss.seam.remoting.gwt.GWTService.processCall(GWTService.java:206)
            at org.jboss.seam.remoting.gwt.GWTService$1.process(GWTService.java:120)
            at org.jboss.seam.servlet.ContextualHttpServletRequest.run(ContextualHttpServletRequest.java:53)
            at org.jboss.seam.remoting.gwt.GWTService.getResource(GWTService.java:105)
            at org.jboss.seam.servlet.SeamResourceServlet.service(SeamResourceServlet.java:80)
            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.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
            at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
            at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
            at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
            at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
            at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
            at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
            at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
            at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
            at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:73)
            at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
            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.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
            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.ajp.AjpProcessor.process(AjpProcessor.java:436)
            at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:384)
            at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
            at java.lang.Thread.run(Thread.java:619)
    

    我们使用jboss as 5.1.0.ga、seam 2.2.0.ga和gwt2.0.3。jboss通过mod_jk接收apache 2的请求。所提供的行号(请求.java:2517)指示请求的方法为空,尽管Fixbug(客户端)、Apache和MODYJK的日志显示该方法是POST。

    目前,我们既不知道什么可能是npe的根本原因,也不知道我们如何能作出一个解决办法。我们在猜测这个问题是否与以下因素有关:

    • 垃圾收集(jboss以-dsun.rmi.dgc.client.gcinterval=3600000-dsun.rmi.dgc.server.gcinterval=3600000启动)
    • 在tomcat中请求回收
    • tomcat中的过滤链回收
    • mod_jk平衡

    我们怎样才能找到这个问题的原因?这个问题有什么可能的解决办法吗?

    任何帮助或建议都是非常感谢的。

    谢谢!

    ——

    我们很幸运,能够在npe期间调试堆栈跟踪。我们发现,请求对象 MockExternalContext 不总是与 SeamResourceServlet 接收。有时请求对象 模拟外部上下文 是新的,包含新实例 org.apache.coyote.Request 所有字段都设置为 null . 如果可以处理请求,则 SeamResourceServlet 与中的相同 模拟外部上下文

    请任何一位接缝专家帮助我们,告诉我们在上面的堆栈中何时何地跟踪 模拟外部上下文 是由 org.jboss.seam.faces.Parameters 是创建的?在什么情况下seam初始化 模拟外部上下文 使用新的请求对象,而不是使用 SeamResourceServlet ?

    我把这个问题交叉贴在 Seam forum .

    ——

    更新

    同时我们发现了NPE的原因:

    由于我们在客户端使用gwt,所有的客户机-服务器通信都是通过gwt-rpc异步完成的。很少,注销调用会运行另一个仍在处理的rpc。注销调用使会话无效,因此另一个rpc无法正常完成,这将导致servletlifecycle.endrequest(request);上下文HttpServletrequest中出现异常。此异常由Seam的ExceptionFilter处理。不幸的是,ExceptionFilter也无法正常完成,因为无效的会话导致以下错误:

    ERROR    [Seam Resource Servlet].error: Servlet.service() for servlet Seam Resource Servlet threw exception
    java.lang.IllegalStateException: Cannot create a session after the response has been committed
            at org.apache.catalina.connector.Request.doGetSession(Request.java:2338)
            at org.apache.catalina.connector.Request.getSession(Request.java:2094)
            at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:833)
            at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:216)
            at org.jboss.seam.mock.MockExternalContext.getSessionMap(MockExternalContext.java:357)
            at org.jboss.seam.contexts.FacesLifecycle.beginExceptionRecovery(FacesLifecycle.java:86)
            at org.jboss.seam.web.ExceptionFilter.endWebRequestAfterException(ExceptionFilter.java:96)
            at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:70)
            at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
            at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
            at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
            at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
            at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
            at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:73)
            at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
            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.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
            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.ajp.AjpProcessor.process(AjpProcessor.java:436)
            at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:384)
            at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
            at java.lang.Thread.run(Thread.java:619)
    

    在ExceptionFilter中创建的MockExternalContext“不知何故”保留在应用程序上下文中,并“有时”用于处理请求。它甚至可以在应用程序的重新部署中生存下来,因此我们必须重新启动jboss以摆脱npe。

    1 回复  |  直到 14 年前
        1
  •  1
  •   beastieboy    14 年前

    非常感谢你的这篇文章。这只虫子是我们几个星期的噩梦。我们的配置是:gwt 2.0.4,seam 2.2.1cr2,jboss as 5.1.0。我们在我们的应用程序中修补了注销机制,但它仍然会返回(尽管很少)。现在看来,当一个事务在ejb层中持续太久时,就会发生这种情况。现在我们已经准备好消除接缝了,它造成的问题比我们能处理的还要多。

    更新: 当“serviceimpl”组件的作用域从“session”更改为默认值时,这个奇怪的错误完全消失了。还添加了注释@bypassinterceptors。同时我为我们的应用程序准备了SeamGwtBridge的替换。这是guice+gwt调度。非常快速可靠的解决方案。