Versions: Tapestry 4.1.6 Java 1.5.0_17 While following the performance tuning tips (http://tapestry.apache.org/tapestry4.1/developmentguide/performancetuning.html), I set the following values that control the pool sizes:
org.apache.tapestry.page-pool-max-active=30 org.apache.tapestry.page-pool-max-idle=30 After setting these parameters, I get an IllegalMonitorStateException (stack trace reproduced below) after a number of requests are successfully satisfied. Note that the line number in the stack trace might be off a little as I've been adding some logging statements to keep track of the state. I think that this is the scenario: * Now that the pool is bounded in size, the "when exhausted" logic is being executed. * The default behaviour is for the thread to block (Object.wait) until another object is released. * The wait() is being called without a corresponding synchronized block, which is what the exception means. I've reproduced this on another Tapestry 4.1.6-based project that some colleagues are working on. With their project, I have to create a small pool (max = min = 2) with a large number of concurrent requests (10, which is large relative to the size of the pool). In this scenario, I can reproduce the IllegalMonitorStateException. This raises two questions for me: 1) Is the wait() call in the "when exhausted" section of TapestryKeyedObjectPool correct? I'm concerned about the lack of obvious synchronization there. 2) Actually, the bigger question for me is this: Why is the pool exhausted so quickly? The AbstractEngine.service method has a finally block which is supposed to release objects back to the pool, but that doesn't seem to be respected in this case. Any help would be greatly appreciated. Thanks, Ben Hall java.lang.IllegalMonitorStateException: current thread not owner at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:474) at org.apache.commons.pool.impl.TapestryKeyedObjectPool.borrowObject(TapestryKeyedObjectPool.java:986) at org.apache.tapestry.pageload.PageSource.getPage(PageSource.java:176) at $IPageSource_120c3e16132.getPage($IPageSource_120c3e16132.java) at org.apache.tapestry.engine.RequestCycle.loadPage(RequestCycle.java:241) at org.apache.tapestry.engine.RequestCycle.getPage(RequestCycle.java:228) at org.apache.tapestry.engine.RequestCycle.activate(RequestCycle.java:575) at org.apache.tapestry.engine.PageService.service(PageService.java:66) at $IEngineService_120c3e161bd.service($IEngineService_120c3e161bd.java) at org.apache.tapestry.services.impl.EngineServiceOuterProxy.service(EngineServiceOuterProxy.java:72) at org.apache.tapestry.engine.AbstractEngine.service(AbstractEngine.java:241) at org.apache.tapestry.services.impl.InvokeEngineTerminator.service(InvokeEngineTerminator.java:54) at $WebRequestServicer_120c3e16198.service($WebRequestServicer_120c3e16198.java) at $WebRequestServicer_120c3e16194.service($WebRequestServicer_120c3e16194.java) at org.apache.tapestry.services.impl.WebRequestServicerPipelineBridge.service(WebRequestServicerPipelineBridge.java:61) at $ServletRequestServicer_120c3e1617a.service($ServletRequestServicer_120c3e1617a.java) at org.apache.tapestry.request.DecodedRequestInjector.service(DecodedRequestInjector.java:55) at $ServletRequestServicerFilter_120c3e16176.service($ServletRequestServicerFilter_120c3e16176.java) at $ServletRequestServicer_120c3e1617c.service($ServletRequestServicer_120c3e1617c.java) at org.apache.tapestry.multipart.MultipartDecoderFilter.service(MultipartDecoderFilter.java:52) at $ServletRequestServicerFilter_120c3e16174.service($ServletRequestServicerFilter_120c3e16174.java) at $ServletRequestServicer_120c3e1617c.service($ServletRequestServicer_120c3e1617c.java) at org.apache.tapestry.services.impl.SetupRequestEncoding.service(SetupRequestEncoding.java:53) at $ServletRequestServicerFilter_120c3e16178.service($ServletRequestServicerFilter_120c3e16178.java) at $ServletRequestServicer_120c3e1617c.service($ServletRequestServicer_120c3e1617c.java) at $ServletRequestServicer_120c3e1616e.service($ServletRequestServicer_120c3e1616e.java) at org.apache.tapestry.ApplicationServlet.doService(ApplicationServlet.java:126) at ca.COMPANY1.fs.webutil.tapestry.FSApplicationServlet.doService(FSApplicationServlet.java:21) at org.apache.tapestry.ApplicationServlet.doGet(ApplicationServlet.java:103) at javax.servlet.http.HttpServlet.service(HttpServlet.java:697) at javax.servlet.http.HttpServlet.service(HttpServlet.java:810) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:463) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:398) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301) at org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint.commence(AuthenticationProcessingFilterEntryPoint.java:138) at com.COMPANY2.rdis.investor.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint.commence(AuthenticationProcessingFilterEntryPoint.java:33) at org.acegisecurity.ui.ExceptionTranslationFilter.sendStartAuthentication(ExceptionTranslationFilter.java:208) at org.acegisecurity.ui.ExceptionTranslationFilter.handleException(ExceptionTranslationFilter.java:158) at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274) at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274) at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:217) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274) at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:229) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274) at com.COMPANY2.rdis.investor.filter.ThreadCacheFilter.doFilter(ThreadCacheFilter.java:32) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274) at ca.COMPANY1.fs.webutil.filter.FSChannelProcessingFilter.doFilter(FSChannelProcessingFilter.java:26) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274) at ca.COMPANY1.fs.performance.filter.PerformanceFilter.doFilter(PerformanceFilter.java:40) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274) at ca.COMPANY1.fs.webtestframework.servlet.filter.WebTestServletFilter.doFilter(WebTestServletFilter.java:41) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274) at ca.COMPANY1.fs.webutil.filter.EncodingFilter.doFilter(EncodingFilter.java:23) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274) at ca.COMPANY1.fs.webutil.filter.NoCacheResponseFilter.doFilter(NoCacheResponseFilter.java:25) at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274) at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:148) at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178) at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175) at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527) at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112) at java.lang.Thread.run(Thread.java:595)