Hi, Yes you both are right. It looks like a race condition between stack.clear and stack.write [1]. But somehow it's odd. I was aware about this and defined them as prototype [2] so I except new instance on each request. I also can recall I tested them heavily on high concurrent load [3].
By the way, Eduardo, you also can workaround this issue for now by synchronizing access to custom.action via using java synchronized keyword inside your action method. Thanks for using Struts! Regards. [1] https://github.com/apache/struts/blob/6183fa0147affb466a9ac18f9c03b3920f3b876a/plugins/json/src/main/java/org/apache/struts2/json/DefaultJSONWriter.java#L114 [2] https://github.com/apache/struts/blob/6183fa0147affb466a9ac18f9c03b3920f3b876a/plugins/json/src/main/resources/struts-plugin.xml#L30 [3] https://github.com/apache/struts/pull/167#issuecomment-329083889 >-----Original Message----- >From: Lukasz Lenart <lukaszlen...@apache.org> >Sent: Monday, January 28, 2019 10:35 PM >To: Struts Users Mailing List <user@struts.apache.org> >Subject: Re: EmptyStackException after upgrading Struts 2.3 to 2.5 > >Hi, > >I think you are right, it's probably a side effect of changes related to this >issues > >https://issues.apache.org/jira/browse/WW-4034 > >Could you register a new JIRA ticket to fix that? > > >Regards >-- >Łukasz >+ 48 606 323 122 http://www.lenart.org.pl/ > >pon., 28 sty 2019 o 16:55 Eduardo Guadalupe <eduardo...@gmail.com> >napisał(a): >> >> I suspect there is a concurrency issue with the DefaultJSONWriter >> implementation. >> I have overridden the JSONInterceptor so a new instance of JSONUtil is used >> with every request and the issue is not happening anymore. I suppose there >> is a performance cost with that change but for now it works. >> >> https://github.com/lalo- >mx/struts/commit/ed29e3f4ed841ef13559c02da1c8dca9b68fb0a7 >> >> Does it sound reasonable what I have found? Or should I better review the >> configuration / documentation for some other change that I have not >> contemplated? >> >> On 2019/01/25 23:57:44, Eduardo Quintanilla <eduardo...@gmail.com> >wrote: >> > Hi, >> > >> > I recently upgraded Struts from version 2.3.34 to 2.5.20. After doing the >> recommended fixes the application runs correctly but an exception started >> happening sporadically. >> > >> > The app is built and runs in JDK 8 with Tomcat 9.0.12 >> > >> > The app is a little big so i have not able to create an example yet. >> > The more relevant libraries in use are Spring + Struts + Hibernate >> > >> > Any tips about how to find the root cause of the issue? >> > >> > >> > Request: >> > Request URL: https://localhost/app/rest/custom.action >> > Request Payload: {"params":["example"],"method":"load","id":1} >> > >> > Logs: >> > DefaultDispatcherErrorHandler: Exception occurred during processing >> request: null >> > java.util.EmptyStackException: null >> > at java.util.Stack.peek(Stack.java:102) ~[?:1.8.0_191] >> > at java.util.Stack.pop(Stack.java:84) ~[?:1.8.0_191] >> > at >> >org.apache.struts2.json.DefaultJSONWriter.process(DefaultJSONWriter.java:196) >> ~[struts2-json-plugin-2.5.20.jar:2.5.20] >> > at >> org.apache.struts2.json.DefaultJSONWriter.value(DefaultJSONWriter.java:154) >> ~[struts2-json-plugin-2.5.20.jar:2.5.20] >> > at >> org.apache.struts2.json.DefaultJSONWriter.write(DefaultJSONWriter.java:121) >> ~[struts2-json-plugin-2.5.20.jar:2.5.20] >> > at org.apache.struts2.json.JSONUtil.serialize(JSONUtil.java:140) >> ~[struts2-json-plugin-2.5.20.jar:2.5.20] >> > at org.apache.struts2.json.JSONUtil.serialize(JSONUtil.java:110) >> ~[struts2-json-plugin-2.5.20.jar:2.5.20] >> > at >> org.apache.struts2.json.JSONInterceptor.intercept(JSONInterceptor.java:178) >> ~[struts2-json-plugin-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(Debug >gingInterceptor.java:250) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercep >t(DefaultWorkflowInterceptor.java:179) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(Meth >odFilterInterceptor.java:99) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.doIntercept >(ConversionErrorInterceptor.java:142) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(Meth >odFilterInterceptor.java:99) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(Para >metersInterceptor.java:137) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(Meth >odFilterInterceptor.java:99) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(Para >metersInterceptor.java:137) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(Meth >odFilterInterceptor.java:99) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(S >taticParametersInterceptor.java:201) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >org.apache.struts2.interceptor.DateTextFieldInterceptor.intercept(DateTextFieldI >nterceptor.java:133) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(Mode >lDrivenInterceptor.java:101) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercep >t(ScopedModelDrivenInterceptor.java:142) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingI >nterceptor.java:160) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(Prepare >Interceptor.java:175) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(Meth >odFilterInterceptor.java:99) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >org.apache.struts2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:12 >1) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigI >nterceptor.java:167) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasIntercept >or.java:203) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept( >ExceptionMappingInterceptor.java:196) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvoc >ation.java:249) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> >org.apache.struts2.factory.StrutsActionProxy.execute(StrutsActionProxy.java:48) >> ~[struts2-core-2.5.20.jar:2.5.20] >> > at >> org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:574) >> [struts2-core-2.5.20.jar:2.5.20] >> > at >> >org.apache.struts2.dispatcher.ExecuteOperations.executeAction(ExecuteOperati >ons.java:79) >> [struts2-core-2.5.20.jar:2.5.20] > >--------------------------------------------------------------------- >To unsubscribe, e-mail: user-unsubscr...@struts.apache.org >For additional commands, e-mail: user-h...@struts.apache.org