Fix class loading deadlock in Error diagnostic classes
Because of non-trivial initialization logic, Errors/ErrorsJvm/etc. are prone to class loading issues. This commit prevents them by preloading all error on plugin initialization step.
This commit is contained in:
@@ -32,8 +32,13 @@ import com.intellij.openapi.util.Disposer;
|
|||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.search.searches.IndexPatternSearch;
|
import com.intellij.psi.search.searches.IndexPatternSearch;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory;
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
import org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter;
|
import org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter;
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinTodoSearcher;
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinTodoSearcher;
|
||||||
|
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm;
|
||||||
|
import org.jetbrains.kotlin.resolve.konan.diagnostics.ErrorsNative;
|
||||||
import org.jetbrains.kotlin.utils.PathUtil;
|
import org.jetbrains.kotlin.utils.PathUtil;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.idea.TestResourceBundleKt.registerAdditionalResourceBundleInTests;
|
import static org.jetbrains.kotlin.idea.TestResourceBundleKt.registerAdditionalResourceBundleInTests;
|
||||||
@@ -50,6 +55,7 @@ public class PluginStartupActivity implements StartupActivity.DumbAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerPathVariable();
|
registerPathVariable();
|
||||||
|
initializeDiagnostics();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// API added in 15.0.2
|
// API added in 15.0.2
|
||||||
@@ -88,6 +94,23 @@ public class PluginStartupActivity implements StartupActivity.DumbAware {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Concurrent access to Errors may lead to the class loading dead lock because of non-trivial initialization in Errors.
|
||||||
|
As a work-around, all Error classes are initialized beforehand.
|
||||||
|
It doesn't matter what exact diagnostic factories are used here.
|
||||||
|
*/
|
||||||
|
private static void initializeDiagnostics() {
|
||||||
|
consumeFactory(Errors.DEPRECATION);
|
||||||
|
consumeFactory(ErrorsJvm.ACCIDENTAL_OVERRIDE);
|
||||||
|
consumeFactory(ErrorsJs.CALL_FROM_UMD_MUST_BE_JS_MODULE_AND_JS_NON_MODULE);
|
||||||
|
consumeFactory(ErrorsNative.INCOMPATIBLE_THROWS_INHERITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void consumeFactory(DiagnosticFactory<?> factory) {
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
factory.getClass();
|
||||||
|
}
|
||||||
|
|
||||||
private static void registerPathVariable() {
|
private static void registerPathVariable() {
|
||||||
PathMacros macros = PathMacros.getInstance();
|
PathMacros macros = PathMacros.getInstance();
|
||||||
macros.setMacro(KOTLIN_BUNDLED, PathUtil.getKotlinPathsForIdeaPlugin().getHomePath().getPath());
|
macros.setMacro(KOTLIN_BUNDLED, PathUtil.getKotlinPathsForIdeaPlugin().getHomePath().getPath());
|
||||||
|
|||||||
@@ -29,8 +29,13 @@ import com.intellij.openapi.updateSettings.impl.UpdateChecker;
|
|||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.search.searches.IndexPatternSearch;
|
import com.intellij.psi.search.searches.IndexPatternSearch;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory;
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
import org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter;
|
import org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter;
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinTodoSearcher;
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinTodoSearcher;
|
||||||
|
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm;
|
||||||
|
import org.jetbrains.kotlin.resolve.konan.diagnostics.ErrorsNative;
|
||||||
import org.jetbrains.kotlin.utils.PathUtil;
|
import org.jetbrains.kotlin.utils.PathUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -60,6 +65,7 @@ public class PluginStartupComponent implements BaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerPathVariable();
|
registerPathVariable();
|
||||||
|
initializeDiagnostics();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// API added in 15.0.2
|
// API added in 15.0.2
|
||||||
@@ -89,6 +95,23 @@ public class PluginStartupComponent implements BaseComponent {
|
|||||||
//KotlinSdkType.Companion.setUpIfNeeded();
|
//KotlinSdkType.Companion.setUpIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Concurrent access to Errors may lead to the class loading dead lock because of non-trivial initialization in Errors.
|
||||||
|
As a work-around, all Error classes are initialized beforehand.
|
||||||
|
It doesn't matter what exact diagnostic factories are used here.
|
||||||
|
*/
|
||||||
|
private static void initializeDiagnostics() {
|
||||||
|
consumeFactory(Errors.DEPRECATION);
|
||||||
|
consumeFactory(ErrorsJvm.ACCIDENTAL_OVERRIDE);
|
||||||
|
consumeFactory(ErrorsJs.CALL_FROM_UMD_MUST_BE_JS_MODULE_AND_JS_NON_MODULE);
|
||||||
|
consumeFactory(ErrorsNative.INCOMPATIBLE_THROWS_INHERITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void consumeFactory(DiagnosticFactory<?> factory) {
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
factory.getClass();
|
||||||
|
}
|
||||||
|
|
||||||
private static void registerPathVariable() {
|
private static void registerPathVariable() {
|
||||||
PathMacros macros = PathMacros.getInstance();
|
PathMacros macros = PathMacros.getInstance();
|
||||||
macros.setMacro(KOTLIN_BUNDLED, PathUtil.getKotlinPathsForIdeaPlugin().getHomePath().getPath());
|
macros.setMacro(KOTLIN_BUNDLED, PathUtil.getKotlinPathsForIdeaPlugin().getHomePath().getPath());
|
||||||
|
|||||||
@@ -29,8 +29,13 @@ import com.intellij.openapi.updateSettings.impl.UpdateChecker;
|
|||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.search.searches.IndexPatternSearch;
|
import com.intellij.psi.search.searches.IndexPatternSearch;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory;
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
import org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter;
|
import org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter;
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinTodoSearcher;
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinTodoSearcher;
|
||||||
|
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm;
|
||||||
|
import org.jetbrains.kotlin.resolve.konan.diagnostics.ErrorsNative;
|
||||||
import org.jetbrains.kotlin.utils.PathUtil;
|
import org.jetbrains.kotlin.utils.PathUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -60,6 +65,7 @@ public class PluginStartupComponent implements BaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerPathVariable();
|
registerPathVariable();
|
||||||
|
initializeDiagnostics();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// API added in 15.0.2
|
// API added in 15.0.2
|
||||||
@@ -89,6 +95,23 @@ public class PluginStartupComponent implements BaseComponent {
|
|||||||
//KotlinSdkType.Companion.setUpIfNeeded();
|
//KotlinSdkType.Companion.setUpIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Concurrent access to Errors may lead to the class loading dead lock because of non-trivial initialization in Errors.
|
||||||
|
As a work-around, all Error classes are initialized beforehand.
|
||||||
|
It doesn't matter what exact diagnostic factories are used here.
|
||||||
|
*/
|
||||||
|
private static void initializeDiagnostics() {
|
||||||
|
consumeFactory(Errors.DEPRECATION);
|
||||||
|
consumeFactory(ErrorsJvm.ACCIDENTAL_OVERRIDE);
|
||||||
|
consumeFactory(ErrorsJs.CALL_FROM_UMD_MUST_BE_JS_MODULE_AND_JS_NON_MODULE);
|
||||||
|
consumeFactory(ErrorsNative.INCOMPATIBLE_THROWS_INHERITED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void consumeFactory(DiagnosticFactory<?> factory) {
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
factory.getClass();
|
||||||
|
}
|
||||||
|
|
||||||
private static void registerPathVariable() {
|
private static void registerPathVariable() {
|
||||||
PathMacros macros = PathMacros.getInstance();
|
PathMacros macros = PathMacros.getInstance();
|
||||||
macros.setMacro(KOTLIN_BUNDLED, PathUtil.getKotlinPathsForIdeaPlugin().getHomePath().getPath());
|
macros.setMacro(KOTLIN_BUNDLED, PathUtil.getKotlinPathsForIdeaPlugin().getHomePath().getPath());
|
||||||
|
|||||||
Reference in New Issue
Block a user