Bug 1134966

Summary: (6.3.1) (Regression) Mojarra 2.1.28-redhat-5 causes ConcurrentModificationExceptions on OpenJDK 1.6 and IBM JDK 1.6
Product: [JBoss] JBoss Enterprise Application Platform 6 Reporter: Ron Šmeral <rsmeral>
Component: JSFAssignee: Farah Juma <fjuma>
Status: CLOSED CURRENTRELEASE QA Contact: Ron Šmeral <rsmeral>
Severity: urgent Docs Contact: Russell Dickenson <rdickens>
Priority: unspecified    
Version: 6.3.1CC: amelicha, bbaranow, jawilson, ppitonak, rsvoboda, ssilvert
Target Milestone: CR2Keywords: Regression
Target Release: EAP 6.3.1   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-10-13 18:38:58 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1102082, 1135905, 1138921    

Description Ron Šmeral 2014-08-28 14:14:56 UTC
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

Comment 1 Farah Juma 2014-08-29 23:01:53 UTC
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.)

Comment 4 Ron Šmeral 2014-09-11 11:47:00 UTC
Verified in 6.3.1.CP.CR2.