Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 330937

Summary: deadlock when initializing FaceletTagRegistry
Product: [WebTools] Java Server Faces Reporter: Alex Smirnoff <alexander.smirnoff>
Component: JSF ToolsAssignee: Cameron Bateman <cameron.bateman>
Status: RESOLVED FIXED QA Contact:
Severity: critical    
Priority: P3 CC: Andrew.McCulloch, cameron.bateman, raghunathan.srinivasan, yurykats
Version: unspecified   
Target Milestone: 3.2.3   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
proposed fixes
none
few more optimizations and suggestions from Andrew none

Description Alex Smirnoff CLA 2010-11-23 11:14:09 EST
Build Identifier: 

Only a single WPE was open and it was an XHTML page for a JSF2.0 DWP when the
deadlock occurred on startup.

This issue happens when one thread (Worker-1) start project rule early. Then tries to acquire the object monitor lock, while another thread (main) first acquires the object monitor, then down the thread stack tries to start the project rule.


"Worker-1" prio=6 tid=0x332d9400 nid=0x192c waiting for monitor entry
[0x340af000]
   java.lang.Thread.State: BLOCKED (on object monitor)
         at
org.eclipse.jst.jsf.facelet.core.internal.registry.FaceletTagRegistry.getTagLibrary(FaceletTagRegistry.java:201)
- waiting to lock <0x0e8d8f10> (a
org.eclipse.jst.jsf.facelet.core.internal.registry.FaceletTagRegistry)
         at
org.eclipse.jst.jsf.designtime.internal.view.TaglibBasedViewDefnAdapter.findTagElement(TaglibBasedViewDefnAdapter.java:53)
         at
org.eclipse.jst.jsf.designtime.internal.view.XMLViewDefnAdapter.mapToTagElement(XMLViewDefnAdapter.java:97)
         at
org.eclipse.jst.jsf.designtime.internal.resolver.ViewBasedTaglibResolverFactory$ViewBasedTaglibResolver._getTagElement(ViewBasedTaglibResolverFactory.java:212)
         at
org.eclipse.jst.jsf.designtime.internal.resolver.ViewBasedTaglibResolverFactory$ViewBasedTaglibResolver.hasTag(ViewBasedTaglibResolverFactory.java:173)
         at
oracle.eclipse.tools.webtier.common.services.discovery.AbstractTagDiscoveryParticipant.visit(AbstractTagDiscoveryParticipant.java:394)
         at
oracle.eclipse.tools.webtier.common.services.discovery.internal.StructuredModelDiscoveryParticipant$Visitor.visit(StructuredModelDiscoveryParticipant.java:241)
         at
oracle.eclipse.tools.webtier.common.services.discovery.internal.StructuredModelDiscoveryParticipant$Visitor.visit(StructuredModelDiscoveryParticipant.java:208)
         at
oracle.eclipse.tools.common.services.dependency.structuredmodel.internal.VisitableDOMAttribute.accept(VisitableDOMAttribute.java:22)
         at
oracle.eclipse.tools.common.services.dependency.structuredmodel.internal.VisitableDOMElement.accept(VisitableDOMElement.java:32)
         at
oracle.eclipse.tools.common.services.dependency.structuredmodel.internal.VisitableDOMElement.accept(VisitableDOMElement.java:39)
         at
oracle.eclipse.tools.common.services.dependency.structuredmodel.internal.VisitableDOMDocument.accept(VisitableDOMDocument.java:43)
         at
oracle.eclipse.tools.common.services.dependency.structuredmodel.internal.VisitableDOMModel.accept(VisitableDOMModel.java:53)
         at
oracle.eclipse.tools.common.services.dependency.structuredmodel.internal.VisitableDOMModel.accept(VisitableDOMModel.java:49)
         at
oracle.eclipse.tools.webtier.common.services.discovery.internal.StructuredModelDiscoveryParticipant.discover(StructuredModelDiscoveryParticipant.java:128)
         at
oracle.eclipse.tools.common.services.dependency.model.internal.DiscoveryParticipantList$4.run(DiscoveryParticipantList.java:92)
         at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
         at
oracle.eclipse.tools.common.services.dependency.model.internal.DiscoveryParticipantList.discover(DiscoveryParticipantList.java:89)
         at
oracle.eclipse.tools.common.services.dependency.model.internal.ResourceSetCommand.execute(ResourceSetCommand.java:62)
         at
oracle.eclipse.tools.common.services.resources.internal.QueueManagerJob$Comma
dSetJob$SafeRunnable.run(QueueManagerJob.java:281)
         at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
         at
oracle.eclipse.tools.common.services.resources.internal.QueueManagerJob$Comma
dSetJob.run(QueueManagerJob.java:208)
         at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)

