"Invalid stub element type in index.. " exception - what is the cause?

hello,

I frequently encounter this type of error message when parsing PSI structure of my test project.
From what I read about stubs in IDEA I reckon some cached file contents have lost sync with the contents of their 'source' files - am I correct ?
I would be very grateful if someone could shed some light on what to do with these exceptions - should
I simply ignore them or is there a way to get rid of them for good ?

Thanks in advance,
regards
Simon

16 comments

Please post full stack trace. Are sources of your plugin available?


0

hello,
sorry, I don't have a stack trace at the moment (I'll post one as soon as I encounter this exception) and the sources are available only in our company's internal VCS but the problem occurs for example after updating the test project's sources and launching the plugin in 'debug' mode (from sandbox). It then browses the projects' content roots (sources + libraries) searching for certain input files (xml + java sources), parsing them and building some kind of data holders to store the retrieved information.
I guess that's when the problem occurs - when I try to access the PSI structure of 'externally' (from VCS) modified files.
Is there any way to force IDEA to refresh its' stubs before accessing file's PSI structure ?

0

stack trace - as promised.
it is not mine (it was submitted via our error report submitter by one of my colleagues) so I don't know the full context of this exception - but it seems to have been triggered after fileCreated event by 'accept' method call of this PSI matcher :

          PsiElement[] setNameMatches =
                PsiTreeUtil.collectElements(p_definitionClass, new PsiElementFilter() {
                    @Override
                    public boolean isAccepted(PsiElement element) {
                        return SET_NAME_METHOD_CALL_EXPR_STMT.accepts(element);
                    }
                });

stack trace :

Invalid stub element type in index: file://C:/projects/git/git_okratek/mors/web/src/main/java/pl/com/tiger/mors/navigators/main/states/MainManagerBatchDetailsState.java;  found: PsiModifierList:public; file stamp: 121725; file modCount: 1392719623370;  unsaved: false; doc stamp: 1273; committed: true; psi stamp: 1; viewProvider  stamp: 1273

