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
- - - - -
This commit is contained in:
Yan Zhulanow
2023-03-04 02:08:18 +09:00
committed by Space Team
parent f40278c036
commit c604577132
2 changed files with 31 additions and 10 deletions
@@ -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
@@ -39,12 +39,38 @@ public class DefaultErrorMessages {
}
private static final DiagnosticFactoryToRendererMap MAP = new DiagnosticFactoryToRendererMap("Default");
private static final List<DiagnosticFactoryToRendererMap> RENDERER_MAPS =
CollectionsKt.plus(
Collections.singletonList(MAP),
CollectionsKt.map(ServiceLoader.load(Extension.class, DefaultErrorMessages.class.getClassLoader()), Extension::getMap)
private static final List<String> 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<DiagnosticFactoryToRendererMap> RENDERER_MAPS;
static {
List<DiagnosticFactoryToRendererMap> 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")
public static String render(@NotNull UnboundDiagnostic diagnostic) {