You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Martijn Brinkers <m....@gmail.com> on 2008/07/09 23:36:49 UTC
T5: java.util.ConcurrentModificationException
On one page I use a persistent Hashmap. The page contains an actionLink
with a click event handler. The onclick event is activated with a delay
using setTimeout. When the event is fired another actionLink is
activated. Now what happens is that during the handling of the first
actionLink the second actionLink is activated and this results in a
ConcurrentModificationException on the Hashmap. I can solve it by using
a multithread safe Hashmap but I want to understand under what
circumstances you need to be carefull for multi threaded activation
(with Tapestry 5 that is). Should a Persisted variable always be
multithread safe? I think so but what other Tapestry related items
should be multithread safe as well?
Martijn
Stack trace:
java.util.ConcurrentModificationException
Stack trace
* java.util.HashMap
$HashIterator.nextEntry(HashMap.java:793)
* java.util.HashMap$KeyIterator.next(HashMap.java:828)
* mitm.mimesecure.web.components.CertificateStoreGrid.downloadSelected(CertificateStoreGrid.java:76)
* mitm.mimesecure.web.components.CertificateStoreGrid.dispatchComponentEvent(CertificateStoreGrid.java)
* org.apache.tapestry5.internal.structure.ComponentPageElementImpl.dispatchEvent(ComponentPageElementImpl.java:864)
* org.apache.tapestry5.internal.structure.ComponentPageElementImpl.triggerContextEvent(ComponentPageElementImpl.java:1025)
* org.apache.tapestry5.internal.services.ComponentEventRequestHandlerImpl.handle(ComponentEventRequestHandlerImpl.java:67)
* org.apache.tapestry5.internal.services.ImmediateActionRenderResponseFilter.handle(ImmediateActionRenderResponseFilter.java:42)
* org.apache.tapestry5.internal.services.AjaxFilter.handle(AjaxFilter.java:42)
* org.apache.tapestry5.services.TapestryModule
$37.handle(TapestryModule.java:1987)
* org.apache.tapestry5.internal.services.ComponentEventDispatcher.dispatch(ComponentEventDispatcher.java:135)
* org.apache.tapestry5.services.TapestryModule
$12.service(TapestryModule.java:938)
* org.apache.tapestry5.internal.services.LocalizationFilter.service(LocalizationFilter.java:42)
* org.apache.tapestry5.services.TapestryModule
$2.service(TapestryModule.java:586)
* org.apache.tapestry5.internal.services.RequestErrorFilter.service(RequestErrorFilter.java:26)
* org.apache.tapestry5.internal.services.StaticFilesFilter.service(StaticFilesFilter.java:79)
* org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:93)
* org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:84)
* org.apache.tapestry5.ioc.internal.util.ConcurrentBarrier.withRead(ConcurrentBarrier.java:75)
* org.apache.tapestry5.internal.services.CheckForUpdatesFilter.service(CheckForUpdatesFilter.java:106)
* org.apache.tapestry5.services.TapestryModule
$11.service(TapestryModule.java:918)
* org.apache.tapestry5.upload.internal.services.MultipartServletRequestFilter.service(MultipartServletRequestFilter.java:44)
* org.apache.tapestry5.internal.services.IgnoredPathsFilter.service(IgnoredPathsFilter.java:62)
* org.apache.tapestry5.TapestryFilter.doFilter(TapestryFilter.java:168)
* org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1084)
* org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
* org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
* org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
* org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
* org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
* org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
* org.mortbay.jetty.Server.handle(Server.java:324)
* org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
* org.mortbay.jetty.HttpConnection
$RequestHandler.headerComplete(HttpConnection.java:828)
* org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
* org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
* org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
* org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
* org.mortbay.thread.BoundedThreadPool
$PoolThread.run(BoundedThreadPool.java:450)
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: T5: java.util.ConcurrentModificationException
Posted by Fernando Padilla <fe...@alum.mit.edu>.
Also, maybe you should be using ConcurrentHashMap or other classes
specifically made for multi-threaded access. And if you review the
javadoc for that class, I think they discuss how they handle iterators
in a multi-thread safe manner..
Howard Lewis Ship wrote:
> Does raise an interesting point.
>
> In a traditional page app, you would rarely have request overlap. It
> was possible (a wildly clicking user, perhaps). Often the main page
> would be one request, followed by a series of overlapping requests to
> retrieve static assets.
>
> It would be possible to add a filter to the page and component event
> request chains that would single-thread requests for any specific
> session.
>
> That would raise some additional problems; for example, an earlier
> user ran afoul of Tapestry's existing code (that single threads the
> system periodically, to check to see if any resources on the file
> system changed). They had a window where process of one request would
> "loop back" as a new request and thus two threads could end up
> deadlocked.
>
> So it does seem to me that if you are using Ajax techniques and thus
> explicitly asynchronous access to the application, you should be
> mindful of this. We could bounce around some ideas as to how the
> framework could assist: perhaps a per-session/per-page lock?
>
> On Wed, Jul 9, 2008 at 2:36 PM, Martijn Brinkers <m....@gmail.com> wrote:
>> On one page I use a persistent Hashmap. The page contains an actionLink
>> with a click event handler. The onclick event is activated with a delay
>> using setTimeout. When the event is fired another actionLink is
>> activated. Now what happens is that during the handling of the first
>> actionLink the second actionLink is activated and this results in a
>> ConcurrentModificationException on the Hashmap. I can solve it by using
>> a multithread safe Hashmap but I want to understand under what
>> circumstances you need to be carefull for multi threaded activation
>> (with Tapestry 5 that is). Should a Persisted variable always be
>> multithread safe? I think so but what other Tapestry related items
>> should be multithread safe as well?
>>
>> Martijn
>>
>> Stack trace:
>>
>> java.util.ConcurrentModificationException
>> Stack trace
>> * java.util.HashMap
>> $HashIterator.nextEntry(HashMap.java:793)
>> * java.util.HashMap$KeyIterator.next(HashMap.java:828)
>> * mitm.mimesecure.web.components.CertificateStoreGrid.downloadSelected(CertificateStoreGrid.java:76)
>> * mitm.mimesecure.web.components.CertificateStoreGrid.dispatchComponentEvent(CertificateStoreGrid.java)
>> * org.apache.tapestry5.internal.structure.ComponentPageElementImpl.dispatchEvent(ComponentPageElementImpl.java:864)
>> * org.apache.tapestry5.internal.structure.ComponentPageElementImpl.triggerContextEvent(ComponentPageElementImpl.java:1025)
>> * org.apache.tapestry5.internal.services.ComponentEventRequestHandlerImpl.handle(ComponentEventRequestHandlerImpl.java:67)
>> * org.apache.tapestry5.internal.services.ImmediateActionRenderResponseFilter.handle(ImmediateActionRenderResponseFilter.java:42)
>> * org.apache.tapestry5.internal.services.AjaxFilter.handle(AjaxFilter.java:42)
>> * org.apache.tapestry5.services.TapestryModule
>> $37.handle(TapestryModule.java:1987)
>> * org.apache.tapestry5.internal.services.ComponentEventDispatcher.dispatch(ComponentEventDispatcher.java:135)
>> * org.apache.tapestry5.services.TapestryModule
>> $12.service(TapestryModule.java:938)
>> * org.apache.tapestry5.internal.services.LocalizationFilter.service(LocalizationFilter.java:42)
>> * org.apache.tapestry5.services.TapestryModule
>> $2.service(TapestryModule.java:586)
>> * org.apache.tapestry5.internal.services.RequestErrorFilter.service(RequestErrorFilter.java:26)
>> * org.apache.tapestry5.internal.services.StaticFilesFilter.service(StaticFilesFilter.java:79)
>> * org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:93)
>> * org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:84)
>> * org.apache.tapestry5.ioc.internal.util.ConcurrentBarrier.withRead(ConcurrentBarrier.java:75)
>> * org.apache.tapestry5.internal.services.CheckForUpdatesFilter.service(CheckForUpdatesFilter.java:106)
>> * org.apache.tapestry5.services.TapestryModule
>> $11.service(TapestryModule.java:918)
>> * org.apache.tapestry5.upload.internal.services.MultipartServletRequestFilter.service(MultipartServletRequestFilter.java:44)
>> * org.apache.tapestry5.internal.services.IgnoredPathsFilter.service(IgnoredPathsFilter.java:62)
>> * org.apache.tapestry5.TapestryFilter.doFilter(TapestryFilter.java:168)
>> * org.mortbay.jetty.servlet.ServletHandler
>> $CachedChain.doFilter(ServletHandler.java:1084)
>> * org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
>> * org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
>> * org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>> * org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
>> * org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
>> * org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>> * org.mortbay.jetty.Server.handle(Server.java:324)
>> * org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
>> * org.mortbay.jetty.HttpConnection
>> $RequestHandler.headerComplete(HttpConnection.java:828)
>> * org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
>> * org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
>> * org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
>> * org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
>> * org.mortbay.thread.BoundedThreadPool
>> $PoolThread.run(BoundedThreadPool.java:450)
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: T5: java.util.ConcurrentModificationException
Posted by Howard Lewis Ship <hl...@gmail.com>.
ASOs are specified in terms of implementation classes, not interfaces.
That makes it more awkward and error prone to create a proxy for them
(you have to create a subclass and hit all the non-private methods and
make them delegate, and there can be issues concerning constructors
that get in the way).
I'd prefer to find a solution, if necessary, that wrapped around all
the code paths that could be accessing a shared resource such as an
ASO. One coarse lock, not many small (and potentially deadlocking)
ones.
On Wed, Jul 9, 2008 at 3:10 PM, Martijn Brinkers <m....@gmail.com> wrote:
>
>> So it does seem to me that if you are using Ajax techniques and thus
>> explicitly asynchronous access to the application, you should be
>> mindful of this. We could bounce around some ideas as to how the
>> framework could assist: perhaps a per-session/per-page lock?
>
> A per-session/per-page lock still allows concurrent access to ASO's I
> guess?
> I think that making any 'globally' accessible objects (ie Persisted
> objects, ASO's...?) thread safe is the safest choice but I'm not sure if
> that works for everyone. Would it be possible to automatically create a
> thread safe wrapper (proxy) for a Persisted object (and ASO) that only
> allows single threaded access to that object? Trigger the auto wrapper
> when a specific annotation is added to the persisted object like
> @ThreadSafe (or something like that). You can then choose to make the
> object thread safe by yourself or let Tapestry make a thread safe
> wrapper for you.
>
> Martijn
>
> On Wed, 2008-07-09 at 14:48 -0700, Howard Lewis Ship wrote:
>> Does raise an interesting point.
>>
>> In a traditional page app, you would rarely have request overlap. It
>> was possible (a wildly clicking user, perhaps). Often the main page
>> would be one request, followed by a series of overlapping requests to
>> retrieve static assets.
>>
>> It would be possible to add a filter to the page and component event
>> request chains that would single-thread requests for any specific
>> session.
>>
>> That would raise some additional problems; for example, an earlier
>> user ran afoul of Tapestry's existing code (that single threads the
>> system periodically, to check to see if any resources on the file
>> system changed). They had a window where process of one request would
>> "loop back" as a new request and thus two threads could end up
>> deadlocked.
>>
>> So it does seem to me that if you are using Ajax techniques and thus
>> explicitly asynchronous access to the application, you should be
>> mindful of this. We could bounce around some ideas as to how the
>> framework could assist: perhaps a per-session/per-page lock?
>>
>> On Wed, Jul 9, 2008 at 2:36 PM, Martijn Brinkers <m....@gmail.com> wrote:
>> > On one page I use a persistent Hashmap. The page contains an actionLink
>> > with a click event handler. The onclick event is activated with a delay
>> > using setTimeout. When the event is fired another actionLink is
>> > activated. Now what happens is that during the handling of the first
>> > actionLink the second actionLink is activated and this results in a
>> > ConcurrentModificationException on the Hashmap. I can solve it by using
>> > a multithread safe Hashmap but I want to understand under what
>> > circumstances you need to be carefull for multi threaded activation
>> > (with Tapestry 5 that is). Should a Persisted variable always be
>> > multithread safe? I think so but what other Tapestry related items
>> > should be multithread safe as well?
>> >
>> > Martijn
>> >
>> > Stack trace:
>> >
>> > java.util.ConcurrentModificationException
>> > Stack trace
>> > * java.util.HashMap
>> > $HashIterator.nextEntry(HashMap.java:793)
>> > * java.util.HashMap$KeyIterator.next(HashMap.java:828)
>> > * mitm.mimesecure.web.components.CertificateStoreGrid.downloadSelected(CertificateStoreGrid.java:76)
>> > * mitm.mimesecure.web.components.CertificateStoreGrid.dispatchComponentEvent(CertificateStoreGrid.java)
>> > * org.apache.tapestry5.internal.structure.ComponentPageElementImpl.dispatchEvent(ComponentPageElementImpl.java:864)
>> > * org.apache.tapestry5.internal.structure.ComponentPageElementImpl.triggerContextEvent(ComponentPageElementImpl.java:1025)
>> > * org.apache.tapestry5.internal.services.ComponentEventRequestHandlerImpl.handle(ComponentEventRequestHandlerImpl.java:67)
>> > * org.apache.tapestry5.internal.services.ImmediateActionRenderResponseFilter.handle(ImmediateActionRenderResponseFilter.java:42)
>> > * org.apache.tapestry5.internal.services.AjaxFilter.handle(AjaxFilter.java:42)
>> > * org.apache.tapestry5.services.TapestryModule
>> > $37.handle(TapestryModule.java:1987)
>> > * org.apache.tapestry5.internal.services.ComponentEventDispatcher.dispatch(ComponentEventDispatcher.java:135)
>> > * org.apache.tapestry5.services.TapestryModule
>> > $12.service(TapestryModule.java:938)
>> > * org.apache.tapestry5.internal.services.LocalizationFilter.service(LocalizationFilter.java:42)
>> > * org.apache.tapestry5.services.TapestryModule
>> > $2.service(TapestryModule.java:586)
>> > * org.apache.tapestry5.internal.services.RequestErrorFilter.service(RequestErrorFilter.java:26)
>> > * org.apache.tapestry5.internal.services.StaticFilesFilter.service(StaticFilesFilter.java:79)
>> > * org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:93)
>> > * org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:84)
>> > * org.apache.tapestry5.ioc.internal.util.ConcurrentBarrier.withRead(ConcurrentBarrier.java:75)
>> > * org.apache.tapestry5.internal.services.CheckForUpdatesFilter.service(CheckForUpdatesFilter.java:106)
>> > * org.apache.tapestry5.services.TapestryModule
>> > $11.service(TapestryModule.java:918)
>> > * org.apache.tapestry5.upload.internal.services.MultipartServletRequestFilter.service(MultipartServletRequestFilter.java:44)
>> > * org.apache.tapestry5.internal.services.IgnoredPathsFilter.service(IgnoredPathsFilter.java:62)
>> > * org.apache.tapestry5.TapestryFilter.doFilter(TapestryFilter.java:168)
>> > * org.mortbay.jetty.servlet.ServletHandler
>> > $CachedChain.doFilter(ServletHandler.java:1084)
>> > * org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
>> > * org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
>> > * org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>> > * org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
>> > * org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
>> > * org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>> > * org.mortbay.jetty.Server.handle(Server.java:324)
>> > * org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
>> > * org.mortbay.jetty.HttpConnection
>> > $RequestHandler.headerComplete(HttpConnection.java:828)
>> > * org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
>> > * org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
>> > * org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
>> > * org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
>> > * org.mortbay.thread.BoundedThreadPool
>> > $PoolThread.run(BoundedThreadPool.java:450)
>> >
>> >
>> > ---------------------------------------------------------------------
>> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> > For additional commands, e-mail: users-help@tapestry.apache.org
>> >
>> >
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>
--
Howard M. Lewis Ship
Creator Apache Tapestry and Apache HiveMind
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: T5: java.util.ConcurrentModificationException
Posted by Martijn Brinkers <m....@gmail.com>.
> So it does seem to me that if you are using Ajax techniques and thus
> explicitly asynchronous access to the application, you should be
> mindful of this. We could bounce around some ideas as to how the
> framework could assist: perhaps a per-session/per-page lock?
A per-session/per-page lock still allows concurrent access to ASO's I
guess?
I think that making any 'globally' accessible objects (ie Persisted
objects, ASO's...?) thread safe is the safest choice but I'm not sure if
that works for everyone. Would it be possible to automatically create a
thread safe wrapper (proxy) for a Persisted object (and ASO) that only
allows single threaded access to that object? Trigger the auto wrapper
when a specific annotation is added to the persisted object like
@ThreadSafe (or something like that). You can then choose to make the
object thread safe by yourself or let Tapestry make a thread safe
wrapper for you.
Martijn
On Wed, 2008-07-09 at 14:48 -0700, Howard Lewis Ship wrote:
> Does raise an interesting point.
>
> In a traditional page app, you would rarely have request overlap. It
> was possible (a wildly clicking user, perhaps). Often the main page
> would be one request, followed by a series of overlapping requests to
> retrieve static assets.
>
> It would be possible to add a filter to the page and component event
> request chains that would single-thread requests for any specific
> session.
>
> That would raise some additional problems; for example, an earlier
> user ran afoul of Tapestry's existing code (that single threads the
> system periodically, to check to see if any resources on the file
> system changed). They had a window where process of one request would
> "loop back" as a new request and thus two threads could end up
> deadlocked.
>
> So it does seem to me that if you are using Ajax techniques and thus
> explicitly asynchronous access to the application, you should be
> mindful of this. We could bounce around some ideas as to how the
> framework could assist: perhaps a per-session/per-page lock?
>
> On Wed, Jul 9, 2008 at 2:36 PM, Martijn Brinkers <m....@gmail.com> wrote:
> > On one page I use a persistent Hashmap. The page contains an actionLink
> > with a click event handler. The onclick event is activated with a delay
> > using setTimeout. When the event is fired another actionLink is
> > activated. Now what happens is that during the handling of the first
> > actionLink the second actionLink is activated and this results in a
> > ConcurrentModificationException on the Hashmap. I can solve it by using
> > a multithread safe Hashmap but I want to understand under what
> > circumstances you need to be carefull for multi threaded activation
> > (with Tapestry 5 that is). Should a Persisted variable always be
> > multithread safe? I think so but what other Tapestry related items
> > should be multithread safe as well?
> >
> > Martijn
> >
> > Stack trace:
> >
> > java.util.ConcurrentModificationException
> > Stack trace
> > * java.util.HashMap
> > $HashIterator.nextEntry(HashMap.java:793)
> > * java.util.HashMap$KeyIterator.next(HashMap.java:828)
> > * mitm.mimesecure.web.components.CertificateStoreGrid.downloadSelected(CertificateStoreGrid.java:76)
> > * mitm.mimesecure.web.components.CertificateStoreGrid.dispatchComponentEvent(CertificateStoreGrid.java)
> > * org.apache.tapestry5.internal.structure.ComponentPageElementImpl.dispatchEvent(ComponentPageElementImpl.java:864)
> > * org.apache.tapestry5.internal.structure.ComponentPageElementImpl.triggerContextEvent(ComponentPageElementImpl.java:1025)
> > * org.apache.tapestry5.internal.services.ComponentEventRequestHandlerImpl.handle(ComponentEventRequestHandlerImpl.java:67)
> > * org.apache.tapestry5.internal.services.ImmediateActionRenderResponseFilter.handle(ImmediateActionRenderResponseFilter.java:42)
> > * org.apache.tapestry5.internal.services.AjaxFilter.handle(AjaxFilter.java:42)
> > * org.apache.tapestry5.services.TapestryModule
> > $37.handle(TapestryModule.java:1987)
> > * org.apache.tapestry5.internal.services.ComponentEventDispatcher.dispatch(ComponentEventDispatcher.java:135)
> > * org.apache.tapestry5.services.TapestryModule
> > $12.service(TapestryModule.java:938)
> > * org.apache.tapestry5.internal.services.LocalizationFilter.service(LocalizationFilter.java:42)
> > * org.apache.tapestry5.services.TapestryModule
> > $2.service(TapestryModule.java:586)
> > * org.apache.tapestry5.internal.services.RequestErrorFilter.service(RequestErrorFilter.java:26)
> > * org.apache.tapestry5.internal.services.StaticFilesFilter.service(StaticFilesFilter.java:79)
> > * org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:93)
> > * org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:84)
> > * org.apache.tapestry5.ioc.internal.util.ConcurrentBarrier.withRead(ConcurrentBarrier.java:75)
> > * org.apache.tapestry5.internal.services.CheckForUpdatesFilter.service(CheckForUpdatesFilter.java:106)
> > * org.apache.tapestry5.services.TapestryModule
> > $11.service(TapestryModule.java:918)
> > * org.apache.tapestry5.upload.internal.services.MultipartServletRequestFilter.service(MultipartServletRequestFilter.java:44)
> > * org.apache.tapestry5.internal.services.IgnoredPathsFilter.service(IgnoredPathsFilter.java:62)
> > * org.apache.tapestry5.TapestryFilter.doFilter(TapestryFilter.java:168)
> > * org.mortbay.jetty.servlet.ServletHandler
> > $CachedChain.doFilter(ServletHandler.java:1084)
> > * org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
> > * org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
> > * org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
> > * org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
> > * org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
> > * org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
> > * org.mortbay.jetty.Server.handle(Server.java:324)
> > * org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
> > * org.mortbay.jetty.HttpConnection
> > $RequestHandler.headerComplete(HttpConnection.java:828)
> > * org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
> > * org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
> > * org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
> > * org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
> > * org.mortbay.thread.BoundedThreadPool
> > $PoolThread.run(BoundedThreadPool.java:450)
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
> >
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: T5: java.util.ConcurrentModificationException
Posted by Howard Lewis Ship <hl...@gmail.com>.
Does raise an interesting point.
In a traditional page app, you would rarely have request overlap. It
was possible (a wildly clicking user, perhaps). Often the main page
would be one request, followed by a series of overlapping requests to
retrieve static assets.
It would be possible to add a filter to the page and component event
request chains that would single-thread requests for any specific
session.
That would raise some additional problems; for example, an earlier
user ran afoul of Tapestry's existing code (that single threads the
system periodically, to check to see if any resources on the file
system changed). They had a window where process of one request would
"loop back" as a new request and thus two threads could end up
deadlocked.
So it does seem to me that if you are using Ajax techniques and thus
explicitly asynchronous access to the application, you should be
mindful of this. We could bounce around some ideas as to how the
framework could assist: perhaps a per-session/per-page lock?
On Wed, Jul 9, 2008 at 2:36 PM, Martijn Brinkers <m....@gmail.com> wrote:
> On one page I use a persistent Hashmap. The page contains an actionLink
> with a click event handler. The onclick event is activated with a delay
> using setTimeout. When the event is fired another actionLink is
> activated. Now what happens is that during the handling of the first
> actionLink the second actionLink is activated and this results in a
> ConcurrentModificationException on the Hashmap. I can solve it by using
> a multithread safe Hashmap but I want to understand under what
> circumstances you need to be carefull for multi threaded activation
> (with Tapestry 5 that is). Should a Persisted variable always be
> multithread safe? I think so but what other Tapestry related items
> should be multithread safe as well?
>
> Martijn
>
> Stack trace:
>
> java.util.ConcurrentModificationException
> Stack trace
> * java.util.HashMap
> $HashIterator.nextEntry(HashMap.java:793)
> * java.util.HashMap$KeyIterator.next(HashMap.java:828)
> * mitm.mimesecure.web.components.CertificateStoreGrid.downloadSelected(CertificateStoreGrid.java:76)
> * mitm.mimesecure.web.components.CertificateStoreGrid.dispatchComponentEvent(CertificateStoreGrid.java)
> * org.apache.tapestry5.internal.structure.ComponentPageElementImpl.dispatchEvent(ComponentPageElementImpl.java:864)
> * org.apache.tapestry5.internal.structure.ComponentPageElementImpl.triggerContextEvent(ComponentPageElementImpl.java:1025)
> * org.apache.tapestry5.internal.services.ComponentEventRequestHandlerImpl.handle(ComponentEventRequestHandlerImpl.java:67)
> * org.apache.tapestry5.internal.services.ImmediateActionRenderResponseFilter.handle(ImmediateActionRenderResponseFilter.java:42)
> * org.apache.tapestry5.internal.services.AjaxFilter.handle(AjaxFilter.java:42)
> * org.apache.tapestry5.services.TapestryModule
> $37.handle(TapestryModule.java:1987)
> * org.apache.tapestry5.internal.services.ComponentEventDispatcher.dispatch(ComponentEventDispatcher.java:135)
> * org.apache.tapestry5.services.TapestryModule
> $12.service(TapestryModule.java:938)
> * org.apache.tapestry5.internal.services.LocalizationFilter.service(LocalizationFilter.java:42)
> * org.apache.tapestry5.services.TapestryModule
> $2.service(TapestryModule.java:586)
> * org.apache.tapestry5.internal.services.RequestErrorFilter.service(RequestErrorFilter.java:26)
> * org.apache.tapestry5.internal.services.StaticFilesFilter.service(StaticFilesFilter.java:79)
> * org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:93)
> * org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:84)
> * org.apache.tapestry5.ioc.internal.util.ConcurrentBarrier.withRead(ConcurrentBarrier.java:75)
> * org.apache.tapestry5.internal.services.CheckForUpdatesFilter.service(CheckForUpdatesFilter.java:106)
> * org.apache.tapestry5.services.TapestryModule
> $11.service(TapestryModule.java:918)
> * org.apache.tapestry5.upload.internal.services.MultipartServletRequestFilter.service(MultipartServletRequestFilter.java:44)
> * org.apache.tapestry5.internal.services.IgnoredPathsFilter.service(IgnoredPathsFilter.java:62)
> * org.apache.tapestry5.TapestryFilter.doFilter(TapestryFilter.java:168)
> * org.mortbay.jetty.servlet.ServletHandler
> $CachedChain.doFilter(ServletHandler.java:1084)
> * org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
> * org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
> * org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
> * org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
> * org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
> * org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
> * org.mortbay.jetty.Server.handle(Server.java:324)
> * org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
> * org.mortbay.jetty.HttpConnection
> $RequestHandler.headerComplete(HttpConnection.java:828)
> * org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
> * org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
> * org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
> * org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
> * org.mortbay.thread.BoundedThreadPool
> $PoolThread.run(BoundedThreadPool.java:450)
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>
--
Howard M. Lewis Ship
Creator Apache Tapestry and Apache HiveMind
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org