在JSF saveState()

时间:2015-10-01 03:35:03

标签: java multithreading jsf

我们的生产环境存在问题,4个线程的HTOP命令处于100%CPU使用率。为了进一步研究这个问题,我生成了一个Thread转储,以便找到正在吃CPU的线程。

这是我发现的。 4个线程具有相同的堆栈跟踪,所有这些都处于 RUNNABLE 状态。不幸的是,我陷入了调查,因为堆栈跟踪没有引用我的内部代码,它更多地在Richfaces方面。我认为这是JSF呈现页面的部分。

堆栈跟踪。

  

"ajp-0.0.0.0-8009-47" daemon prio=10 tid=0x00007fb8040af000 nid=0x172c runnable [0x00007fb8b3bf8000]
   java.lang.Thread.State: RUNNABLE
    at java.util.HashMap.hash(HashMap.java:351)
    at java.util.HashMap.putForCreate(HashMap.java:512)
    at java.util.HashMap.putAllForCreate(HashMap.java:534)
    at java.util.HashMap.<init>(HashMap.java:320)
    at org.ajax4jsf.component.UIDataAdaptorBase.createChildStateCopy(UIDataAdaptorBase.java:894)
    at org.ajax4jsf.component.UIDataAdaptorBase.saveState(UIDataAdaptorBase.java:1554)
    at org.richfaces.component.UIDataTable.saveState(UIDataTable.java:181)
    at org.richfaces.component.html.HtmlDataTable.saveState(HtmlDataTable.java:1361)
    at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1103)
    at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
    at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
    at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
    at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
    at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
    at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
    at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1119)
    at org.ajax4jsf.component.AjaxViewRoot.processSaveState(AjaxViewRoot.java:751)
    at org.ajax4jsf.application.AjaxStateManager.getComponentStateToSave(AjaxStateManager.java:179)
    at org.ajax4jsf.application.AjaxStateManager.buildViewState(AjaxStateManager.java:515)
    at org.ajax4jsf.application.AjaxStateManager$SeamStateManagerWrapper.saveView(AjaxStateManager.java:106)
    at org.jboss.seam.jsf.SeamStateManager.saveView(SeamStateManager.java:89)
    at org.ajax4jsf.application.AjaxStateManager.saveSerializedView(AjaxStateManager.java:470)
    at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:615)
    at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
    at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.josso.servlet.agent.GenericServletSSOAgentFilter.doFilter(GenericServletSSOAgentFilter.java:558)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    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.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:73)
    at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:73)
    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.web.MultipartFilter.doFilter(MultipartFilter.java:90)
    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.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:206)
    at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
    at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
    at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
    at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
    at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
    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.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:722)

另一件事是,我有没有办法进入堆栈跟踪,让我说我想生成一个日志,以便我可以告诉我的应用程序中哪个页面正在生成这个堆栈跟踪?或者也许我可以使用阶段监听器?

任何帮助将不胜感激。 谢谢。

我正在使用Seam 2.2,Richfaces 3.3.3 final,JSF 1.2。

2 个答案:

答案 0 :(得分:7)

此,

java.lang.Thread.State: RUNNABLE
    at java.util.HashMap.hash(HashMap.java:351)
    at java.util.HashMap.putForCreate(HashMap.java:512)
    at java.util.HashMap.putAllForCreate(HashMap.java:534)
    at java.util.HashMap.<init>(HashMap.java:320)

这个,

java.lang.Thread.State: RUNNABLE
    at java.util.HashMap.getEntry(HashMap.java:446)
    at java.util.HashMap.get(HashMap.java:405)
当一个线程调用java.util.HashMap而另一个线程同时执行get()时,

put()的已知线程安全问题。线程将在计算哈希期间陷入无限循环。此问题的技术解决方案是使用ConcurrentMap实现。另见a.o. this dzone article

但是,在您的具体情况下,

    at java.util.HashMap.<init>(HashMap.java:320)
    at org.ajax4jsf.component.UIDataAdaptorBase.createChildStateCopy(UIDataAdaptorBase.java:894)
    at org.ajax4jsf.component.UIDataAdaptorBase.saveState(UIDataAdaptorBase.java:1554)
    at org.richfaces.component.UIDataTable.saveState(UIDataTable.java:181)
    at org.richfaces.component.html.HtmlDataTable.saveState(HtmlDataTable.java:1361)
    at javax.faces.component.UIComponentBase.processSaveState(UIComponentBase.java:1103)

当您要保存<rich:dataTable>组件的状态时,似乎会出现此问题。这反过来表明多个线程正在访问组件的相同实例。这是不对的,UIComponent类首先从未设计为线程安全。这反过来表明所讨论的组件实例不是JSF规范要求的请求范围。例如,当您使用binding将组件绑定到作用域的会话或甚至是应用程序范围的bean,或者更糟的是静态字段时,就会发生这种情况。

<x:someComponent ... binding="#{nonRequestScopedBean.someComponent}">

您应该在您的代码库中寻找这样的组件并通过确保bean是请求作用域来相应地修复它,或者通过使用不同的解决方案来解决您认为使用binding这个问题的问题方式将是正确的解决方案。

另见:

答案 1 :(得分:0)

经过长时间的分析,我的问题得到了解决。

因为我们使用的是jsf 2.1.7版本,所以在2.1.7版本中使用hashmap实现了UI重复。因此,当我们使用嵌套的ui重复cpu很高时。 现在应用程序正在运行,我已经用JSTL替换了ui repeat。

您也可以使用其他方式,您需要更改JSF 2.2.4或更高版本。