From f1ea5991479fbd22390ca858935e919f96db268e Mon Sep 17 00:00:00 2001 From: Alexander Bubenchikov Date: Tue, 30 Jul 2024 14:03:14 +0200 Subject: [PATCH] [maven] maven 4 repositories fix GitOrigin-RevId: c800f1435d40021a440e275fe7d9dc58d2003c90 --- .../server/m40/Maven40ServerEmbedderImpl.java | 126 ++++++++---------- .../utils/Maven40AetherModelConverter.java | 56 +++++--- .../m40/utils/Maven40ModelConverter.java | 4 +- .../m40/utils/Maven40ProjectResolver.java | 6 +- .../importing/RepositoriesImportingTest.kt | 16 +++ 5 files changed, 111 insertions(+), 97 deletions(-) diff --git a/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/Maven40ServerEmbedderImpl.java b/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/Maven40ServerEmbedderImpl.java index 8664f7360904..19fc5c0fe8e8 100644 --- a/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/Maven40ServerEmbedderImpl.java +++ b/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/Maven40ServerEmbedderImpl.java @@ -53,9 +53,9 @@ import org.codehaus.plexus.util.StringUtils; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.graph.DependencyNode; -import org.eclipse.aether.impl.RemoteRepositoryManager; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResolutionException; import org.eclipse.aether.resolution.ArtifactResult; import org.eclipse.aether.transfer.ArtifactTransferException; import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator; @@ -695,45 +695,51 @@ public class Maven40ServerEmbedderImpl extends MavenServerEmbeddedBase { MavenServerUtil.checkToken(token); String longRunningTaskId = longRunningTaskInput.getLongRunningTaskId(); MavenServerOpenTelemetry telemetry = MavenServerOpenTelemetry.of(longRunningTaskInput); - boolean runInParallel = canResolveDependenciesInParallel(); + + try (LongRunningTask task = newLongRunningTask(longRunningTaskId, pluginResolutionRequests.size(), myConsoleWrapper)) { MavenExecutionRequest request = createRequest(null, null, null); request.setTransferListener(new Maven40TransferListenerAdapter(task.getIndicator())); request.setUpdateSnapshots(myAlwaysUpdateSnapshots || forceUpdateSnapshots); - DefaultMaven maven = (DefaultMaven)getComponent(Maven.class); - RepositorySystemSession session = maven.newRepositorySession(request); - myImporterSpy.setIndicator(task.getIndicator()); + List resolutions = collectPluginResolutionData(pluginResolutionRequests); + List results = new ArrayList<>(); + executeWithMavenSession(request, MavenWorkspaceMap.empty(), task.getIndicator(), session -> { + results.addAll(ParallelRunnerForServer.execute(false, resolutions, resolution -> + resolvePlugin(task, resolution.mavenPluginId, resolution.pluginDependencies, resolution.remoteRepos, + session.getRepositorySession()))); + }); - List resolutions = new ArrayList<>(); - - for (PluginResolutionRequest pluginResolutionRequest : pluginResolutionRequests) { - MavenId mavenPluginId = pluginResolutionRequest.getMavenPluginId(); - int nativeMavenProjectId = pluginResolutionRequest.getNativeMavenProjectId(); - - String groupId = mavenPluginId.getGroupId(); - String artifactId = mavenPluginId.getArtifactId(); - - MavenProject project = RemoteNativeMaven40ProjectHolder.findProjectById(nativeMavenProjectId); - List remoteRepos = project.getRemotePluginRepositories(); - - Plugin pluginFromProject = project.getBuild().getPluginsAsMap().get(groupId + ':' + artifactId); - List pluginDependencies = - null == pluginFromProject ? Collections.emptyList() : pluginFromProject.getDependencies(); - - PluginResolutionData resolution = new PluginResolutionData(mavenPluginId, pluginDependencies, remoteRepos); - resolutions.add(resolution); - } + byte[] telemetryTrace = telemetry.shutdown(); // IDEA-341451: Parallel plugin resolution hangs in Maven 4.0.0-alpha-9 // It worked fine up until Maven 4.0.0-alpha-8 - List results = ParallelRunnerForServer.execute(false, resolutions, resolution -> - resolvePlugin(task, resolution.mavenPluginId, resolution.pluginDependencies, resolution.remoteRepos, session) - ); - byte[] telemetryTrace = telemetry.shutdown(); return new MavenServerResponse<>(new ArrayList<>(results), getLongRunningTaskStatus(longRunningTaskId, token), telemetryTrace); } } + private static @NotNull List collectPluginResolutionData(@NotNull ArrayList pluginResolutionRequests) { + List resolutions = new ArrayList<>(); + + for (PluginResolutionRequest pluginResolutionRequest : pluginResolutionRequests) { + MavenId mavenPluginId = pluginResolutionRequest.getMavenPluginId(); + int nativeMavenProjectId = pluginResolutionRequest.getNativeMavenProjectId(); + + String groupId = mavenPluginId.getGroupId(); + String artifactId = mavenPluginId.getArtifactId(); + + MavenProject project = RemoteNativeMaven40ProjectHolder.findProjectById(nativeMavenProjectId); + List remoteRepos = project.getRemotePluginRepositories(); + + Plugin pluginFromProject = project.getBuild().getPluginsAsMap().get(groupId + ':' + artifactId); + List pluginDependencies = + null == pluginFromProject ? Collections.emptyList() : pluginFromProject.getDependencies(); + + PluginResolutionData resolution = new PluginResolutionData(mavenPluginId, pluginDependencies, remoteRepos); + resolutions.add(resolution); + } + return resolutions; + } + private static class PluginResolutionData { MavenId mavenPluginId; List pluginDependencies; @@ -980,13 +986,33 @@ public class Maven40ServerEmbedderImpl extends MavenServerEmbeddedBase { private ArrayList doResolveArtifacts(@NotNull LongRunningTask task, @NotNull Collection requests) { try { + MavenExecutionRequest executionRequest = + createRequest(null, null, null); ArrayList artifacts = new ArrayList<>(); + Set repos = new LinkedHashSet<>(); for (MavenArtifactResolutionRequest request : requests) { - if (task.isCanceled()) break; - MavenArtifact artifact = doResolveArtifact(request.getArtifactInfo(), request.getRemoteRepositories()); - artifacts.add(artifact); - task.incrementFinishedRequests(); + repos.addAll(request.getRemoteRepositories()); } + List repositories = convertRepositories(new ArrayList<>(repos)); + repositories.forEach(executionRequest::addRemoteRepository); + + executeWithMavenSession(executionRequest, MavenWorkspaceMap.empty(), task.getIndicator(), mavenSession -> { + try { + RepositorySystem repositorySystem = getComponent(RepositorySystem.class); + for (MavenArtifactResolutionRequest request : requests) { + ArtifactResult artifactResult = repositorySystem.resolveArtifact( + mavenSession.getRepositorySession(), + new ArtifactRequest(RepositoryUtils.toArtifact(createArtifact(request.getArtifactInfo())), + RepositoryUtils.toRepos(repositories), null)); + artifacts.add( + Maven40ModelConverter.convertArtifact(RepositoryUtils.toArtifact(artifactResult.getArtifact()), getLocalRepositoryFile())); + task.incrementFinishedRequests(); + } + } + catch (ArtifactResolutionException e) { + throw new RuntimeException(e); + } + }); return artifacts; } catch (Exception e) { @@ -994,42 +1020,6 @@ public class Maven40ServerEmbedderImpl extends MavenServerEmbeddedBase { } } - private MavenArtifact doResolveArtifact(MavenArtifactInfo info, List remoteRepositories) { - Artifact resolved = doResolveArtifact(createArtifact(info), convertRepositories(remoteRepositories)); - return Maven40ModelConverter.convertArtifact(resolved, getLocalRepositoryFile()); - } - - private Artifact doResolveArtifact(Artifact artifact, List remoteRepositories) { - try { - MavenExecutionRequest request = - createRequest(null, null, null); - for (ArtifactRepository artifactRepository : remoteRepositories) { - request.addRemoteRepository(artifactRepository); - } - - DefaultMaven maven = (DefaultMaven)getComponent(Maven.class); - RepositorySystemSession repositorySystemSession = maven.newRepositorySession(request); - - initLogging(myConsoleWrapper); - - // do not use request.getRemoteRepositories() here, - // it can be broken after DefaultMaven#newRepositorySession => MavenRepositorySystem.injectMirror invocation - RemoteRepositoryManager remoteRepositoryManager = getComponent(RemoteRepositoryManager.class); - org.eclipse.aether.RepositorySystem repositorySystem = getComponent(org.eclipse.aether.RepositorySystem.class); - List repositories = RepositoryUtils.toRepos(remoteRepositories); - repositories = - remoteRepositoryManager.aggregateRepositories(repositorySystemSession, new ArrayList<>(), repositories, false); - - ArtifactResult artifactResult = repositorySystem.resolveArtifact( - repositorySystemSession, new ArtifactRequest(RepositoryUtils.toArtifact(artifact), repositories, null)); - - return RepositoryUtils.toArtifact(artifactResult.getArtifact()); - } - catch (Exception e) { - MavenServerGlobals.getLogger().info(e); - } - return artifact; - } private static void initLogging(Maven40ServerConsoleLogger consoleWrapper) { Maven40Sl4jLoggerWrapper.setCurrentWrapper(consoleWrapper); diff --git a/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40AetherModelConverter.java b/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40AetherModelConverter.java index c4f4af076fec..04bc246db4fa 100644 --- a/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40AetherModelConverter.java +++ b/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40AetherModelConverter.java @@ -3,10 +3,12 @@ package com.intellij.maven.server.m40.utils; import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; -import org.apache.maven.model.Model; import org.apache.maven.model.Parent; +import org.apache.maven.project.MavenProject; import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.repository.RepositoryPolicy; import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; import org.eclipse.aether.util.graph.transformer.ConflictResolver; import org.jetbrains.annotations.NotNull; @@ -15,46 +17,56 @@ import org.jetbrains.idea.maven.model.*; import java.io.File; import java.util.*; +import java.util.stream.Collectors; /** * {@link Maven40AetherModelConverter} provides adapted methods of {@link Maven40ModelConverter} for aether models conversion */ public final class Maven40AetherModelConverter extends Maven40ModelConverter { @NotNull - public static MavenModel convertModelWithAetherDependencyTree(Model model, - List sources, - List testSources, - Collection dependencies, + public static MavenModel convertModelWithAetherDependencyTree(MavenProject mavenProject, Collection dependencyTree, - Collection extensions, File localRepository) { MavenModel result = new MavenModel(); - result.setMavenId(new MavenId(model.getGroupId(), model.getArtifactId(), model.getVersion())); + result.setMavenId(new MavenId(mavenProject.getGroupId(), mavenProject.getArtifactId(), mavenProject.getVersion())); - Parent parent = model.getParent(); + Parent parent = mavenProject.getModel().getParent(); if (parent != null) { - result.setParent(new MavenParent(new MavenId(parent.getGroupId(), parent.getArtifactId(), parent.getVersion()), - parent.getRelativePath())); + result.setParent( + new MavenParent(new MavenId(parent.getGroupId(), parent.getArtifactId(), parent.getVersion()), parent.getRelativePath())); } - result.setPackaging(model.getPackaging()); - result.setName(model.getName()); - result.setProperties(model.getProperties() == null ? new Properties() : model.getProperties()); - result.setPlugins(convertPlugins(model)); + result.setPackaging(mavenProject.getPackaging()); + result.setName(mavenProject.getName()); + result.setProperties(mavenProject.getProperties() == null ? new Properties() : mavenProject.getProperties()); + //noinspection SSBasedInspection + result.setPlugins(convertPlugins(mavenProject.getModel())); Map convertedArtifacts = new HashMap<>(); - result.setExtensions(convertArtifacts(extensions, convertedArtifacts, localRepository)); - result.setDependencyTree( - convertAetherDependencyNodes(null, dependencyTree, convertedArtifacts, localRepository)); - result.setDependencies(convertArtifacts(dependencies, convertedArtifacts, localRepository)); + result.setExtensions(convertArtifacts(mavenProject.getExtensionArtifacts(), convertedArtifacts, localRepository)); + result.setDependencyTree(convertAetherDependencyNodes(null, dependencyTree, convertedArtifacts, localRepository)); + result.setDependencies(convertArtifacts(mavenProject.getArtifacts(), convertedArtifacts, localRepository)); - result.setRemoteRepositories(convertRepositories(model.getRepositories())); - result.setProfiles(convertProfiles(model.getProfiles())); - result.setModules(model.getModules()); + result.setRemoteRepositories(convertAetherRepositories(mavenProject.getRemoteProjectRepositories())); + result.setProfiles(convertProfiles(mavenProject.getModel().getProfiles())); + result.setModules(mavenProject.getModules()); - convertBuild(result.getBuild(), model.getBuild(), sources, testSources); + convertBuild(result.getBuild(), mavenProject.getModel().getBuild(), mavenProject.getCompileSourceRoots(), + mavenProject.getTestCompileSourceRoots()); return result; } + @SuppressWarnings("SSBasedInspection") + private static List convertAetherRepositories(List repositories) { + return repositories.stream().map( + r -> new MavenRemoteRepository(r.getId(), r.getId(), r.getUrl(), "default", convertPolicy(r.getPolicy(false)), + convertPolicy(r.getPolicy(true)))).collect(Collectors.toList()); + } + + private static MavenRemoteRepository.@Nullable Policy convertPolicy(RepositoryPolicy policy) { + return policy != null ? new MavenRemoteRepository.Policy(policy.isEnabled(), policy.getArtifactUpdatePolicy(), + policy.getChecksumPolicy()) : null; + } + public static List convertAetherDependencyNodes(MavenArtifactNode parent, Collection nodes, Map nativeToConvertedMap, diff --git a/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40ModelConverter.java b/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40ModelConverter.java index 9401eee432d9..daaf646e123c 100644 --- a/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40ModelConverter.java +++ b/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40ModelConverter.java @@ -73,7 +73,7 @@ public class Maven40ModelConverter { return result; } - private static MavenPlugin convertPlugin(Plugin plugin) { + public static MavenPlugin convertPlugin(Plugin plugin) { List executions = new ArrayList<>(plugin.getExecutions().size()); for (PluginExecution each : plugin.getExecutions()) { executions.add(convertExecution(each)); @@ -202,7 +202,7 @@ public class Maven40ModelConverter { } - private static MavenRemoteRepository.Policy convertPolicy(RepositoryPolicy policy) { + public static MavenRemoteRepository.Policy convertPolicy(RepositoryPolicy policy) { return policy != null ? new MavenRemoteRepository.Policy(policy.isEnabled(), policy.getUpdatePolicy(), policy.getChecksumPolicy()) : null; diff --git a/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40ProjectResolver.java b/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40ProjectResolver.java index ff9a80525002..02dbc2dafdb2 100644 --- a/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40ProjectResolver.java +++ b/plugins/maven/maven40-server-impl/src/com/intellij/maven/server/m40/utils/Maven40ProjectResolver.java @@ -284,12 +284,8 @@ public class Maven40ProjectResolver { List dependencyNodes = dependencyGraph != null ? dependencyGraph.getChildren() : Collections.emptyList(); model = Maven40AetherModelConverter.convertModelWithAetherDependencyTree( - mavenProject.getModel(), - mavenProject.getCompileSourceRoots(), - mavenProject.getTestCompileSourceRoots(), - mavenProject.getArtifacts(), + mavenProject, dependencyNodes, - Collections.emptyList(), //mavenProject.getExtensionArtifacts(), myLocalRepositoryFile); } catch (Exception e) { diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/RepositoriesImportingTest.kt b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/RepositoriesImportingTest.kt index c14ec4980634..afe535b61ee3 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/RepositoriesImportingTest.kt +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/RepositoriesImportingTest.kt @@ -3,11 +3,27 @@ package org.jetbrains.idea.maven.importing import com.intellij.jarRepository.RemoteRepositoriesConfiguration import com.intellij.maven.testFramework.MavenMultiVersionImportingTestCase +import com.intellij.openapi.util.registry.Registry +import com.intellij.testFramework.UsefulTestCase import kotlinx.coroutines.runBlocking import org.junit.Test class RepositoriesImportingTest : MavenMultiVersionImportingTestCase() { + + @Test + fun importSimpleProject() = runBlocking { + importProjectAsync(""" + test + project + pom + 1 + """.trimIndent()) + val mavenProject = projectsManager.findProject(projectPom) + assertNotNull(mavenProject) + UsefulTestCase.assertSameElements(mavenProject!!.remoteRepositories.map { it.url }, "https://repo.maven.apache.org/maven2") + } + @Test fun testMirrorCentralImport() = runBlocking { val oldSettingsFile = mavenGeneralSettings.userSettingsFile