diff --git a/platform/boot/src/com/intellij/concurrency/IdeaForkJoinWorkerThreadFactory.java b/platform/boot/src/com/intellij/concurrency/IdeaForkJoinWorkerThreadFactory.java index 6be99990d714..8843e876a0f9 100644 --- a/platform/boot/src/com/intellij/concurrency/IdeaForkJoinWorkerThreadFactory.java +++ b/platform/boot/src/com/intellij/concurrency/IdeaForkJoinWorkerThreadFactory.java @@ -37,6 +37,13 @@ public class IdeaForkJoinWorkerThreadFactory implements ForkJoinPool.ForkJoinWor } } + public static void setupPoisonFactory() { + // if this method is called early enough and app called setupForkJoinCommonPool() too late + // (setupForkJoinCommonPool() has to be called after Main.setFlags() but before FJP init) + // then on the first use the FJP will explode, revealing who did the too early FJP init + System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory", PoisonFactory.class.getName()); + } + private static final AtomicLong bits = new AtomicLong(); @Override public ForkJoinWorkerThread newThread(ForkJoinPool pool) { diff --git a/platform/boot/src/com/intellij/concurrency/PoisonFactory.java b/platform/boot/src/com/intellij/concurrency/PoisonFactory.java new file mode 100644 index 000000000000..92f7bdace2f3 --- /dev/null +++ b/platform/boot/src/com/intellij/concurrency/PoisonFactory.java @@ -0,0 +1,19 @@ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.concurrency; + +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinWorkerThread; + +public class PoisonFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory{ + public PoisonFactory() { + RuntimeException exception = new RuntimeException("ForkJoinPool initialized too early, IdeaForkJoinWorkerThreadFactory ignored"); + exception.printStackTrace(); + exception.printStackTrace(System.out); + throw exception; + } + + @Override + public ForkJoinWorkerThread newThread(ForkJoinPool pool) { + throw new RuntimeException(); + } +} diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java index f174ac85799c..c2b75fd2329c 100644 --- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java +++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java @@ -1,6 +1,7 @@ // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.idea; +import com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory; import com.intellij.ide.cloudConfig.CloudConfigProvider; import com.intellij.ide.customize.CustomizeIDEWizardDialog; import com.intellij.ide.customize.CustomizeIDEWizardStepsProvider; @@ -74,6 +75,7 @@ public class StartupUtil { } static void prepareAndStart(String[] args, AppStarter appStarter) { + IdeaForkJoinWorkerThreadFactory.setupPoisonFactory(); boolean newConfigFolder = false; if (!Main.isHeadless()) { diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index c5abd7063201..fd8f6035cb4e 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -87,6 +87,7 @@ public abstract class UsefulTestCase extends TestCase { private static final Map TOTAL_TEARDOWN_COST_MILLIS = new HashMap<>(); static { + IdeaForkJoinWorkerThreadFactory.setupPoisonFactory(); Logger.setFactory(TestLoggerFactory.class); } protected static final Logger LOG = Logger.getInstance(UsefulTestCase.class); diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/BaseFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/BaseFixture.java index 1fd45ec4e831..c0381fc09335 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/BaseFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/BaseFixture.java @@ -15,6 +15,7 @@ */ package com.intellij.testFramework.fixtures.impl; +import com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory; import com.intellij.openapi.Disposable; import com.intellij.openapi.util.Disposer; import com.intellij.testFramework.EdtTestUtil; @@ -31,6 +32,10 @@ public class BaseFixture implements IdeaTestFixture { private boolean myDisposed; private final Disposable myTestRootDisposable = Disposer.newDisposable(); + static { + IdeaForkJoinWorkerThreadFactory.setupPoisonFactory(); + } + @Override public void setUp() throws Exception { Assert.assertFalse("setUp() already has been called", myInitialized);