java.lang.Throwable
at  com.intellij.openapi.diagnostic.Logger.error(Logger.java:54)
at  com.intellij.psi.stubs.StubIndexImpl.reportStubPsiMismatch(StubIndexImpl.java:424)
at  com.intellij.psi.stubs.StubIndex.safeGet(StubIndex.java:76)
at  com.intellij.psi.impl.java.stubs.index.JavaFullClassNameIndex.get(JavaFullClassNameIndex.java:48)
at  com.intellij.psi.impl.file.impl.JavaFileManagerBase.findClasses(JavaFileManagerBase.java:131)
at  com.intellij.psi.impl.JavaPsiFacadeImpl$PsiElementFinderImpl.findClasses(JavaPsiFacadeImpl.java:287)
at  com.intellij.psi.impl.JavaPsiFacadeImpl.findClasses(JavaPsiFacadeImpl.java:146)
at  com.intellij.psi.impl.file.PsiPackageImpl.a(PsiPackageImpl.java:178)
at  com.intellij.psi.impl.file.PsiPackageImpl.a(PsiPackageImpl.java:259)
at  com.intellij.psi.impl.file.PsiPackageImpl.processDeclarations(PsiPackageImpl.java:216)
at  com.intellij.psi.impl.source.PsiJavaFileBaseImpl.a(PsiJavaFileBaseImpl.java:390)
at  com.intellij.psi.impl.source.PsiJavaFileBaseImpl.a(PsiJavaFileBaseImpl.java:337)
at  com.intellij.psi.impl.source.PsiJavaFileBaseImpl.processDeclarations(PsiJavaFileBaseImpl.java:288)
at  com.intellij.psi.scope.util.PsiScopesUtil.treeWalkUp(PsiScopesUtil.java:71)
at  com.intellij.psi.scope.util.PsiScopesUtil.treeWalkUp(PsiScopesUtil.java:53)
at  com.intellij.psi.scope.util.PsiScopesUtil.resolveAndWalk(PsiScopesUtil.java:219)
at  com.intellij.psi.scope.util.PsiScopesUtil.resolveAndWalk(PsiScopesUtil.java:150)
at  com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl.b(PsiJavaCodeReferenceElementImpl.java:444)
at  com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl.access$000(PsiJavaCodeReferenceElementImpl.java:54)
at  com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl$OurGenericsResolver.resolve(PsiJavaCodeReferenceElementImpl.java:325)
at  com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl$OurGenericsResolver.resolve(PsiJavaCodeReferenceElementImpl.java:317)
at  com.intellij.psi.impl.source.resolve.ResolveCache$2.compute(ResolveCache.java:107)
at  com.intellij.openapi.util.RecursionManager$2.doPreventingRecursion(RecursionManager.java:110)
at  com.intellij.psi.impl.source.resolve.ResolveCache.a(ResolveCache.java:104)
at  com.intellij.psi.impl.source.resolve.ResolveCache.resolveWithCaching(ResolveCache.java:132)
at  com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl.multiResolve(PsiJavaCodeReferenceElementImpl.java:371)
at  com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl.advancedResolve(PsiJavaCodeReferenceElementImpl.java:345)
at  com.intellij.psi.impl.source.PsiClassReferenceType.resolveGenerics(PsiClassReferenceType.java:141)
at  com.intellij.psi.util.PsiUtil.captureToplevelWildcards(PsiUtil.java:663)
at  com.intellij.psi.impl.PsiImplUtil.normalizeWildcardTypeByPosition(PsiImplUtil.java:497)
at  com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl$TypeEvaluator.a(PsiMethodCallExpressionImpl.java:226)
at  com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl$TypeEvaluator.fun(PsiMethodCallExpressionImpl.java:155)
at  com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl$TypeEvaluator.fun(PsiMethodCallExpressionImpl.java:147)
at  com.intellij.psi.impl.source.resolve.JavaResolveCache.getType(JavaResolveCache.java:93)
at  com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl.getType(PsiMethodCallExpressionImpl.java:48)
at  com.intellij.psi.scope.util.PsiScopesUtil.setupAndRunProcessor(PsiScopesUtil.java:312)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl.d(PsiReferenceExpressionImpl.java:274)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl.a(PsiReferenceExpressionImpl.java:259)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl.access$000(PsiReferenceExpressionImpl.java:61)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl$OurGenericsResolver.resolve(PsiReferenceExpressionImpl.java:196)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl$OurGenericsResolver.resolve(PsiReferenceExpressionImpl.java:185)
at  com.intellij.psi.impl.source.resolve.ResolveCache$2.compute(ResolveCache.java:107)
at  com.intellij.openapi.util.RecursionManager$2.doPreventingRecursion(RecursionManager.java:110)
at  com.intellij.psi.impl.source.resolve.ResolveCache.a(ResolveCache.java:104)
at  com.intellij.psi.impl.source.resolve.ResolveCache.resolveWithCaching(ResolveCache.java:132)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl.multiResolve(PsiReferenceExpressionImpl.java:337)
at  com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl$TypeEvaluator.fun(PsiMethodCallExpressionImpl.java:153)
at  com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl$TypeEvaluator.fun(PsiMethodCallExpressionImpl.java:147)
at  com.intellij.psi.impl.source.resolve.JavaResolveCache.getType(JavaResolveCache.java:93)
at  com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl.getType(PsiMethodCallExpressionImpl.java:48)
at  com.intellij.psi.impl.source.tree.java.PsiExpressionListImpl.getExpressionTypes(PsiExpressionListImpl.java:48)
at  com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver.<init>(JavaMethodsConflictResolver.java:51)
at  com.intellij.psi.scope.processor.MethodResolverProcessor.<init>(MethodResolverProcessor.java:30)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl.d(PsiReferenceExpressionImpl.java:272)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl.a(PsiReferenceExpressionImpl.java:259)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl.access$000(PsiReferenceExpressionImpl.java:61)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl$OurGenericsResolver.resolve(PsiReferenceExpressionImpl.java:196)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl$OurGenericsResolver.resolve(PsiReferenceExpressionImpl.java:185)
at  com.intellij.psi.impl.source.resolve.ResolveCache$2.compute(ResolveCache.java:107)
at  com.intellij.openapi.util.RecursionManager$2.doPreventingRecursion(RecursionManager.java:110)
at  com.intellij.psi.impl.source.resolve.ResolveCache.a(ResolveCache.java:104)
at  com.intellij.psi.impl.source.resolve.ResolveCache.resolveWithCaching(ResolveCache.java:132)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl.multiResolve(PsiReferenceExpressionImpl.java:337)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionBase.advancedResolve(PsiReferenceExpressionBase.java:86)
at  com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionBase.resolve(PsiReferenceExpressionBase.java:48)
at  com.intellij.patterns.PsiElementPattern$14.accepts(PsiElementPattern.java:276)
at  com.intellij.patterns.PsiElementPattern$14.accepts(PsiElementPattern.java:272)
at  com.intellij.patterns.ElementPatternCondition.accepts(ElementPatternCondition.java:39)
at  com.intellij.patterns.ObjectPattern.accepts(ObjectPattern.java:53)
at  com.intellij.patterns.TreeElementPattern$8.accepts(TreeElementPattern.java:202)
at  com.intellij.patterns.ElementPatternCondition.accepts(ElementPatternCondition.java:39)
at  com.intellij.patterns.CollectionPattern$3.accepts(CollectionPattern.java:55)
at  com.intellij.patterns.CollectionPattern$3.accepts(CollectionPattern.java:52)
at  com.intellij.patterns.ElementPatternCondition.accepts(ElementPatternCondition.java:39)
at  com.intellij.patterns.ObjectPattern.accepts(ObjectPattern.java:53)
at  com.intellij.patterns.PatternConditionPlus.process(PatternConditionPlus.java:45)
at  com.intellij.patterns.PatternConditionPlus.process(PatternConditionPlus.java:26)
at  com.intellij.patterns.TreeElementPattern$2.processValues(TreeElementPattern.java:86)
at  com.intellij.patterns.PatternConditionPlus.accepts(PatternConditionPlus.java:41)
at  com.intellij.patterns.ElementPatternCondition.accepts(ElementPatternCondition.java:39)
at  com.intellij.patterns.CollectionPattern$3.accepts(CollectionPattern.java:55)
at  com.intellij.patterns.CollectionPattern$3.accepts(CollectionPattern.java:52)
at  com.intellij.patterns.ElementPatternCondition.accepts(ElementPatternCondition.java:39)
at  com.intellij.patterns.ObjectPattern.accepts(ObjectPattern.java:53)
at  com.intellij.patterns.PatternConditionPlus.process(PatternConditionPlus.java:45)
at  com.intellij.patterns.PatternConditionPlus.process(PatternConditionPlus.java:26)
at  com.intellij.patterns.TreeElementPattern$2.processValues(TreeElementPattern.java:86)
at  com.intellij.patterns.PatternConditionPlus.accepts(PatternConditionPlus.java:41)
at  com.intellij.patterns.ElementPatternCondition.accepts(ElementPatternCondition.java:39)
at  com.intellij.patterns.ObjectPattern.accepts(ObjectPattern.java:49)
at  pl.com.tiger.navigators.plugin.dataFeeder.structureBuilders.impl.FromStateClassDSBuilder$1.isAccepted(FromStateClassDSBuilder.java:110)
at  com.intellij.psi.search.PsiElementProcessor$CollectFilteredElements.execute(PsiElementProcessor.java:85)
at  com.intellij.psi.util.PsiTreeUtil$4.visitElement(PsiTreeUtil.java:646)
at  com.intellij.psi.impl.source.tree.java.PsiExpressionStatementImpl.accept(PsiExpressionStatementImpl.java:80)
at  com.intellij.psi.PsiWalkingState.visit(PsiWalkingState.java:61)
at  com.intellij.psi.PsiWalkingState.visit(PsiWalkingState.java:26)
at  com.intellij.util.WalkingState.walkChildren(WalkingState.java:65)
at  com.intellij.util.WalkingState.elementStarted(WalkingState.java:52)
at  com.intellij.psi.PsiWalkingState.elementStarted(PsiWalkingState.java:70)
at  com.intellij.psi.PsiRecursiveElementWalkingVisitor.visitElement(PsiRecursiveElementWalkingVisitor.java:48)
at  com.intellij.psi.util.PsiTreeUtil$4.visitElement(PsiTreeUtil.java:647)
at  com.intellij.psi.impl.source.PsiClassImpl.accept(PsiClassImpl.java:485)
at  com.intellij.psi.util.PsiTreeUtil.processElements(PsiTreeUtil.java:642)
at  com.intellij.psi.util.PsiTreeUtil.collectElements(PsiTreeUtil.java:607)
at  pl.com.tiger.navigators.plugin.dataFeeder.structureBuilders.impl.FromStateClassDSBuilder.scanDefinitionClass(FromStateClassDSBuilder.java:106)
at  pl.com.tiger.navigators.plugin.dataFeeder.structureBuilders.impl.FromStateClassDSBuilder.scanDefinitionClass(FromStateClassDSBuilder.java:23)
at  pl.com.tiger.navigators.plugin.dataFeeder.structureBuilders.FromClassDSBuilder.buildStructures(FromClassDSBuilder.java:41)
at  pl.com.tiger.navigators.plugin.components.StructureManager$4.visitFile(StructureManager.java:268)
at  com.intellij.openapi.vfs.VirtualFileVisitor.visitFileEx(VirtualFileVisitor.java:124)
at  com.intellij.openapi.vfs.VfsUtilCore.visitChildrenRecursively(VfsUtilCore.java:204)
at  pl.com.tiger.navigators.plugin.components.StructureManager.internalRebuildStructures(StructureManager.java:261)
at  pl.com.tiger.navigators.plugin.components.StructureManager.rebuildStructures(StructureManager.java:251)
at  pl.com.tiger.navigators.plugin.components.StructureManager$3.fileCreated(StructureManager.java:206)
at  sun.reflect.GeneratedMethodAccessor173.invoke(Unknown Source)
at  sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at  java.lang.reflect.Method.invoke(Method.java:601)
at  com.intellij.util.EventDispatcher.dispatch(EventDispatcher.java:89)
at  com.intellij.util.EventDispatcher.access$100(EventDispatcher.java:34)
at  com.intellij.util.EventDispatcher$1.invoke(EventDispatcher.java:66)
at  $Proxy14.fileCreated(Unknown Source)
at  com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter.fireAfter(BulkVirtualFileListenerAdapter.java:80)
at  com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter.after(BulkVirtualFileListenerAdapter.java:56)
at  sun.reflect.GeneratedMethodAccessor155.invoke(Unknown Source)
at  sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at  java.lang.reflect.Method.invoke(Method.java:601)
at  com.intellij.util.messages.impl.MessageBusConnectionImpl.deliverMessage(MessageBusConnectionImpl.java:120)
at  com.intellij.util.messages.impl.MessageBusImpl.doPumpMessages(MessageBusImpl.java:228)
at  com.intellij.util.messages.impl.MessageBusImpl.pumpMessages(MessageBusImpl.java:219)
at  com.intellij.util.messages.impl.MessageBusImpl.sendMessage(MessageBusImpl.java:209)
at  com.intellij.util.messages.impl.MessageBusImpl.access$000(MessageBusImpl.java:43)
at  com.intellij.util.messages.impl.MessageBusImpl$1.invoke(MessageBusImpl.java:131)
at  $Proxy15.after(Unknown Source)
at  com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl.processEvents(PersistentFSImpl.java:750)
at  com.intellij.openapi.vfs.newvfs.RefreshSessionImpl.fireEventsInWriteAction(RefreshSessionImpl.java:189)
at  com.intellij.openapi.vfs.newvfs.RefreshSessionImpl$1.run(RefreshSessionImpl.java:173)
at  com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:1013)
at  com.intellij.openapi.vfs.newvfs.RefreshSessionImpl.fireEvents(RefreshSessionImpl.java:170)
at  com.intellij.openapi.vfs.newvfs.RefreshQueueImpl$1$1.run(RefreshQueueImpl.java:90)
at  com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.run(LaterInvocator.java:343)
at  java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at  java.awt.EventQueue.dispatchEventImpl(EventQueue.java:721)
at  java.awt.EventQueue.access$200(EventQueue.java:103)
at  java.awt.EventQueue$3.run(EventQueue.java:682)
at  java.awt.EventQueue$3.run(EventQueue.java:680)
at  java.security.AccessController.doPrivileged(Native Method)
at  java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at  java.awt.EventQueue.dispatchEvent(EventQueue.java:691)
at  com.intellij.ide.IdeEventQueue.d(IdeEventQueue.java:700)
at  com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:525)
at  com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:348)
at  java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at  java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at  java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at  java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at  java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at  java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

