PortletStateHolder in the JBoss PortletBridge and ConcurrentModificationException

While looking through my logfiles, I found a ConcurrentModificationException in the PortletStateHolder of JBoss PortletBridge Version 1.0.0.CR1:

15:45:41,176 WARN  () [ContainerBase] Exception processing manager
org.apache.catalina.session.StandardManager@8d386e background process
java.util.ConcurrentModificationException
at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:365)
at java.util.LinkedHashMap$KeyIterator.next(LinkedHashMap.java:376)
at org.jboss.portletbridge.application.PortletStateHolder.
removeSessionStates(PortletStateHolder.java:223)
at org.jboss.portletbridge.application.PortletStateHolder.
access$200(PortletStateHolder.java:57)
at org .jboss.portletbridge.application.PortletStateHolder
$WindowIDRetriver.valueUnbound(PortletStateHolder.java:291)
at org.apache.catalina.session.StandardSession.
removeAttributeInternal(StandardSession.java:1649)
at org.apache.catalina.session.StandardSession.
expire(StandardSession.java:756)
at org.apache.catalina.session.StandardSession.
isValid(StandardSession.java:592)
at org.apache.catalina.session.ManagerBase.
processExpires(ManagerBase.java:681)
at org.apache.catalina.session.ManagerBase.
backgroundProcess(ManagerBase.java:666)
at org.apache.catalina.core.ContainerBase.
backgroundProcess(ContainerBase.java:1315)
at org.apache.catalina.core.ContainerBase$
ContainerBackgroundProcessor.processChildren(ContainerBase.java:1600)
at org.apache.catalina.core.ContainerBase$
ContainerBackgroundProcessor.processChildren(ContainerBase.java:1609)
at org.apache.catalina.core.ContainerBase$
ContainerBackgroundProcessor.processChildren(ContainerBase.java:1609)
at org.apache.catalina.core.ContainerBase$
ContainerBackgroundProcessor.run(ContainerBase.java:1589)
at java.lang.Thread.run(Thread.java:595)

This is a common Exception which is mostly thrown if an iterator is manipulated while he is in use. A quick look at the code confirmed my suspicion:

private void removeSessionStates(String scopeId) {
  synchronized (states) {
   // Iterate over copy of the keys, so LinkedHashSet do not support
   // concurrent modifications.
   for (Iterator keysIterator = states.keySet().iterator(); keysIterator
     .hasNext();) {
     StateId key = keysIterator.next();
     if (key.getScopeId().equals(scopeId)) {
       keysIterator.remove();
     }
   }
 }
}

The developer saw the problem, but forgot to make the copy of the iterator..
To fix the problem you can code copy the class and fix the method:

private void removeSessionStates(String scopeId) {
 synchronized (states) {

   // collect the ids of the states which should be removed
   ArrayList toDelKeys = new ArrayList(10);
   for (StateId stateId : states.keySet()) {
    if (stateId.getScopeId().equals(scopeId)) {
      toDelKeys.add(stateId);
    }
   }

  // delete them
  for (StateId stateId : toDelKeys) {
    states.remove(stateId);
  }
 }
}

Then you have to code copy the PortletBridgeBase and change all instances of PortletStateHolder
to your class.

Then you have to configure your web aplications to use a custom PortletBridge. Add

   <context-param>
        <param-name>javax.portlet.faces.renderPolicy</param-name>
       <param-value>NEVER_DELEGATE</param-value>
    </context-param>
    <context-param>
        <param-name>javax.portlet.faces.BridgeImplClass</param-name>
        <param-value>de.koelnerwasser.portlet.bridge.MyPortletBridge</param-value>
    </context-param>

to the web.xml.

Stupidly i lost the password for my JBoss account, so i’m not able to add a Jira entry now . But I will do it next week.

One thought on “PortletStateHolder in the JBoss PortletBridge and ConcurrentModificationException

  1. Pingback: PortletStateHolder in the JBoss PortletBridge and ConcurrentModificationException | koelnerwasser.de

Leave a Reply

Your email address will not be published. Required fields are marked *

*