Community
Participate
Working Groups
Build ID: Eclipse 3.4M6a Steps To Reproduce: I am seeing the following stack trace in my code: java.lang.NullPointerException at org.eclipse.jface.text.source.AnnotationModel.connect(AnnotationModel.java:513) at org.eclipse.core.internal.filebuffers.ResourceTextFileBuffer.getAnnotationModel(ResourceTextFileBuffer.java:152) <snip> I think there is a thread-safety issue with both subclasses of ITextFileBuffer. This is what I'm doing: I was listening to a buffer create. I stashed away the buffer for later use. The thing that created the buffer is doing its thing on say, Thread A. My Thread B comes along and says... hey, I need some info from the annotations associated with the file. So it lookes at the stashed away buffer and does getAnnotationModel(). getAnnotationModel() starts doing a connect(). In the mean time, Thread A is done with the buffer, and i assume, disposes it But connect() was in the middle of doing something... it tries to add a listener to the fDocument but it can't because it's already null because it was disposed. The solution is that I think ResourceTextFileBuffer (and the other one) needs to protect it's dispose() method using the same fAnnotationModelCreationLock lock that it uses for the getAnnotationModel(). Well, not the *whole* dispose method, but the section that is disposing the annotation model. More information:
Please read Javadoc of IFileBuffer: * It is not specified whether simultaneous editing sessions can be owned by * different threads. * </p> What could help you is: org.eclipse.core.filebuffers.manipulation.GenericFileBufferOperationRunner org.eclipse.core.filebuffers.manipulation.IFileBufferOperation See also: org.eclipse.core.filebuffers.ISynchronizationContext
What you've suggested won't help me. The javadocs for IFileBufferOperation state that * A file buffer operation performs changes of the contents of a file buffer. I'm not changing the contents of the IFileBuffer at all. Additionally, the IFileBufferOperation will commit() the buffer which would be very bad for performance since I'm simply trying to read it. The other two files you mentioned seem to be related to the execution of the IFileBufferOperation. Also, in the javadoc quoted here: * It is not specified whether simultaneous editing sessions can be owned by * different threads. It is referring to simultaneous *editing* sessions. I wouldn't consider calling getAnnotationModel() to be an *editing* operation. I believe there are two categories of manipulating buffers. Lifecycle operations (create/dispose) and character manipulation, the later of which I *would* consider a edit op. Let me restate my problem. I'm simply trying to read the annotations for a file buffer. I have an IFileBufferListener that listens to create/dispose events. On create/dispose it will register/deregister a IDocument listener to the document associated with the IFileBuffer. Additionally, it adds ITextFileBuffer to a map when created and removed it when disposed. The document listener updates/creates positions and annotations if the file changes while it is open. A background processing thread needs to query these annotations (if they are present.) If the background processing thread enters the ITextFileBuffer.getAnnotationModel() while similtaneously the ITextFileBuffer is disposed(), the getAnnotationModel() throws a very uninformative and unwanted NullPointerException. It seems that a little adding a bit of thread safety to the *lifecycle* manipulations of a IFileBuffer would be the way to solve this. (I could call getAnnotationModel at the time of create() but that also seems like it would be a very bad performance hit - as I'm listening to *all* ITextFileBuffers)
Maybe you already noticed, but the annotation model itself is currently also not thread-safe (see bug 69289). In your case the best bet for now is to run your code that gets the annotation model in the UI thread. Reopening as the current API for getAnnotationModel() is not clear, e.g. it doesn't spec that 'null' might be returned.
(In reply to comment #3) > Maybe you already noticed, but the annotation model itself is currently also > not thread-safe (see bug 69289). > > In your case the best bet for now is to run your code that gets the annotation > model in the UI thread. What is special about the UI thread? It seems to me that FileBuffers.getTextFileBufferManager().disconnect() can and *does* get called from the non-UI thread. If this happens, even if I'm calling getAnnotationModel() in the UI thread, I will still have the same problem. Only if *everybody* that accessed the getTextFileBufferManager() did so from same thread would it work. > Reopening as the current API for getAnnotationModel() is not clear, e.g. it > doesn't spec that 'null' might be returned. > If 'null' was being returned, I'd be happy. But what is happening is a NullPointerException is being thrown.
Fixed in HEAD (adjusted Javadoc and made AnnotationModel.connect(...) more stable. Available in builds > N20080911-2000.