0

It's an internal IDEA's issue. Could you please try to reproduce it on IDEA 13.1 EAP? It might be fixed there. If not, we'd appreciate very much exact steps to reproduce.

0

hello Peter,
thanks for a quick response.
I use IDEA 12.1.6 and don't intend to upgrade to 13.x any time soon (I need to pay for the license myself plus I read about your new yearly subscription feature starting with 13.x which I think is a step backwards since it forces the user to upgrade more frequently).
It's not easy to reproduce this exception - it occurs randomly after some fileCreated / contentsChanged event when I launch my data structures refresh and access the PSI trees of affected files.
Anyway - if I understand correctly - it is an acknowledged 'issue' and since it might have even been fixed in 13.1 EAP - may I expect a bugfix for 12.x any time in the future ? Or have you ceased supporting 12.x branch with the release of 13.x ?

0

We ceased to backport the fixes to 12.1.X

0

won't fix, huh?
That in a way answers my question so once again - thx for response.

0

Actually you would better to avoid accessing PSI inside event handler, if your code do it slightly later you should have less such errors

0

thanks for the tip, Maxim
Actually I don't access the PSI tree directly from the event handler -> I call 'rebuildStructures(VirtualFile startingFrom)', iterate over registered class-specific 'builders' and do it from there.
Are you suggesting that if I gave IDEA more time to refresh its internal data structures after the event has been intercepted - this exception wouldn't occur ?
Is there a way to wait for a PSI refresh / force such refresh to avoid these kind of errors altogether ?