"main" prio=6 tid=0x003b7400 nid=0x3f34 in Object.wait() [0x0090e000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
         at java.lang.Object.wait(Native Method)
         at
org.eclipse.core.internal.jobs.ThreadJob.waitForRun(ThreadJob.java:270)
- locked <0x0eca18e8> (a java.lang.Object)
         at
org.eclipse.core.internal.jobs.ThreadJob.joinRun(ThreadJob.java:199)
         at
org.eclipse.core.internal.jobs.ImplicitJobs.begin(ImplicitJobs.java:92)
         at
org.eclipse.core.internal.jobs.JobManager.beginRule(JobManager.java:286)
         at
org.eclipse.core.internal.resources.WorkManager.checkIn(WorkManager.java:117)
         at
org.eclipse.core.internal.resources.Workspace.prepareOperation(Workspace.java:1914)
         at
org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1970)
         at
org.eclipse.jst.jee.model.internal.common.AbstractMergedModelProvider.loadModel(AbstractMergedModelProvider.java:229)
         at
org.eclipse.jst.jee.model.internal.common.AbstractMergedModelProvider.getMergedModel(AbstractMergedModelProvider.java:213)
         at
org.eclipse.jst.jee.model.internal.common.AbstractMergedModelProvider.getModelObject(AbstractMergedModelProvider.java:133)
         at
org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.WebappConfiguration.getConfigFilesFromContextParam(WebappConfiguration.java:184)
         at
org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.WebappConfiguration.getFiles(WebappConfiguration.java:115)
         at
org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.TaglibResourceManager.initResources(TaglibResourceManager.java:62)
         at
org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.ContextParamSpecifiedFaceletTaglibLocator.start(ContextParamSpecifiedFaceletTaglibLocator.java:82)

         at
org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.ContextParamSpecifiedFaceletTaglibLocator.start(ContextParamSpecifiedFaceletTaglibLocator.java:1)
         at
org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.ProjectTaglibDescriptor$1.run(ProjectTaglibDescriptor.java:82)
         at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
         at
org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.ProjectTaglibDescriptor.initialize(ProjectTaglibDescriptor.java:71)
- locked <0x0ebf0618> (a
org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.ProjectTaglibDescriptor)
         at
org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.ProjectTaglibDescriptor.getTagLibraries(ProjectTaglibDescriptor.java:117)
         at
org.eclipse.jst.jsf.facelet.core.internal.registry.FaceletTagRegistry.initialize(FaceletTagRegistry.java:155)
         at
org.eclipse.jst.jsf.facelet.core.internal.registry.FaceletTagRegistry.getAllTagLibraries(FaceletTagRegistry.java:110)
- locked <0x0e8d8f10> (a
org.eclipse.jst.jsf.facelet.core.internal.registry.FaceletTagRegistry)
         at
org.eclipse.jst.jsf.facelet.core.internal.registry.FaceletTagRegistry.getTagLibrary(FaceletTagRegistry.java:201)
- locked <0x0e8d8f10> (a
org.eclipse.jst.jsf.facelet.core.internal.registry.FaceletTagRegistry)
         at
org.eclipse.jst.jsf.facelet.core.internal.metadata.FaceletNamespaceMetaDataLocator.locateMetaDataModelProviders(FaceletNamespaceMetaDataLocator.java:53)
         at
org.eclipse.jst.jsf.common.metadata.internal.DomainLoadingStrategy.locateMetaDataSourceInstances(DomainLoadingStrategy.java:143)
         at
org.eclipse.jst.jsf.common.metadata.internal.DomainLoadingStrategy.load(DomainLoadingStrategy.java:55)
         at
org.eclipse.jst.jsf.common.metadata.internal.MetaDataModel.load(MetaDataModel.java:93)
- locked <0x0e88a620> (a
org.eclipse.jst.jsf.common.metadata.internal.MetaDataModel)
         at
org.eclipse.jst.jsf.common.metadata.internal.MetaDataModelManager.loadMetadata(MetaDataModelManager.java:147)
         at
org.eclipse.jst.jsf.common.metadata.internal.MetaDataModelManager.getModel(MetaDataModelManager.java:90)
         at
org.eclipse.jst.jsf.common.metadata.query.TaglibDomainMetaDataQueryHelper.getMDModel(TaglibDomainMetaDataQueryHelper.java:205)
         at
org.eclipse.jst.jsf.common.metadata.query.TaglibDomainMetaDataQueryHelper.getModel(TaglibDomainMetaDataQueryHelper.java:90)
         at
org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteHelper.getOrCreateTaglibPaletteDrawer(PaletteHelper.java:131)
         at
org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemManager.registerHTMLCategory(PaletteItemManager.java:349)
         at
