Hide Forgot
Description of problem: Mojarra was updated to 2.1.28-redhat-5 in 6.3.1.CP.CR1. Multiple tests in CDI TCK, integration tests and cluster tests fail, all with the same ConcurrentModificationException: JBWEB000236: Servlet.service() for servlet Faces Servlet threw exception: java.util.ConcurrentModificationException at java.util.LinkedHashMap$AbstractMapIterator.checkConcurrentMod(LinkedHashMap.java:136) [java.util.jar:] at java.util.LinkedHashMap$AbstractMapIterator.makeNext(LinkedHashMap.java:141) [java.util.jar:] at java.util.LinkedHashMap$EntryIterator.next(LinkedHashMap.java:188) [java.util.jar:] at java.util.LinkedHashMap$EntryIterator.next(LinkedHashMap.java:180) [java.util.jar:] at java.util.AbstractMap.equals(AbstractMap.java:384) [java.util.jar:] at java.util.Collections$SynchronizedMap.equals(Collections.java:746) [java.util.jar:] at com.sun.faces.context.SessionMap.put(SessionMap.java:138) [jsf-impl-2.1.28.redhat-5.jar:2.1.28.redhat-5] at com.sun.faces.context.SessionMap.put(SessionMap.java:61) [jsf-impl-2.1.28.redhat-5.jar:2.1.28.redhat-5] at com.sun.faces.renderkit.ServerSideStateHelper.writeState(ServerSideStateHelper.java:243) [jsf-impl-2.1.28.redhat-5.jar:2.1.28.redhat-5] at com.sun.faces.renderkit.ResponseStateManagerImpl.writeState(ResponseStateManagerImpl.java:122) [jsf-impl-2.1.28.redhat-5.jar:2.1.28.redhat-5] at com.sun.faces.application.StateManagerImpl.writeState(StateManagerImpl.java:113) [jsf-impl-2.1.28.redhat-5.jar:2.1.28.redhat-5] at com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:225) [jsf-impl-2.1.28.redhat-5.jar:2.1.28.redhat-5] at com.sun.faces.application.view.JspViewHandlingStrategy.renderView(JspViewHandlingStrategy.java:248) [jsf-impl-2.1.28.redhat-5.jar:2.1.28.redhat-5] at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125) [jsf-impl-2.1.28.redhat-5.jar:2.1.28.redhat-5] at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:286) [jboss-jsf-api_2.1_spec-2.1.28.Final-redhat-1.jar:2.1.28.Final-redhat-1] at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120) [jsf-impl-2.1.28.redhat-5.jar:2.1.28.redhat-5] at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.28.redhat-5.jar:2.1.28.redhat-5] at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) [jsf-impl-2.1.28.redhat-5.jar:2.1.28.redhat-5] at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) [jboss-jsf-api_2.1_spec-2.1.28.Final-redhat-1.jar:2.1.28.Final-redhat-1] This only happens on OpenJDK 1.6 and IBM JDK 1.6, on all tested platforms. Other platforms pass EAP 6.3.1.CP.CR1 with Mojarra 2.1.28-redhat-3 (from 6.3.0.ER10) doesn't fail. Version-Release number of selected component (if applicable): Mojarra 2.1.28-redhat-5 How reproducible: CDI TCK tests: org.jboss.jsr299.tck.tests.context.conversation.ClientConversationContextTest.testConversationIdSetByContainerIsUnique org.jboss.jsr299.tck.tests.context.conversation.ClientConversationContextTest.testConversationsDontCrossSessionBoundary1 org.jboss.jsr299.tck.tests.context.conversation.ClientConversationContextTest.testConversationsDontCrossSessionBoundary2 org.jboss.jsr299.tck.tests.context.conversation.LongRunningConversationPropagatedByFacesContextTest.testConversationPropagatedOverRedirect
Note that the only difference between the Mojarra 2.1.28-redhat-3 version and the Mojarra 2.1.28-redhat-5 version is that the logicalMap in ServerSideStateHelper.java was wrapped with a Collections.SynchronizedMap (bug 1105280). These ConcurrentModificationExceptions are occurring only on OpenJDK 1.6 and IBM JDK 1.6 because of a difference in the implementation of the java.util.Collections.SynchronizedMap#equals(Object o) method. In particular, in Oracle JDK 1.6 and in the JDK 1.7 versions, there's a check at the beginning of the method to see if this == o, as shown below. Note that the java.util.AbstractMap.equals(Object o) method will only be called if this check fails. http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/util/Collections.java?av=f#2081 In the OpenJDK 1.6 and IBM JDK 1.6 versions that are being used, there isn't such a check. Without this, a ConcurrentModificationException occurs if the logicalMap calls the equals() method against itself. (Note that the logicalMap is backed by a LinkedHashMap<String, LinkedHashMap<String, Object[]>>. The javadoc for a LinkedHashMap states that merely querying such a map with get is considered to be a structural modification. This causes a ConcurrentModificationException to occur when the java.util.AbstractMap.equals(Object o) method iterates over the map.)
Verified in 6.3.1.CP.CR2.