[ 
https://issues.apache.org/jira/browse/WAVE-332?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13204303#comment-13204303
 ] 

Michael MacFadden commented on WAVE-332:
----------------------------------------

I think the problem might actually be in the following.  In the search method 
of the MemorySearchProvider we see these lines of code:

...
Multimap<WaveId, WaveletId> currentUserWavesView =  
createWavesViewToFilter(user, isAllQuery);
Function<ReadableWaveletData, Boolean> filterWaveletsFunction =
        createFilterWaveletsFunction(user, isAllQuery, withParticipantIds, 
creatorParticipantIds);
Map<WaveId, WaveViewData> results = 
filterWavesViewBySearchCriteria(filterWaveletsFunction, currentUserWavesView);
...

The exception we are seeing is inside the filterWavesViewBySearchCriteria in 
the following code:

...
for (WaveId waveId : currentUserWavesView.keySet()) {
...

So it seems that the issue is the modification of the key set of the 
currentUserWavesView while we are iterating over it.  Looking at the 
createWavesViewToFilter which builds this map for use we see the following:


 private Multimap<WaveId, WaveletId> createWavesViewToFilter(final 
ParticipantId user,
      final boolean isAllQuery) {
    Multimap<WaveId, WaveletId> currentUserWavesView;
    if (isAllQuery) {
      // If it is the "all" query - we need to include also waves view of the
      // shared domain participant.
      currentUserWavesView = HashMultimap.create();
      currentUserWavesView.putAll(subscriber.getPerUserWaveView(user));
      
currentUserWavesView.putAll(subscriber.getPerUserWaveView(sharedDomainParticipantId));
    } else {
      currentUserWavesView = subscriber.getPerUserWaveView(user);
    }
    return currentUserWavesView;
  }

If isAllQuery is true then we create a new map and put all of the values we 
care about in the new map.  The map is created here and only ever used in our 
method.  However is isAllQuery is false we actually return an existing map that 
is owned by the subscriber object.  This map may be modified by other processes 
at any time.

My suggestion would be to modify the code so it always creates a new map and 
copies the elements in to it.  If no one has a suggestion I will create a patch 
for this and post a code review.
                
> ConcurrentModificationException in MemorySearchProvider
> -------------------------------------------------------
>
>                 Key: WAVE-332
>                 URL: https://issues.apache.org/jira/browse/WAVE-332
>             Project: Wave
>          Issue Type: Bug
>          Components: Server
>            Reporter: Vicente J. Ruiz Jurado
>            Priority: Minor
>
> I get this error during normal use of WIAB (using trunk):
> INFO: Submit to [WaveletName localhost/w+o8UvbYIRZeA/localhost/conv+root] by 
> vjrj@localhost @ 0 with 4 ops
> 2012-02-09 02:16:55.289:WARN:oejs.ServletHandler:/search/
> java.util.ConcurrentModificationException
>         at java.util.HashMap$HashIterator.nextEntry(HashMap.java:810)
>         at java.util.HashMap$EntryIterator.next(HashMap.java:851)
>         at java.util.HashMap$EntryIterator.next(HashMap.java:849)
>         at 
> com.google.common.collect.AbstractMultimap$KeySet$1.next(AbstractMultimap.java:902)
>         at 
> org.waveprotocol.box.server.waveserver.MemorySearchProvider.filterWavesViewBySearchCriteria(MemorySearchProvider.java:166)
>         at 
> org.waveprotocol.box.server.waveserver.MemorySearchProvider.search(MemorySearchProvider.java:113)
>         at 
> org.waveprotocol.box.server.robots.operations.SearchService.search(SearchService.java:72)
>         at 
> org.waveprotocol.box.server.robots.operations.SearchService.execute(SearchService.java:62)
>         at 
> org.waveprotocol.box.server.robots.util.OperationUtil.executeOperation(OperationUtil.java:184)
>         at 
> org.waveprotocol.box.server.rpc.SearchServlet.performSearch(SearchServlet.java:189)
>         at 
> org.waveprotocol.box.server.rpc.SearchServlet.doGet(SearchServlet.java:170)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
>         at 
> org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:558)
>         at 
> org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:489)
>         at 
> org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
>         at 
> org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:520)
>         at 
> org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:233)
>         at 
> org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:972)
>         at 
> org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:417)
>         at 
> org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192)
>         at 
> org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:906)
>         at 
> org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
>         at 
> org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110)
>         at org.eclipse.jetty.server.Server.handle(Server.java:346)
>         at 
> org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:442)
>         at 
> org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:910)
>         at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:565)
>         at 
> org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:217)
>         at 
> org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:46)
>         at 
> org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:545)
>         at 
> org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:43)
>         at 
> org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:598)
>         at 
> org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:533)
>         at java.lang.Thread.run(Thread.java:679)
> 2012-02-09 02:16:55.289:DBUG:oejs.ServletHandler:[GET 
> /search/?query=in:inbox&index=0&numResults=20]@1686674510 
> org.eclipse.jetty.server.Request@64889c4e

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to