Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: JRuby 1.2
-
Fix Version/s: JRuby 1.3RC1
-
Component/s: None
-
Labels:None
Description
Looks like the synchronization removed by the fix to JRUBY-3308 was necessary after all...
We now get the following stack trace:
java.util.concurrent.ExecutionException: org.jruby.exceptions.RaiseException: IO error -- C:\work\installations\RubyMine 821\rb\paramdefs\rails/../paramdefs_loader_base at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222) at java.util.concurrent.FutureTask.get(FutureTask.java:83) at com.intellij.concurrency.PrioritizedFutureTask.done(PrioritizedFutureTask.java:21) at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619) Caused by: org.jruby.exceptions.RaiseException: IO error -- C:\work\installations\RubyMine 821\rb\paramdefs\rails/../paramdefs_loader_base at (unknown).initialize(C:\work\installations\RubyMine 821\rb\paramdefs\rails\paramdefs_loader.rb:9) at Kernel.require(C:\work\installations\RubyMine 821\rb\paramdefs\rails\paramdefs_loader.rb:9) at (unknown).(unknown)(C:\work\installations\RubyMine 821\rb\paramdefs\rails\paramdefs_loader.rb:1) at (unknown).(unknown)(:1) Caused by: java.util.ConcurrentModificationException at java.util.WeakHashMap$HashIterator.nextEntry(WeakHashMap.java:762) at java.util.WeakHashMap$KeyIterator.next(WeakHashMap.java:795) at org.jruby.RubyClass.invalidateCacheDescendants(RubyClass.java:671) at org.jruby.RubyClass.invalidateCacheDescendants(RubyClass.java:672) at org.jruby.RubyClass.invalidateCacheDescendants(RubyClass.java:672) at org.jruby.RubyClass.invalidateCacheDescendants(RubyClass.java:672) at org.jruby.RubyClass.invalidateCacheDescendants(RubyClass.java:672) at org.jruby.RubyModule.includeModule(RubyModule.java:513) at org.jruby.RubyModule.append_features(RubyModule.java:1877) at org.jruby.RubyModule$i_method_1_0$RUBYINVOKER$append_features.call(org/jruby/RubyModule$i_method_1_0$RUBYINVOKER$append_features.gen) at org.jruby.RubyClass.finvoke(RubyClass.java:468) at org.jruby.javasupport.util.RuntimeHelpers.invoke(RuntimeHelpers.java:392) at org.jruby.RubyBasicObject.callMethod(RubyBasicObject.java:321) at org.jruby.RubyModule.include(RubyModule.java:1902) at org.jruby.TopSelfFactory$2.execute(TopSelfFactory.java:78) at org.jruby.internal.runtime.methods.SimpleCallbackMethod.call(SimpleCallbackMethod.java:67) at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:243) at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:152) at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:273) at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:112) at org.jruby.ast.FCallOneArgNode.interpret(FCallOneArgNode.java:36) at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:104) at org.jruby.ast.BlockNode.interpret(BlockNode.java:71) at org.jruby.ast.RootNode.interpret(RootNode.java:129) at org.jruby.Ruby.loadFile(Ruby.java:2247) at org.jruby.runtime.load.ExternalScript.load(ExternalScript.java:58) at org.jruby.runtime.load.LoadService.tryLoadingLibraryOrScript(LoadService.java:570) at org.jruby.runtime.load.LoadService.smartLoad(LoadService.java:277) at org.jruby.runtime.load.LoadService.require(LoadService.java:288) at org.jruby.RubyKernel.require(RubyKernel.java:839) at org.jruby.RubyKernel$s_method_1_0$RUBYFRAMEDINVOKER$require.call(org/jruby/RubyKernel$s_method_1_0$RUBYFRAMEDINVOKER$require.gen) at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodOneOrNBlock.call(JavaMethod.java:312) at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:273) at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:112) at org.jruby.ast.FCallOneArgNode.interpret(FCallOneArgNode.java:36) at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:104) at org.jruby.ast.BlockNode.interpret(BlockNode.java:71) at org.jruby.ast.RootNode.interpret(RootNode.java:129) at org.jruby.Ruby.loadFile(Ruby.java:2247) at org.jruby.runtime.load.ExternalScript.load(ExternalScript.java:58) at org.jruby.runtime.load.LoadService.tryLoadingLibraryOrScript(LoadService.java:570) at org.jruby.runtime.load.LoadService.smartLoad(LoadService.java:277) at org.jruby.runtime.load.LoadService.require(LoadService.java:288) at org.jetbrains.plugins.ruby.ruby.lang.RubySupportLoader$2.run(RubySupportLoader.java:1) at org.jetbrains.plugins.ruby.ruby.lang.RubySupportLoader.a(RubySupportLoader.java:12) at org.jetbrains.plugins.ruby.ruby.lang.RubySupportLoader.require(RubySupportLoader.java:49) at org.jetbrains.plugins.ruby.ruby.lang.RubySupportLoader$1.run(RubySupportLoader.java:1) at org.jetbrains.plugins.ruby.ruby.lang.RubySupportLoader.a(RubySupportLoader.java:12) at org.jetbrains.plugins.ruby.ruby.lang.RubySupportLoader.loadRubyScript(RubySupportLoader.java:75) at org.jetbrains.plugins.ruby.rails.codeInsight.RailsParamDefProvider.registerParamDefs(RailsParamDefProvider.java:5) at org.jetbrains.plugins.ruby.ruby.codeInsight.paramDefs.ParamDefManager.<init>(ParamDefManager.java:6) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at org.picocontainer.defaults.InstantiatingComponentAdapter.newInstance(InstantiatingComponentAdapter.java:193) at org.picocontainer.defaults.ConstructorInjectionComponentAdapter$1.run(ConstructorInjectionComponentAdapter.java:220) at org.picocontainer.defaults.ThreadLocalCyclicDependencyGuard.observe(ThreadLocalCyclicDependencyGuard.java:53) at org.picocontainer.defaults.ConstructorInjectionComponentAdapter.getComponentInstance(ConstructorInjectionComponentAdapter.java:248) at org.picocontainer.defaults.DecoratingComponentAdapter.getComponentInstance(DecoratingComponentAdapter.java:60) at com.intellij.openapi.components.impl.CachingComponentAdapter.getComponentInstance(CachingComponentAdapter.java:26) at com.intellij.openapi.components.impl.ServiceManagerImpl$MyComponentAdapter.a(ServiceManagerImpl.java:5) at com.intellij.openapi.components.impl.ServiceManagerImpl$MyComponentAdapter.access$100(ServiceManagerImpl.java:8) at com.intellij.openapi.components.impl.ServiceManagerImpl$MyComponentAdapter$1.compute(ServiceManagerImpl.java:6) at com.intellij.openapi.application.impl.ApplicationImpl$11.run(ApplicationImpl.java:2) at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:261) at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:283) at com.intellij.openapi.components.impl.ServiceManagerImpl$MyComponentAdapter.getComponentInstance(ServiceManagerImpl.java:28) at com.intellij.util.pico.DefaultPicoContainer.getLocalInstance(DefaultPicoContainer.java:230) at com.intellij.util.pico.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:217) at com.intellij.util.pico.DefaultPicoContainer.getComponentInstance(DefaultPicoContainer.java:199) at org.picocontainer.alternatives.AbstractDelegatingMutablePicoContainer.getComponentInstance(AbstractDelegatingMutablePicoContainer.java:75) at com.intellij.openapi.components.ServiceManager.getService(ServiceManager.java:33) at org.jetbrains.plugins.ruby.ruby.codeInsight.paramDefs.ParamDefManager.getInstance(ParamDefManager.java:7) at org.jetbrains.plugins.ruby.ruby.codeInsight.paramDefs.matcher.ParamDefMatcher.match(ParamDefMatcher.java:1) at org.jetbrains.plugins.ruby.ruby.codeInsight.paramDefs.matcher.ParamDefMatcher.createParamDefReference(ParamDefMatcher.java:2) at org.jetbrains.plugins.ruby.ruby.lang.psi.impl.basicTypes.stringLiterals.RStringLiteralBase.getReference(RStringLiteralBase.java:12) at com.intellij.psi.impl.SharedPsiElementImplUtil.getReferences(SharedPsiElementImplUtil.java:56) at com.intellij.extapi.psi.PsiElementBase.getReferences(PsiElementBase.java:151) at org.jetbrains.plugins.ruby.rails.inspections.paramdefs.ParamDefResolveVisitor.a(ParamDefResolveVisitor.java:8) at org.jetbrains.plugins.ruby.rails.inspections.paramdefs.ParamDefResolveVisitor.a(ParamDefResolveVisitor.java:28) at org.jetbrains.plugins.ruby.rails.inspections.paramdefs.ParamDefResolveVisitor.visitRDStringLiteral(ParamDefResolveVisitor.java:14) at org.jetbrains.plugins.ruby.ruby.lang.psi.impl.basicTypes.stringLiterals.baseString.RDStringLiteralImpl.accept(RDStringLiteralImpl.java:3) at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass$1$1.run(LocalInspectionsPass.java:192) at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:129) at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass$1.process(LocalInspectionsPass.java:178) at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass$1.process(LocalInspectionsPass.java:171) at com.intellij.concurrency.JobUtil$2$1.run(JobUtil.java:68) at com.intellij.openapi.progress.impl.ProgressManagerImpl$2.run(ProgressManagerImpl.java:11) at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:129) at com.intellij.openapi.progress.impl.ProgressManagerImpl.runProcess(ProgressManagerImpl.java:30) at com.intellij.concurrency.JobUtil$2.process(JobUtil.java:66) at com.intellij.concurrency.JobUtil$1.run(JobUtil.java:42) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at com.intellij.concurrency.JobImpl.scheduleAndWaitForResults(JobImpl.java:53) at com.intellij.concurrency.JobUtil.invokeConcurrentlyForAll(JobUtil.java:49) at com.intellij.concurrency.JobUtil.invokeConcurrentlyUnderMyProgress(JobUtil.java:63) at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.inspect(LocalInspectionsPass.java:171) at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.inspectRoot(LocalInspectionsPass.java:93) at com.intellij.codeInsight.daemon.impl.LocalInspectionsPass.collectInformationWithProgress(LocalInspectionsPass.java:84) at com.intellij.codeInsight.daemon.impl.ProgressableTextEditorHighlightingPass.doCollectInformation(ProgressableTextEditorHighlightingPass.java:36) at com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:45) at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass$1$1.run(PassExecutorService.java:278) at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:261) at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass$1.run(PassExecutorService.java:274) at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:129) at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:271) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619)
I've come up with a simple fix for the moment: http://gist.github.com/94810
I have not spent much time to explore whether this has a performance impact on real apps, but it should definitely fix the above issue. I'm trying to avoid adding any synchronization to the invalidation process, since it would have to be a global lock to avoid deadlock potential. This fix accomplishes that, but at the cost of having new classes construct a new WeakHashSet rather than modifying the existing one.