0

Your code is using psi indirectly and forcing e.g. index to rebuild values within file events processing.
Event listener should remember something updated and rebuild the state later, possibly merging updates if needed. E.g. see MergingUpdateQueue

0

I see.
I haven't found any documentation on how to use these event listeners properly - what is allowed or discouraged - and that's why I'm a bit lost here. And the exceptions I occasionally come across don't help to clarify it.
I assumed that when I'm notified about 'rootsChanged' event, all the internal structures and indices are already recalculated and I'm free to access them as I see fit.
Could you please point me to or post some usage examples of MergingUpdateQueue ?
Or better yet - could you please take a look at my 'rootsChanged' implementation and tell me how to modify it to make it work ?
Here's the code :

// project source root / library class root added / removed -> rebuild structures
        myProject.getMessageBus().connect().subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
            @Override
            public void rootsChanged(ModuleRootEvent event) {
                LOG.debug("-- rootsChanged event fired -> rebuilding data structures");
                try {

                    ProjectRootManager rootManager = ProjectRootManager.getInstance(myProject);

                    VirtualFile[] sourceRoots = rootManager.getContentSourceRoots();
                    VirtualFile[] libraryClassRoots = rootManager.orderEntries().librariesOnly().getClassesRoots();

                    HashSet<VirtualFile> currentContentRoots = new HashSet<>();
                    ContainerUtil.addAll(currentContentRoots, sourceRoots);
                    ContainerUtil.addAll(currentContentRoots, libraryClassRoots);

                    HashSet<VirtualFile> unmatchedContentRoots = new HashSet<>();
                    // copy to prevent concurrent modification exception..
                    Sets.symmetricDifference(knownContentRoots, currentContentRoots).copyInto(unmatchedContentRoots);

                    // scan project content roots for changes (new / removed source roots, new / removed library class roots)

                    LOG.debug("\nunmatched project content roots :");
                    for (VirtualFile unmatchedRoot : unmatchedContentRoots) {
                        String info = "content root [" + unmatchedRoot.getPresentableUrl() + "] : {}";
                        if (!knownContentRoots.contains(unmatchedRoot)) {
                            LOG.debug(info, "new -> scanning for structure definition files");
                            // new content root -> scan for structure definition files..
                            knownContentRoots.add(unmatchedRoot);
                            rebuildStructures(unmatchedRoot);
                            continue;
                        }
                        // deleted content root -> delete related data structures and content root from knownContentRoots collection
                        LOG.debug(info, "removed from project structure");
                        removeDataObjects(unmatchedRoot);
                        knownContentRoots.remove(unmatchedRoot);
                    }

                } catch (RuntimeException re) {
                    throw ExceptionDecorator.processException(re, "Error updating data structures after rootsChanged event",
                          myProject, DumbService.isDumb(myProject));
                }
            }
        });


