dev@javaserverfaces.java.net

JSF 1.1 => ApplicationAssociate->createAndMaybeStoreManagedBeans ==> deadlock

From: Matthias Wessendorf <matzew_at_apache.org>
Date: Fri, 20 Mar 2009 09:34:48 +0100

Hi,

in the 1.1_02-b08 version of the RI, there is a the
"createAndMaybeStoreManagedBeans" method which has a sync block(see
below for the code), which causes a deadlock...:

Thread dump shows two deadlocks:
<deadlock>
"AJPRequestHandler-RMICallHandler-59" prio=6 tid=0x558a8da0
nid=0x1100 waiting for monitor entry [0x612fe000..0x612ffa9c] at
com.sun.faces.application.ApplicationAssociate.createAndMaybeStoreManagedBeans(ApplicationAssociate.java:282)
     - waiting to lock <0x18cb1608> (a
com.sun.faces.application.ApplicationAssociate) at
com.sun.faces.el.VariableResolverImpl.resolveVariable(VariableResolverImpl.java:97)
     at oracle.adfinternal.view.faces.el.AdfFacesVariableResolver.resolveVariable(AdfFacesVariableResolver.java:40)
     at com.sun.faces.el.impl.NamedValue.evaluate(NamedValue.java:145)
     at com.sun.faces.el.impl.ComplexValue.evaluate(ComplexValue.java:166)
     at com.sun.faces.el.impl.ExpressionEvaluatorImpl.evaluate(ExpressionEvaluatorImpl.java:263)
     at com.sun.faces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:160)
     at com.sun.faces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:143)
.....
....

"AJPRequestHandler-RMICallHandler-57" prio=6 tid=0x54086298
nid=0x1c94 waiting for monitor entry [0x609ce000..0x609cfa1c] at
com.evermind.server.http.EvermindHttpSession.getAttribute(EvermindHttpSession.java:208)
     - waiting to lock <0x2d981328> (a
com.evermind.server.http.EvermindHttpSession) at
com.sun.faces.context.SessionMap.get(ExternalContextImpl.java:569)
 at com.sun.faces.el.VariableResolverImpl.resolveVariable(VariableResolverImpl.java:90)
     at oracle.adfinternal.view.faces.el.AdfFacesVariableResolver.resolveVariable(AdfFacesVariableResolver.java:40)
     at com.sun.faces.el.impl.NamedValue.evaluate(NamedValue.java:145)
     at com.sun.faces.el.impl.ComplexValue.evaluate(ComplexValue.java:166)
     at com.sun.faces.el.impl.ExpressionEvaluatorImpl.evaluate(ExpressionEvaluatorImpl.java:263)
     at com.sun.faces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:160)
     at com.sun.faces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:143)
</deadlock>

Looking at the ApplicationAssociate and I see that that method is now
gone, due to some changes/refactorings, I guess...

Also, I found this bug, where some one reported already a deadlock:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6223295

So, my questions are now:
-was 1.1_02-b08 the LAST release of the JSF 1.1 specific implementation ?
-was the bug only fixed for JSF 1.2 ?

::::::::::::::::CODE::::::::::::::::
check this sync block; it also includes the session.put - which is a
recursive lock into the http session

<snip>
public Object createAndMaybeStoreManagedBeans(FacesContext context,
String managedBeanName) throws FacesException

{

    ManagedBeanFactory managedBean =
(ManagedBeanFactory)managedBeanFactoriesMap.get(managedBeanName);

    if(managedBean == null)

    {

        if(log.isDebugEnabled()) log.debug("Couldn't find a factory
for " + managedBeanName);

            return null;

    }

    Object bean = null;

    String scope = managedBean.getScope();

if(log.isTraceEnabled())

log.trace("Storing " + managedBeanName + " in scope " + scope);

boolean scopeIsApplication = false;

boolean scopeIsSession = false;

boolean scopeIsRequest = false;

if((scopeIsApplication = scope.equalsIgnoreCase("application")) ||
(scopeIsSession = scope.equalsIgnoreCase("session")))

{

synchronized(this)

{

try

{

bean = managedBean.newInstance(context);

if(log.isDebugEnabled())

log.debug("Created bean " + managedBeanName + " successfully ");

}

catch(Exception ex)

{

Object params[] = {

ex.getMessage()

};

if(log.isErrorEnabled())

log.error("Managedbean " + managedBeanName + " could not be created "
+ ex.getMessage(), ex);

throw new FacesException(ex);

}

if(scopeIsApplication)

context.getExternalContext().getApplicationMap().put(managedBeanName, bean);

if(scopeIsSession)

Util.getSessionMap(context).put(managedBeanName, bean);

}

} else
.........
</snip>

Thanks!
Matthias

-- 
Matthias Wessendorf
blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf