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

Bug 115714

Summary: NullPointerException in Hashtable caused by FileBufferModelManager releaseModel
Product: [WebTools] WTP Source Editing Reporter: Scott Ellis <sellis>
Component: wst.sseAssignee: Nitin Dahyabhai <thatnitind>
Status: RESOLVED WORKSFORME QA Contact:
Severity: major    
Priority: P3 CC: david_williams, jhouston.mail, stammt, thatnitind
Version: 0.7Keywords: helpwanted
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Scott Ellis CLA 2005-11-09 17:37:48 EST
We saw the following NPE during a run of bea internal tests.



     [java] !ENTRY org.eclipse.jst.jsp.core 4 4 2005-11-09 12:48:45.469
     [java] !MESSAGE JSPIndexer problem
indexing:/customerCareWebProject/web/customerManagementPageFlow/customers.jsp
     [java] !STACK 0
     [java] java.lang.NullPointerException
     [java] 	at
java.util.Hashtable.get(Ljava.lang.Object;)Ljava.lang.Object;(Unknown Source)
     [java] 	at
org.eclipse.wst.sse.core.internal.FileBufferModelManager.releaseModel(FileBufferModelManager.java:597)
     [java] 	at
org.eclipse.wst.sse.core.internal.model.ModelManagerImpl.discardModel(ModelManagerImpl.java:1370)
     [java] 	at
org.eclipse.wst.sse.core.internal.model.ModelManagerImpl.releaseFromRead(ModelManagerImpl.java:1397)
     [java] 	at
org.eclipse.wst.sse.core.internal.model.AbstractStructuredModel.releaseFromRead(AbstractStructuredModel.java:1067)
     [java] 	at
org.eclipse.wst.xml.core.internal.document.DOMModelImpl.releaseFromRead(DOMModelImpl.java:806)
     [java] 	at
org.eclipse.wst.html.core.internal.document.DOMStyleModelImpl.releaseFromRead(DOMStyleModelImpl.java:44)
     [java] 	at
org.eclipse.jst.jsp.core.internal.java.search.JSPSearchDocument.getJSPTranslation(JSPSearchDocument.java:128)
     [java] 	at
org.eclipse.jst.jsp.core.internal.java.search.JSPSearchDocument.getPath(JSPSearchDocument.java:149)
     [java] 	at
org.eclipse.jst.jsp.core.internal.java.search.JavaSearchDocumentDelegate.<init>(JavaSearchDocumentDelegate.java:30)
     [java] 	at
org.eclipse.jst.jsp.core.internal.java.search.JSPSearchSupport.createSearchDocument(JSPSearchSupport.java:426)
     [java] 	at
org.eclipse.jst.jsp.core.internal.java.search.JSPSearchSupport.addJspFile(JSPSearchSupport.java:320)
     [java] 	at
org.eclipse.jst.jsp.core.internal.java.search.JSPIndexManager$ProcessFilesJob.run(JSPIndexManager.java:251)
     [java] 	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:76)
Comment 1 Nitin Dahyabhai CLA 2005-11-10 00:57:29 EST
Were there other files or Jobs running?  Does it happen consistently?  Is this
reproducable with the latest integration build?
Comment 2 Scott Ellis CLA 2005-11-10 13:59:17 EST
1. Were there other files or Jobs running?  
Sorry, we don't know

2. Does it happen consistently?  
No.

3. Is this reproducable with the latest integration build?
Again sorry, we don't know yet



After the initial NPE, there were all sorts of other problems, probably all
related to the first NPE. However for completeness I will list them all here:

first the npe:
     [java] !ENTRY org.eclipse.jst.jsp.core 4 4 2005-11-09 12:48:45.469
     [java] !MESSAGE JSPIndexer problem
indexing:/customerCareWebProject/web/customerManagementPageFlow/customers.jsp
     [java] !STACK 0
     [java] java.lang.NullPointerException
     [java]     at
java.util.Hashtable.get(Ljava.lang.Object;)Ljava.lang.Object;(Unknown Source)
     [java]     at
org.eclipse.wst.sse.core.internal.FileBufferModelManager.releaseModel(FileBufferModelManager.java:597)
     [java]     at
org.eclipse.wst.sse.core.internal.model.ModelManagerImpl.discardModel(ModelManagerImpl.java:1370)
     [java]     at
org.eclipse.wst.sse.core.internal.model.ModelManagerImpl.releaseFromRead(ModelManagerImpl.java:1397)
     [java]     at
org.eclipse.wst.sse.core.internal.model.AbstractStructuredModel.releaseFromRead(AbstractStructuredModel.java:1067)
     [java]     at
org.eclipse.wst.xml.core.internal.document.DOMModelImpl.releaseFromRead(DOMModelImpl.java:806)
     [java]     at
org.eclipse.wst.html.core.internal.document.DOMStyleModelImpl.releaseFromRead(DOMStyleModelImpl.java:44)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.search.JSPSearchDocument.getJSPTranslation(JSPSearchDocument.java:128)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.search.JSPSearchDocument.getPath(JSPSearchDocument.java:149)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.search.JavaSearchDocumentDelegate.<init>(JavaSearchDocumentDelegate.java:30)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.search.JSPSearchSupport.createSearchDocument(JSPSearchSupport.java:426)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.search.JSPSearchSupport.addJspFile(JSPSearchSupport.java:320)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.search.JSPIndexManager$ProcessFilesJob.run(JSPIndexManager.java:251)
     [java]     at org.eclipse.core.internal.jobs.Worker.run(Worker.java:76)

Then the same NPE but coming from a different caller:

     [java] !ENTRY org.eclipse.core.runtime 4 2 2005-11-09 12:48:45.531
     [java] !MESSAGE An internal error occurred during: "Model structure
builder: PageModel:
/customerCareWebProject/web/customerManagementPageFlow/customers.jsp".
     [java] !STACK 0
     [java] java.lang.NullPointerException
     [java]     at
java.util.Hashtable.get(Ljava.lang.Object;)Ljava.lang.Object;(Unknown Source)
     [java]     at
org.eclipse.wst.sse.core.internal.FileBufferModelManager.releaseModel(FileBufferModelManager.java:597)
     [java]     at
org.eclipse.wst.sse.core.internal.model.ModelManagerImpl.discardModel(ModelManagerImpl.java:1370)
     [java]     at
org.eclipse.wst.sse.core.internal.model.ModelManagerImpl.releaseFromRead(ModelManagerImpl.java:1397)
     [java]     at
org.eclipse.wst.sse.core.internal.model.AbstractStructuredModel.releaseFromRead(AbstractStructuredModel.java:1067)
     [java]     at
org.eclipse.wst.xml.core.internal.document.DOMModelImpl.releaseFromRead(DOMModelImpl.java:806)
     [java]     at
org.eclipse.wst.html.core.internal.document.DOMStyleModelImpl.releaseFromRead(DOMStyleModelImpl.java:44)
     [java]     at
com.bea.wlw.netui.core.page.structure.PageStructureBuilder.build(PageStructureBuilder.java:152)
     [java]     at
com.bea.wlw.common.core.model.AbstractExternalEventAdapter$StructureBuilderJob.run(AbstractExternalEventAdapter.java:285)
     [java]     at org.eclipse.core.internal.jobs.Worker.run(Worker.java:76)

Then the following assert:

     [java] !ENTRY org.eclipse.wst.sse.ui 4 4 2005-11-09 12:48:56.641
     [java] !MESSAGE problem with as-you-type validation
     [java] !STACK 0
     [java] org.eclipse.jface.text.Assert$AssertionFailedException: Assertion
failed: wrong model
     [java]     at org.eclipse.jface.text.Assert.isTrue(Assert.java:189)
     [java]     at
org.eclipse.jst.jsp.ui.internal.reconcile.ReconcileStepForJava.reconcileModel(ReconcileStepForJava.java:81)
     [java]     at
org.eclipse.jface.text.reconciler.AbstractReconcileStep.reconcile(AbstractReconcileStep.java:96)
     [java]     at
org.eclipse.jface.text.reconciler.AbstractReconcileStep.reconcile(AbstractReconcileStep.java:99)
     [java]     at
org.eclipse.wst.sse.ui.internal.reconcile.AbstractStructuredTextReconcilingStrategy.reconcile(AbstractStructuredTextReconcilingStrategy.java:368)
     [java]     at
org.eclipse.jst.jsp.ui.internal.reconcile.StructuredTextReconcilingStrategyForJSP.reconcile(StructuredTextReconcilingStrategyForJSP.java:149)
     [java]     at
org.eclipse.wst.sse.ui.internal.reconcile.StructuredRegionProcessor.process(StructuredRegionProcessor.java:170)
     [java]     at
org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor.run(DirtyRegionProcessor.java:412)
     [java]     at org.eclipse.core.internal.jobs.Worker.run(Worker.java:76)

Then the following NPE:

     [java] !ENTRY org.eclipse.core.filebuffers 4 2 2005-11-09 12:49:57.547
     [java] !MESSAGE Problems occurred when invoking code from plug-in:
"org.eclipse.core.filebuffers".
     [java] !STACK 0
     [java] java.lang.NullPointerException
     [java]     at
org.eclipse.wst.sse.core.internal.model.AbstractStructuredModel.setDirtyState(AbstractStructuredModel.java:1337)
     [java]     at
org.eclipse.wst.sse.core.internal.FileBufferModelManager$FileBufferMapper.dirtyStateChanged(FileBufferModelManager.java:282)
     [java]     at
org.eclipse.core.internal.filebuffers.TextFileBufferManager$3.run(TextFileBufferManager.java:374)
     [java]     at
org.eclipse.core.internal.runtime.InternalPlatform.run(InternalPlatform.java:1044)
     [java]     at org.eclipse.core.runtime.Platform.run(Platform.java:783)
     [java]     at
org.eclipse.core.internal.filebuffers.TextFileBufferManager.fireDirtyStateChanged(TextFileBufferManager.java:372)
     [java]     at
org.eclipse.core.internal.filebuffers.ResourceFileBuffer.commit(ResourceFileBuffer.java:327)
     [java]     at
com.bea.wlw.template.textinserter.TextInserter.insertText(TextInserter.java:75)
     [java]     at
com.bea.wlw.jsp.core.commands.GenericTagCommand.performInsert(GenericTagCommand.java:189)
     [java]     at
com.bea.wlw.jsp.core.commands.GenericTagCommand.execute(GenericTagCommand.java:118)
     [java]     at
com.bea.wlw.netui.ui.jsp.commands.BaseDialogCommand.execute(BaseDialogCommand.java:53)
     [java]     at
org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:151)
     [java]     at org.eclipse.core.commands.Command.execute(Command.java:311)
     [java]     at
com.bea.wlw.netui.ui.jsp.commands.DataPaletteTagCommand.execute(DataPaletteTagCommand.java:120)
     [java]     at
org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:151)
     [java]     at org.eclipse.core.commands.Command.execute(Command.java:311)
     [java]     at
com.bea.wlw.common.ui.palette.dnd.DelegatingCommandDropAction.execute(DelegatingCommandDropAction.java:97)
     [java]     at
com.bea.wlw.common.ui.palette.design.DelegatingCommandDropActionAdapter.execute(DelegatingCommandDropActionAdapter.java:50)
     [java]     at
com.bea.wlw.common.ui.palette.design.DesignPalette$InsertMouseListener.mouseDoubleClick(DesignPalette.java:586)
     [java]     at
org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:141)
     [java]     at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
     [java]     at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:843)
     [java]     at
org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3080)
     [java]     at
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2713)
     [java]     at abbot.swt.Robot.delay(Robot.java:232)
     [java]     at abbot.tester.swt.Robot.delay(Robot.java:387)
     [java]     at abbot.tester.swt.Robot.wait(Robot.java:1447)
     [java]     at
com.bea.test.common.testers.AbstractDialogTester.runDialog(AbstractDialogTester.java:402)
     [java]     at
com.bea.test.wlw.netui.ui.jsp.testers.PageInputsDataGridDialogTester.invokeDialog(PageInputsDataGridDialogTester.java:57)
     [java]     at
com.bea.test.common.testers.AbstractDialogTester.runDialog(AbstractDialogTester.java:392)
     [java]     at
com.bea.test.wlw.scenario.tests.BasicDataScenarioDRT.addCustomerGrid(BasicDataScenarioDRT.java:678)
     [java]     at
com.bea.test.wlw.scenario.tests.BasicDataScenarioDRT.testBasicDataScenario(BasicDataScenarioDRT.java:212)

Then this one:

     [java] !ENTRY org.eclipse.jst.jsp.core 4 4 2005-11-09 12:49:57.562
     [java] !MESSAGE JSPIndexer problem
indexing:/customerCareWebProject/web/customerManagementPageFlow/customers.jsp
     [java] !STACK 0
     [java] java.lang.NullPointerException
     [java]     at
org.eclipse.jst.jsp.core.internal.java.JSPTranslator.reset(JSPTranslator.java:324)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.JSPTranslationAdapter.getTranslator(JSPTranslationAdapter.java:171)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.JSPTranslationAdapter.getJSPTranslation(JSPTranslationAdapter.java:130)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.search.JSPSearchDocument.getJSPTranslation(JSPSearchDocument.java:112)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.search.JSPSearchDocument.getPath(JSPSearchDocument.java:149)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.search.JavaSearchDocumentDelegate.<init>(JavaSearchDocumentDelegate.java:30)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.search.JSPSearchSupport.createSearchDocument(JSPSearchSupport.java:426)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.search.JSPSearchSupport.addJspFile(JSPSearchSupport.java:320)
     [java]     at
org.eclipse.jst.jsp.core.internal.java.search.JSPIndexManager$ProcessFilesJob.run(JSPIndexManager.java:251)
     [java]     at org.eclipse.core.internal.jobs.Worker.run(Worker.java:76)
Comment 3 David Williams CLA 2005-11-12 01:57:06 EST
There's many possiblities of error here. 

Other than the flaky stuff I know about, an intersting part of this use case 
is this part of the stack trace: 

org.eclipse.core.internal.filebuffers.ResourceFileBuffer.commit(ResourceFileBuffer.java:327)
     [java]     at
com.bea.wlw.template.textinserter.TextInserter.insertText(TextInserter.java:75)
     [java]     at
com.bea.wlw.jsp.core.commands.GenericTagCommand.performInsert(GenericTagCommand.java:189)
     [java]     at
com.bea.wlw.jsp.core.commands.GenericTagCommand.execute(GenericTagCommand.java:118)
     [java]     at
com.bea.wlw.netui.ui.jsp.commands.BaseDialogCommand.execute(BaseDialogCommand.java:53)

Its not that this part causes the problem per se, but hints that some previous
use of ResouceBuffer, Document, and/or Model (actually, their interactions) that
may have left things in a bad state. 

Ironically, this appears to be using as we intend ... but ... we do not do so
much, in this way, at this point, and there's likely thread coordination issues
we have planned, but have not put in place. 

