From 85764debe974acfee90cbd08fa694e7e893bb546 Mon Sep 17 00:00:00 2001 From: Nikolay Chashnikov Date: Wed, 29 Jan 2025 16:39:46 +0100 Subject: [PATCH] [module-based loader] specify the proper classpath for content modules in module-based loader (IJPL-165692) When a content module is loaded via module-based loader, it may happen that its JAR cannot be found by the standard relative path (pluginDir/lib/modules/module.name.jar), because, for example, the main plugin JAR is located in a pluginDir/lib/frontend-split subdirectory. It's more reliable to use data from the runtime module repository in such cases. GitOrigin-RevId: 335849d125241d367758485a033d145f951c240e --- .../bootstrap/ModuleBasedPluginXmlPathResolver.kt | 6 ++++++ .../intellij/ide/plugins/PathBasedJdomXIncluder.kt | 9 +++++++++ .../intellij/ide/plugins/PluginDescriptorLoader.kt | 14 ++++++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/platform/bootstrap/src/com/intellij/platform/bootstrap/ModuleBasedPluginXmlPathResolver.kt b/platform/bootstrap/src/com/intellij/platform/bootstrap/ModuleBasedPluginXmlPathResolver.kt index fe95a39ce1c0..a07370825807 100644 --- a/platform/bootstrap/src/com/intellij/platform/bootstrap/ModuleBasedPluginXmlPathResolver.kt +++ b/platform/bootstrap/src/com/intellij/platform/bootstrap/ModuleBasedPluginXmlPathResolver.kt @@ -4,6 +4,7 @@ package com.intellij.platform.bootstrap import com.intellij.ide.plugins.* import com.intellij.platform.runtime.product.IncludedRuntimeModule import com.intellij.platform.runtime.repository.RuntimeModuleId +import java.nio.file.Path /** * Implementation of [PathResolver] which can load module descriptors not only from the main plugin JAR file, unlike [PluginXmlPathResolver] @@ -44,6 +45,11 @@ internal class ModuleBasedPluginXmlPathResolver( return fallbackResolver.resolveModuleFile(readContext = readContext, dataLoader = dataLoader, path = path, readInto = readInto) } + override fun resolveCustomModuleClassesRoots(moduleName: String): List { + val moduleDescriptor = includedModules.find { it.moduleDescriptor.moduleId.stringId == moduleName }?.moduleDescriptor + return moduleDescriptor?.resourceRootPaths ?: emptyList() + } + override fun loadXIncludeReference( readInto: RawPluginDescriptor, readContext: ReadModuleContext, diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PathBasedJdomXIncluder.kt b/platform/core-impl/src/com/intellij/ide/plugins/PathBasedJdomXIncluder.kt index 9a513892b90f..bf518b71040e 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/PathBasedJdomXIncluder.kt +++ b/platform/core-impl/src/com/intellij/ide/plugins/PathBasedJdomXIncluder.kt @@ -4,6 +4,7 @@ package com.intellij.ide.plugins import org.jetbrains.annotations.ApiStatus +import java.nio.file.Path @ApiStatus.Internal interface PathResolver { @@ -16,4 +17,12 @@ interface PathResolver { // module in a new file name format must always be resolved fun resolveModuleFile(readContext: ReadModuleContext, dataLoader: DataLoader, path: String, readInto: RawPluginDescriptor?): RawPluginDescriptor + + /** + * Returns custom classes roots for a content module [moduleName] if any. + * If the module is located in the standard place (lib/modules/module.name.jar) or merged with one of JARs loaded by the main classloader, an empty list is returned. + */ + fun resolveCustomModuleClassesRoots(moduleName: String): List { + return emptyList() + } } \ No newline at end of file diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorLoader.kt b/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorLoader.kt index bd42cca642c6..71a0d45b6b26 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorLoader.kt +++ b/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorLoader.kt @@ -230,7 +230,12 @@ fun initMainDescriptorByRaw( } else { val subRaw = pathResolver.resolveModuleFile(context, dataLoader, subDescriptorFile, readInto = null) - module.descriptor = descriptor.createSub(subRaw, subDescriptorFile, context, module) + val subDescriptor = descriptor.createSub(subRaw, subDescriptorFile, context, module) + module.descriptor = subDescriptor + val customRoots = pathResolver.resolveCustomModuleClassesRoots(module.name) + if (customRoots.isNotEmpty()) { + subDescriptor.jarFiles = customRoots + } } } else { @@ -993,7 +998,12 @@ private fun loadModuleDescriptors( } val raw = pathResolver.resolveModuleFile(readContext = context, dataLoader = dataLoader, path = subDescriptorFile, readInto = null) - module.descriptor = descriptor.createSub(raw = raw, descriptorPath = subDescriptorFile, context = context, module = module) + val subDescriptor = descriptor.createSub(raw = raw, descriptorPath = subDescriptorFile, context = context, module = module) + val customModuleClassesRoots = pathResolver.resolveCustomModuleClassesRoots(moduleName) + if (customModuleClassesRoots.isNotEmpty()) { + subDescriptor.jarFiles = customModuleClassesRoots + } + module.descriptor = subDescriptor } }