From c604577132d30223605b575780b71c923e35ab0c Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Sat, 4 Mar 2023 02:08:18 +0900 Subject: [PATCH] Embed DefaultErrorMessages extension list (KT-57102) Normally, 'DefaultErrorMessages' extensions should only be loaded from the main compiler JAR. However, in the in-process JPS build, there are two versions of the compiler classes in the process, and 'ClassLoader's there are not fully isolated. 'ServiceManager' loads extensions from both 'META-INF' locations. If the JPS plugin bundles newer compiler components, newly appeared 'DefaultErrorMessages' extensions will be loaded from the JPS (parent) 'ClassLoader', causing an exception. Such a problem appeared with 'DefaultErrorMessagesWasm': - - - - - java.util.ServiceConfigurationError: org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages$Extension: org.jetbrains.kotlin.wasm.resolve.diagnostics.DefaultErrorMessagesWasm not a subtype - - - - - --- ...s.rendering.DefaultErrorMessages$Extension | 5 --- .../rendering/DefaultErrorMessages.java | 36 ++++++++++++++++--- 2 files changed, 31 insertions(+), 10 deletions(-) delete mode 100644 compiler/cli/resources/META-INF/services/org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages$Extension diff --git a/compiler/cli/resources/META-INF/services/org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages$Extension b/compiler/cli/resources/META-INF/services/org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages$Extension deleted file mode 100644 index d9c11f9b3e4..00000000000 --- a/compiler/cli/resources/META-INF/services/org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages$Extension +++ /dev/null @@ -1,5 +0,0 @@ -# Note that this file is also present in idea/src/META-INF/services -org.jetbrains.kotlin.resolve.jvm.diagnostics.DefaultErrorMessagesJvm -org.jetbrains.kotlin.js.resolve.diagnostics.DefaultErrorMessagesJs -org.jetbrains.kotlin.resolve.konan.diagnostics.DefaultErrorMessagesNative -org.jetbrains.kotlin.wasm.resolve.diagnostics.DefaultErrorMessagesWasm diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index bc8cbacf765..d7d8c76c8b7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -39,11 +39,37 @@ public class DefaultErrorMessages { } private static final DiagnosticFactoryToRendererMap MAP = new DiagnosticFactoryToRendererMap("Default"); - private static final List RENDERER_MAPS = - CollectionsKt.plus( - Collections.singletonList(MAP), - CollectionsKt.map(ServiceLoader.load(Extension.class, DefaultErrorMessages.class.getClassLoader()), Extension::getMap) - ); + + private static final List RENDERER_PLATFORM_EXTENSIONS = CollectionsKt.listOf( + "org.jetbrains.kotlin.resolve.jvm.diagnostics.DefaultErrorMessagesJvm", + "org.jetbrains.kotlin.js.resolve.diagnostics.DefaultErrorMessagesJs", + "org.jetbrains.kotlin.resolve.konan.diagnostics.DefaultErrorMessagesNative", + "org.jetbrains.kotlin.wasm.resolve.diagnostics.DefaultErrorMessagesWasm" + ); + + private static final List RENDERER_MAPS; + + static { + List rendererMaps = new ArrayList<>(RENDERER_PLATFORM_EXTENSIONS.size() + 1); + rendererMaps.add(MAP); + + for (String extensionFqName : RENDERER_PLATFORM_EXTENSIONS) { + try { + Class extensionClass = Class.forName(extensionFqName); + if (!Extension.class.isAssignableFrom(extensionClass)) { + throw new IllegalStateException(extensionClass.getName() + " is not a " + Extension.class.getName()); + } + + Extension extension = (Extension) extensionClass.newInstance(); + rendererMaps.add(extension.getMap()); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + RENDERER_MAPS = Collections.unmodifiableList(rendererMaps); + } @NotNull @SuppressWarnings("unchecked")