So, here's some off hand questions on the general case ... 
Do the resource being used exist ahead of time, or is it sometimes completely
new? (You'll be more likely to see problems for completely new resources,
especially if the are saved, and then processed some more. (There's some issues
where the "ID" we use internally is miscomputed, some would say, for completely
new resources, and some parts of the "system" thinks there's two documents, when
there's really just one. 

Do you directly use our model or Document *and* the resouce buffer ... or just
the buffer? (and model and document just used indirectly? ) 


Comment 4 Tom Stamm CLA 2005-11-19 11:27:19 EST
What our code is doing here is inserting a tag based on a drag/drop gesture from
a design palette. The tag itself is generated from a template, and inserted as
text into the file buffer, at the current caret offset in the editor. The
TextInserter code gets an ITextFileBuffer from the buffer manager, connects to
it, gets the buffer's IDocument, then creates and applies an InsertEdit. After
applying the edit, if the buffer was not previously dirty, it calls commit on
the buffer.

Right before doing the text insert, we do access the structured model to look
for taglib imports of the tag we are generating, so that we can use the right
prefix. We do this by calling
StructuredModelManager.getModelManager().getModelForRead( jspFile ) where
jspFile is the IFile, to get the IStructureModel, then get a DOM by calling
structuredModel.getAdapter( Document.class ), and iterating through the import
tags until we find one with the right uri. We call releaseFromRead on the
structured model in a finally block.

One thing I just noticed while looking back through the code is that we get the
Element for the taglib import, release the model from read, and then get the
prefix attribute from that element. It happens after the model's been released,
but before the text insertion. I'm not sure if that could be a problem...?

After we do the text insert, if we couldn't find an import for the tag, we get
the structured model again by calling getModelForEdit(), and then create and
insert the taglib nodes (but that hasn't happened by the time this NPE hit). It
is done in this order because we found that if we added the nodes to the DOM
before doing the text insert, sometimes one or the other would get "lost", as if
the text insert and the DOM node insert were applied to different internal
instances, and one would "win" over the other when the actual text buffer was
updated.

I hope that wasn't too much detail :-)
Comment 5 David Williams CLA 2005-11-19 18:41:08 EST
Definitly not too much detail! In fact, with that much detail, sounds like
you're close to providing a standalone JUnit test :) 

There are a large number of issues going on here, and while I don't
know/understand them all ... I'll post notes as I gain understanding, and
perhaps that will at least keep progress moving forward. 

>What our code is doing here is inserting a tag based on a drag/drop gesture from
>a design palette. The tag itself is generated from a template, and inserted as
>text into the file buffer, at the current caret offset in the editor. The
>TextInserter code gets an ITextFileBuffer from the buffer manager, connects to
>it, gets the buffer's IDocument, then creates and applies an InsertEdit. After
>applying the edit, if the buffer was not previously dirty, it calls commit on
>the buffer.

The thing that stands out here is the end: "calls commit on the buffer". 
If you call commit directly on the buffer, do you first get (compute) the
commitSchedulingRule? Even if you "might" commit, 
you should get that scheduling rule first and, I think, before any part of the
operations in this paragraph! Granted, this may cause some cases, such as if
autobuild is in progress, there the drag/drop from pallette will cause a dialog
to pop up that says "user operation is blocked by backgroud job" ... but ..
that's the idea to gaurd data. And, improvements in this "user experience" will
take some deeper work. 
[I'm not sure this is the cause of this particular bug ... I'm just trying to 
outline "correct client behavior" ... just in case]. 


>One thing I just noticed while looking back through the code is that we get the
>Element for the taglib import, release the model from read, and then get the
>prefix attribute from that element. It happens after the model's been released,
>but before the text insertion. I'm not sure if that could be a problem...?

In general, yes, this is incorrrect client behavior ... once released, nothing
should be done with any part of the model. [Again, not sure if this is cause of
this bug, but could be related]. 




I'm (still) guessing part of this bug is due to the "new file vs. existing file"
bugs that are resulting due to some behavior in text buffer manager we did not
well anticipate ... and related to bugs 107311, 107316, and 107320 .... so I'll
take a look at those this weekend. 

I expect, however, in the complex case you've detailed, it will take a fair
amount of work to track down and fix all the scheduling and thread issues. 
Comment 6 Tom Stamm CLA 2005-11-19 18:50:30 EST
Interesting! I don't think we are getting the commit scheduling rule, I'll look
into that; and to keeping the DOM element after releasing the model.

I forgot one of your original questions - in this case, the file was already
existing. This didn't happen while creating a new file.

Also, as far as I know, this particular NPE was only reported once; and these
tests are run continuously every day. So it's definitely much less common than
some of the other threading issues we've run into. (mostly involving usage of EMF)
Comment 7 Nitin Dahyabhai CLA 2006-04-20 16:48:30 EDT
*** Bug 102223 has been marked as a duplicate of this bug. ***
Comment 8 Nitin Dahyabhai CLA 2006-06-01 13:03:46 EDT
Decreasing priority.  If anyone is able to consistently reproduce this and/or has a JUnit test for it, we'll bump it back up.
Comment 9 Nitin Dahyabhai CLA 2009-04-19 23:32:31 EDT
Closing as worksforme.  The model's document can become null when it's released completely and discarded, which could lead to a "null" document being sent to the FileBufferModelManager's releaseModel method.  Could also have been related to bug 205733.  Please reopen if you run across it again so we can renew the investigation on something more current.