The 'magic' is 'rebuildStructures(unmatchedRoot)' method call - that's where I iterate over unmatchedRoot's contents searching for input files I'm interested in (xml + java), parse them and create some data holders for the retrieved information. And that's what produces these exceptions. Oh, and 'knownContentRoots' is a collection of content roots, registered on project startup (project component's field).
So what would you suggest ?

0

one more thing - since you suggest using MergeUpdateQueue to postpone my rebuild, I reckon there must be some flag somewhere, indicating that the PSI structure refresh has been completed. Am I correct ?
Some kind of 'dumb mode' for the PSI indexer ?
Is there a way to just wait for IDEA to finish its job - some kind of DumbService.waitForSmart() thingy to pause program execution and wait for a green light to come up ?

0

Please note that we started to talk about workarounds and not best practices.
Dumb mode is switched on upon large update (and there is DumbService.isDumb(), runWhenSmart, etc).
Roots changed event is produced upon library change (e.g. different jar files) - for some reason you switched from file events to library ones.

I recommend to see MvcModuleStructureSynchronizer in latest CE sources for nice example of writing file events listener that queues updates
FrameworkDetectionManager is example of using MergingUpdateQueue that listens for dumb changes.

0

And the reason is lack of sufficient documentation to get started.
And the answers I keep getting - most of them are 'yes / no' type and many of my 'open' questions ('please clarify on sth') are simply ignored. I'm no programming expert and I'm trying to learn as much as I can to produce the code that behaves as expected and makes lives of my colleages easier.
I switched from file events to library ones because they are related - when I intercept a library change I usually want to find out what has changed. And that usually involves browsing library contents in search of files I deem interesting.
So to recap - thank yout for your help and please forgive me being so inquisitive - if there was a thorough documentation regarding writing plugins, I wouldn't have to ask all of these questions and you wouldn't have to answer them.

0

please forgive my slight overreaction.
The truth is I like to know HOW THINGS WORK and the only feedback I keep getting here is HOW TO MAKE THEM WORK. I simply lack some background knowledge - what happens under the hood and why do I need to do this or that.
I appreciate all the help I get from all of the JB team and I don't doubt your good intentions but the answers I'm receiving are most frequently to brief to fill me in.
I understand you have more important things to take care of than teaching newbies - I would gladly spend a few euros on a book on writing plugins for IDEA but there is none I know of. The confluence web page is just a primer and while undoubtedly helpful, it doesn't raise many important issues.
The JB forum on the other hand is also of little value since the plugin-writer community seems to be rather sparse which means the knowledge base is very limited.
So once again - thanks for your support and I hope my little outburst won't ban me from this forum :)

0

Please sign in to leave a comment.