org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemManager.initTagRegistry(PaletteItemManager.java:313)
         at
org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemManager.init(PaletteItemManager.java:278)
- locked <0x0e81e650> (a
org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemManager)
         at
org.eclipse.jst.pagedesigner.editors.palette.impl.PaletteItemManager.getInstance(PaletteItemManager.java:119)
         at
oracle.eclipse.tools.webtier.ui.internal.palette.model.taglibs.TagLibPaletteCntributor.getContributions(TagLibPaletteContributor.java:73)
         at
oracle.eclipse.tools.webtier.ui.palette.internal.OEPEPaletteRoot.addDrawers(OPEPaletteRoot.java:138)
         at
oracle.eclipse.tools.webtier.ui.palette.internal.OEPEPaletteRoot.resetPaletteoot(OEPEPaletteRoot.java:110)
         at
oracle.eclipse.tools.webtier.ui.palette.internal.OEPEPaletteRoot.<init>(OEPEPletteRoot.java:51)
         at
oracle.eclipse.tools.webtier.ui.palette.internal.PaletteFactory.createPaletteoot(PaletteFactory.java:61)
         at
org.eclipse.jst.pagedesigner.editors.SimpleGraphicalEditor.getPaletteRoot(SimpleGraphicalEditor.java:479)
         at
org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette.setEditDomain(GraphicalEditorWithFlyoutPalette.java:145)
         at
org.eclipse.jst.pagedesigner.editors.SimpleGraphicalEditor.<init>(SimpleGraphicalEditor.java:164)
         at
org.eclipse.jst.pagedesigner.editors.HTMLEditor.sash_createAndAddDesignSourcePage(HTMLEditor.java:259)
         at
org.eclipse.jst.pagedesigner.editors.HTMLEditor.createPages(HTMLEditor.java:439)
         at
org.eclipse.ui.part.MultiPageEditorPart.createPartControl(MultiPageEditorPart.java:348)
         at
org.eclipse.ui.internal.EditorReference.createPartHelper(EditorReference.java:670)
         at
org.eclipse.ui.internal.EditorReference.createPart(EditorReference.java:465)
         at
org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
         at
org.eclipse.ui.internal.EditorAreaHelper.setVisibleEditor(EditorAreaHelper.java:271)
         at
org.eclipse.ui.internal.EditorManager.setVisibleEditor(EditorManager.java:1429)
         at
org.eclipse.ui.internal.EditorManager$5.runWithException(EditorManager.java:942)
         at
org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
         at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
         at
org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
- locked <0x0e279250> (a org.eclipse.swt.widgets.RunnableLock)
         at
org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4041)
         at
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3660)
         at
org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
         at
org.eclipse.ui.internal.Workbench$31.runWithException(Workbench.java:1567)
         at
org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
         at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
         at
org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
- locked <0x0d9a81c8> (a org.eclipse.swt.widgets.RunnableLock)
         at
org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4041)
         at
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3660)
         at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2548)
         at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438)
         at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671)
         at
org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
         at
org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664)
         at
org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
         at
org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
         at
org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
         at
org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
         at
org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
         at
org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
         at
org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
         at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
         at java.lang.reflect.Method.invoke(Method.java:597)
         at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
         at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
         at org.eclipse.equinox.launcher.Main.run(Main.java:1407)
         at org.eclipse.equinox.launcher.Main.main(Main.java:1383)


Reproducible: Sometimes

Steps to Reproduce:
This is deadlock issue hard to reproduce consistently.
Comment 1 Alex Smirnoff CLA 2010-11-23 11:29:49 EST
Created attachment 183681 [details]
proposed fixes

Main idea of the bug fix here is to reverse the synchronization order. Because the rules are re-entrant, we can grab the project rule before the synchronization in FaceletTagRegistry.

The patch also introduces few improvements:

1. Synchronization is managed by platform ILock API.
2. Because the rule acquisition happens only during initialization phase, the patch only use preemptive rule acquisition when registry is not initialized, in getAllTagLibraries method.
3. All change jobs registered with project rules. This is done mainly because ew don't know what the client listener code may do, but every time client listener code will be running in synchronized block.
Comment 2 Alex Smirnoff CLA 2010-11-23 11:37:00 EST
One more thing: the patch is maid against R3_2_2 tag
Comment 3 Alex Smirnoff CLA 2010-11-23 15:49:44 EST
Created attachment 183712 [details]
few more optimizations and suggestions from Andrew

One more suggestion for the future optimization: to make private remove() and initialize() methods (they have escaping internal state) and moving LibraryOperationFactory to FaceletTagRegistry.
Comment 4 Cameron Bateman CLA 2010-11-24 13:24:36 EST
Patch applied to HEAD (3.2.3 and 3.3).