You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by "Jesse Kuhnert (JIRA)" <ta...@jakarta.apache.org> on 2006/03/14 14:35:39 UTC

[jira] Resolved: (TAPESTRY-806) (T3 only) Multithreading problems possibly due to double-checked locking

     [ http://issues.apache.org/jira/browse/TAPESTRY-806?page=all ]
     
Jesse Kuhnert resolved TAPESTRY-806:
------------------------------------

    Fix Version: 3.0.4
     Resolution: Fixed

Patch applied, thanks.

> (T3 only) Multithreading problems possibly due to double-checked locking
> ------------------------------------------------------------------------
>
>          Key: TAPESTRY-806
>          URL: http://issues.apache.org/jira/browse/TAPESTRY-806
>      Project: Tapestry
>         Type: Bug
>   Components: Framework
>     Versions: 3.0.3
>  Environment: Unspecified, except for "8-CPU server"
>     Reporter: Nick Westgate
>     Assignee: Jesse Kuhnert
>      Fix For: 3.0.4
>  Attachments: TapestryDoubleCheckedLockingIssue.patch
>
> Flawed synchronization code using "double-checked locking" is used in these methods:
> (1) org.apache.tapestry.enhance.DefaultComponentClassEnhancer.getEnhancedClass()
> (2) org.apache.tapestry.enhance.javassist.EnhancedClassFactory.getObjectType()
> Suggested fix for (1) is:
> public Class getEnhancedClass(IComponentSpecification specification,
>         String className)
> {
>     synchronized (specification)
>     {
>         Class result = getCachedClass(specification);
>         if (result == null)
>         {
>             result = getCachedClass(specification);
>             if (result == null)
>             {
>                 result = constructComponentClass(specification, className);
>                 storeCachedClass(specification, result);
>             }
>         }
>     }
>     return result;
> }
> Original bug report, from Michael Prescott ( mprescott@exchangesolutions.com ) in users list is:
> We're coming across an unusual exception that occurs when our
> application is under load.  Below is an example stack trace, although
> the problem can occur while enhancing any of a number of things, so it
> doesn't seem specific to one part of our application.  The root
> exception is always the same, however:
>  
>   javassist.CannotCompileException: duplicate method: <init>
>  
> Since it seemed to be related to concurrency, we were reading through
> the Tapestry classes along this stack, and found what looks like a
> threading problem in DefaultComponentClassEnhancer.java:
>  
>  public Class getEnhancedClass(IComponentSpecification specification,
> String className)
>     {
>         Class result = getCachedClass(specification);
>  
>         if (result == null)
>         {
>             synchronized (this)
>             {
>                 result = getCachedClass(specification);
>                 if (result == null)
>                 {
>                     result = constructComponentClass(specification,
> className);
>                     storeCachedClass(specification, result);
>                 }
>             }
>         }
>  
>         return result;
>     }
>  
> This is double-checked locking, which isn't safe given instruction
> reordering and thread-specific copies of variables, and all that
> multi-CPU magic.  This problem is occurring on an 8-CPU server, which
> I'm guessing is enough processors to expose the subtle ways in which
> double-checked locking can fail.
>  
> Does this ring any bells for anyone?  I realize this is a somewhat
> nebulous query.
>  
> Michael
>  
> org.apache.tapestry.ApplicationRuntimeException: A code generation error
> occured while enhancing class org.apache.tapestry.link.GenericLink.
>         at
> org.apache.tapestry.enhance.DefaultComponentClassEnhancer.constructCompo
> nentClass(DefaultComponentClassEnhancer.java:151)
>         at
> org.apache.tapestry.enhance.DefaultComponentClassEnhancer.getEnhancedCla
> ss(DefaultComponentClassEnhancer.java:97)
>         at
> org.apache.tapestry.pageload.PageLoader.instantiateComponent(PageLoader.
> java:603)
>         at
> org.apache.tapestry.pageload.PageLoader.createImplicitComponent(PageLoad
> er.java:569)
>         at
> org.apache.tapestry.BaseComponentTemplateLoader.createImplicitComponent(
> BaseComponentTemplateLoader.java:295)
>         at
> org.apache.tapestry.BaseComponentTemplateLoader.process(BaseComponentTem
> plateLoader.java:237)
>         at
> org.apache.tapestry.BaseComponentTemplateLoader.process(BaseComponentTem
> plateLoader.java:172)
>         at
> org.apache.tapestry.BaseComponent.readTemplate(BaseComponent.java:100)
>         at
> org.apache.tapestry.BaseComponent.finishLoad(BaseComponent.java:135)
>         at
> org.apache.tapestry.pageload.PageLoader.constructComponent(PageLoader.ja
> va:519)
>         at
> org.apache.tapestry.pageload.PageLoader.createImplicitComponent(PageLoad
> er.java:576)
>         at
> org.apache.tapestry.BaseComponentTemplateLoader.createImplicitComponent(
> BaseComponentTemplateLoader.java:295)
>         at
> org.apache.tapestry.BaseComponentTemplateLoader.process(BaseComponentTem
> plateLoader.java:237)
>         at
> org.apache.tapestry.BaseComponentTemplateLoader.process(BaseComponentTem
> plateLoader.java:172)
>         at
> org.apache.tapestry.BaseComponent.readTemplate(BaseComponent.java:100)
>         at
> org.apache.tapestry.BaseComponent.finishLoad(BaseComponent.java:135)
>         at
> org.apache.tapestry.pageload.PageLoader.constructComponent(PageLoader.ja
> va:519)
>         at
> org.apache.tapestry.pageload.PageLoader.createImplicitComponent(PageLoad
> er.java:576)
>         at
> org.apache.tapestry.BaseComponentTemplateLoader.createImplicitComponent(
> BaseComponentTemplateLoader.java:295)
>         at
> org.apache.tapestry.BaseComponentTemplateLoader.process(BaseComponentTem
> plateLoader.java:237)
>         at
> org.apache.tapestry.BaseComponentTemplateLoader.process(BaseComponentTem
> plateLoader.java:172)
>         at
> org.apache.tapestry.BaseComponent.readTemplate(BaseComponent.java:100)
>         at
> org.apache.tapestry.BaseComponent.finishLoad(BaseComponent.java:135)
>         at
> org.apache.tapestry.pageload.PageLoader.constructComponent(PageLoader.ja
> va:519)
>         at
> org.apache.tapestry.pageload.PageLoader.createImplicitComponent(PageLoad
> er.java:576)
>         at
> org.apache.tapestry.BaseComponentTemplateLoader.createImplicitComponent(
> BaseComponentTemplateLoader.java:295)
>         at
> org.apache.tapestry.BaseComponentTemplateLoader.process(BaseComponentTem
> plateLoader.java:237)
>         at
> org.apache.tapestry.BaseComponentTemplateLoader.process(BaseComponentTem
> plateLoader.java:172)
>         at
> org.apache.tapestry.BaseComponent.readTemplate(BaseComponent.java:100)
>         at
> org.apache.tapestry.BaseComponent.finishLoad(BaseComponent.java:135)
>         at
> org.apache.tapestry.pageload.PageLoader.constructComponent(PageLoader.ja
> va:519)
>         at
> org.apache.tapestry.pageload.PageLoader.loadPage(PageLoader.java:764)
>         at
> org.apache.tapestry.pageload.PageSource.getPage(PageSource.java:152)
>         at
> org.apache.tapestry.engine.RequestCycle.getPage(RequestCycle.java:195)
>         at
> org.apache.tapestry.engine.ActionService.service(ActionService.java:125)
>         at
> org.apache.tapestry.engine.AbstractEngine.service(AbstractEngine.java:88
> 9)
>         at
> org.apache.tapestry.ApplicationServlet.doService(ApplicationServlet.java
> :198)
>         at
> net.exchangesolutions.sn.ui.tapestry.SynchronizedServlet.doService(Synch
> ronizedServlet.java:37)
>         at
> org.apache.tapestry.ApplicationServlet.doGet(ApplicationServlet.java:159
> )
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:115)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:92)
>         at
> com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChai
> n.java:99)
>         at
> net.exchangesolutions.sncore.servlet.StateFilter.doFilter(StateFilter.ja
> va:56)
>         at
> com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.
> java:70)
>         at
> com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.ja
> va:163)
>         at
> com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.j
> ava:208)
>         at
> com.caucho.server.hmux.HmuxRequest.handleRequest(HmuxRequest.java:396)
>         at
> com.caucho.server.port.TcpConnection.run(TcpConnection.java:363)
>         at com.caucho.util.ThreadPool.runTasks(ThreadPool.java:490)
>         at com.caucho.util.ThreadPool.run(ThreadPool.java:423)
>         at java.lang.Thread.run(Thread.java:595)
> Caused by: org.apache.tapestry.enhance.CodeGenerationException
>         at
> org.apache.tapestry.enhance.javassist.ClassFabricator.getByteCode(ClassF
> abricator.java:291)
>         at
> org.apache.tapestry.enhance.javassist.EnhancedClass.createEnhancedSubcla
> ss(EnhancedClass.java:130)
>         at
> org.apache.tapestry.enhance.ComponentClassFactory.createEnhancedSubclass
> (ComponentClassFactory.java:336)
>         at
> org.apache.tapestry.enhance.DefaultComponentClassEnhancer.constructCompo
> nentClass(DefaultComponentClassEnhancer.java:143)
>         ... 50 more
> Caused by: javassist.CannotCompileException: duplicate method: <init>
>         at
> javassist.bytecode.ClassFile.testExistingMethod(ClassFile.java:488)
>         at javassist.bytecode.ClassFile.addMethod(ClassFile.java:472)
>         at javassist.CtClassType.addConstructor(CtClassType.java:885)
>         at javassist.CtNewClass.addConstructor(CtNewClass.java:55)
>         at
> javassist.CtNewClass.inheritAllConstructors(CtNewClass.java:96)
>         at javassist.CtNewClass.toBytecode(CtNewClass.java:63)
>         at javassist.CtClass.toBytecode(CtClass.java:1021)
>         at
> org.apache.tapestry.enhance.javassist.ClassFabricator.getByteCode(ClassF
> abricator.java:279)
>         ... 53 more
>  
> Michael Prescott
> direct: 416.646.7062
> main: 416.646.7000 
> fax: 416.646.7050 
> Exchange Solutions Inc.
> 250 Yonge Street, 18th Floor
> Toronto, ON M5B 2L7
> www.exchangesolutions.com

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org