From 0b44b70d519d11aefa2d9ada10db72e57bda1ad7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Nov 2025 04:04:37 +0000 Subject: [PATCH 1/4] Initial plan From b61583338c0b364079dd6497b7b4bbb3502c0ebf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Nov 2025 04:18:06 +0000 Subject: [PATCH 2/4] Migrate MavenDependenciesResolverConfigurer to use Aether Resolver API Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com> --- .../MavenDependenciesResolverConfigurer.java | 175 ++++++++++++------ .../maven/MavenDependenciesResolverTest.java | 41 +++- 2 files changed, 156 insertions(+), 60 deletions(-) diff --git a/tycho-core/src/main/java/org/eclipse/tycho/osgi/configuration/MavenDependenciesResolverConfigurer.java b/tycho-core/src/main/java/org/eclipse/tycho/osgi/configuration/MavenDependenciesResolverConfigurer.java index e3a2ba81e6..15be445dd1 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/osgi/configuration/MavenDependenciesResolverConfigurer.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/osgi/configuration/MavenDependenciesResolverConfigurer.java @@ -20,30 +20,38 @@ import java.util.Collection; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; import java.util.stream.Stream; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.InvalidRepositoryException; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; -import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Model; import org.apache.maven.model.Parent; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.plugin.LegacySupport; import org.apache.maven.project.MavenProject; -import org.apache.maven.repository.RepositorySystem; -import org.apache.maven.settings.Settings; +import org.apache.maven.project.RepositorySessionDecorator; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.collection.CollectResult; +import org.eclipse.aether.collection.DependencyCollectionException; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.DependencyRequest; +import org.eclipse.aether.resolution.DependencyResolutionException; +import org.eclipse.aether.resolution.DependencyResult; import org.eclipse.tycho.MavenArtifactRepositoryReference; -import org.eclipse.tycho.core.DependencyResolutionException; import org.eclipse.tycho.core.MavenDependenciesResolver; import org.eclipse.tycho.core.MavenModelFacade; import org.eclipse.tycho.core.maven.MavenArtifactFacade; @@ -61,69 +69,130 @@ public class MavenDependenciesResolverConfigurer implements MavenDependenciesRes @Inject private RepositorySystem repositorySystem; + @Inject + private List decorators; + @Override public Collection resolve(String groupId, String artifactId, String version, String packaging, String classifier, Collection scopes, int depth, Collection additionalRepositories, - Object session) throws DependencyResolutionException { - Artifact artifact; + Object session) throws org.eclipse.tycho.core.DependencyResolutionException { + + String extension = packaging != null ? packaging : "jar"; + org.eclipse.aether.artifact.Artifact aetherArtifact; if (classifier != null && !classifier.isEmpty()) { - artifact = repositorySystem.createArtifactWithClassifier(groupId, artifactId, version, packaging, - classifier); + aetherArtifact = new DefaultArtifact(groupId, artifactId, classifier, extension, version); } else { - artifact = repositorySystem.createArtifact(groupId, artifactId, version, null, packaging); + aetherArtifact = new DefaultArtifact(groupId, artifactId, "", extension, version); } - logger.debug("Resolving " + artifact); - ArtifactResolutionRequest request = new ArtifactResolutionRequest(); - request.setArtifact(artifact); + logger.debug("Resolving " + aetherArtifact); + MavenSession mavenSession = getMavenSession(session); - request.setResolveRoot(true); - request.setOffline(mavenSession.isOffline()); - request.setCollectionFilter(a -> isValidScope(a, scopes)); - request.setResolutionFilter(a -> { - List trail = a.getDependencyTrail(); - if (logger.isDebugEnabled()) { - logger.debug("[depth=" + trail.size() + ", scope matches =" + isValidScope(a, scopes) + "][" + a + "][" - + trail.stream().collect(Collectors.joining(" >> ")) + "]"); + MavenProject project = mavenSession.getCurrentProject(); + RepositorySystemSession repositorySession = getRepositorySession(project, mavenSession); + + List repositories = getEffectiveRepositories(project, additionalRepositories); + + try { + if (depth == 0) { + // Only resolve the root artifact without dependencies + ArtifactRequest artifactRequest = new ArtifactRequest(aetherArtifact, repositories, null); + org.eclipse.aether.resolution.ArtifactResult result = repositorySystem.resolveArtifact(repositorySession, artifactRequest); + Artifact mavenArtifact = RepositoryUtils.toArtifact(result.getArtifact()); + if (mavenArtifact != null && mavenArtifact.getFile() != null) { + return List.of(new MavenArtifactFacade(mavenArtifact)); + } + return List.of(); } - return trail.size() <= depth && isValidScope(a, scopes); - }); - request.setLocalRepository(mavenSession.getLocalRepository()); - request.setResolveTransitively(depth > 0); - request.setRemoteRepositories(getEffectiveRepositories(mavenSession.getCurrentProject(), additionalRepositories, - repositorySystem, mavenSession.getSettings())); - ArtifactResolutionResult result = repositorySystem.resolve(request); - if (result.hasExceptions()) { - throw new DependencyResolutionException("resolving " + artifact + " failed!", result.getExceptions()); + + // Collect and resolve dependencies + CollectRequest collectRequest = new CollectRequest(); + collectRequest.setRoot(new Dependency(aetherArtifact, null)); + collectRequest.setRepositories(repositories); + + CollectResult collectResult = repositorySystem.collectDependencies(repositorySession, collectRequest); + DependencyNode rootNode = collectResult.getRoot(); + + final int maxDepth = depth; + final Collection effectiveScopes = scopes; + + DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, (node, parents) -> { + // Filter by depth (parents list size represents the depth) + if (parents.size() >= maxDepth) { + return false; + } + // Filter by scope + Dependency dependency = node.getDependency(); + if (dependency != null) { + Artifact mavenArt = RepositoryUtils.toArtifact(dependency.getArtifact()); + if (mavenArt != null) { + mavenArt.setScope(dependency.getScope()); + return isValidScope(mavenArt, effectiveScopes); + } + } + return true; + }); + dependencyRequest.setRoot(rootNode); + + DependencyResult dependencyResult = repositorySystem.resolveDependencies(repositorySession, dependencyRequest); + + List result = new ArrayList<>(); + for (org.eclipse.aether.resolution.ArtifactResult ar : dependencyResult.getArtifactResults()) { + if (ar.isResolved()) { + org.eclipse.aether.artifact.Artifact resolved = ar.getArtifact(); + if (resolved != null && resolved.getFile() != null) { + Artifact mavenArtifact = RepositoryUtils.toArtifact(resolved); + DependencyNode node = ar.getRequest().getDependencyNode(); + if (node != null && node.getDependency() != null) { + mavenArtifact.setScope(node.getDependency().getScope()); + } + if (isValidScope(mavenArtifact, effectiveScopes)) { + result.add(new MavenArtifactFacade(mavenArtifact)); + } + } + } else { + if (logger.isDebugEnabled()) { + logger.debug("Failed to resolve: " + ar.getRequest().getArtifact()); + } + } + } + return result; + + } catch (ArtifactResolutionException | DependencyCollectionException | DependencyResolutionException e) { + throw new org.eclipse.tycho.core.DependencyResolutionException("resolving " + aetherArtifact + " failed!", List.of(e)); } - return result.getArtifacts().stream().filter(a -> a.getFile() != null).map(MavenArtifactFacade::new).toList(); } - @SuppressWarnings("deprecation") - public static List getEffectiveRepositories(MavenProject project, - Collection additionalRepositories, RepositorySystem repositorySystem, - Settings settings) { - List projectRepositories; - if (project == null) { - try { - projectRepositories = List.of(repositorySystem.createDefaultRemoteRepository()); - } catch (InvalidRepositoryException e) { - projectRepositories = List.of(); + private RepositorySystemSession getRepositorySession(MavenProject project, MavenSession session) { + RepositorySystemSession repositorySession = session.getRepositorySession(); + for (RepositorySessionDecorator decorator : decorators) { + RepositorySystemSession decorated = decorator.decorate(project, repositorySession); + if (decorated != null) { + repositorySession = decorated; } + } + return repositorySession; + } + + public static List getEffectiveRepositories(MavenProject project, + Collection additionalRepositories) { + List repositories = new ArrayList<>(); + if (project == null) { + // Use Maven Central as default + repositories.add(new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/").build()); } else { - projectRepositories = project.getRemoteArtifactRepositories(); + List projectRepos = project.getRemoteProjectRepositories(); + if (projectRepos != null) { + repositories.addAll(projectRepos); + } } + if (additionalRepositories != null && !additionalRepositories.isEmpty()) { - List repositories = new ArrayList<>(projectRepositories); for (MavenArtifactRepositoryReference reference : additionalRepositories) { - repositories.add(repositorySystem.createArtifactRepository(reference.getId(), reference.getUrl(), null, - null, null)); + repositories.add(new RemoteRepository.Builder(reference.getId(), "default", reference.getUrl()).build()); } - projectRepositories = repositorySystem.getEffectiveRepositories(repositories); } - repositorySystem.injectMirror(projectRepositories, settings.getMirrors()); - repositorySystem.injectProxy(projectRepositories, settings.getProxies()); - repositorySystem.injectAuthentication(projectRepositories, settings.getServers()); - return projectRepositories; + + return repositories; } protected boolean isValidScope(Artifact artifact, Collection scopes) { diff --git a/tycho-core/src/test/java/org/eclipse/tycho/core/maven/MavenDependenciesResolverTest.java b/tycho-core/src/test/java/org/eclipse/tycho/core/maven/MavenDependenciesResolverTest.java index a5d11f0d0c..c0005e5215 100644 --- a/tycho-core/src/test/java/org/eclipse/tycho/core/maven/MavenDependenciesResolverTest.java +++ b/tycho-core/src/test/java/org/eclipse/tycho/core/maven/MavenDependenciesResolverTest.java @@ -13,17 +13,26 @@ import java.io.IOException; import java.nio.file.Files; import java.util.Collection; +import java.util.Date; import java.util.List; import org.apache.commons.io.FileUtils; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.execution.DefaultMavenExecutionRequest; import org.apache.maven.execution.DefaultMavenExecutionRequestPopulator; +import org.apache.maven.execution.DefaultMavenExecutionResult; +import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionRequestPopulationException; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.LegacySupport; import org.apache.maven.plugin.testing.AbstractMojoTestCase; import org.apache.maven.project.MavenProject; +import org.apache.maven.repository.internal.MavenRepositorySystemUtils; import org.codehaus.plexus.PlexusContainerException; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; +import org.eclipse.aether.repository.LocalRepository; import org.eclipse.tycho.MavenArtifactRepositoryReference; import org.eclipse.tycho.core.DependencyResolutionException; import org.eclipse.tycho.core.MavenDependenciesResolver; @@ -34,19 +43,37 @@ public class MavenDependenciesResolverTest extends AbstractMojoTestCase { @Test public void testResolveCommonsIO() throws DependencyResolutionException, PlexusContainerException, - ComponentLookupException, MavenExecutionRequestPopulationException, IOException { - MavenSession session = newMavenSession(new MavenProject()); + ComponentLookupException, MavenExecutionRequestPopulationException, IOException, Exception { File localRepo = Files.createTempDirectory("testResolveCommonsIO").toFile(); - session.getRequest().setLocalRepositoryPath(localRepo); + + // Create a properly configured repository session + DefaultRepositorySystemSession repositorySession = MavenRepositorySystemUtils.newSession(); + LocalRepository localRepository = new LocalRepository(localRepo); + repositorySession.setLocalRepositoryManager( + new SimpleLocalRepositoryManagerFactory().newInstance(repositorySession, localRepository)); + + // Create the Maven execution request + MavenExecutionRequest request = new DefaultMavenExecutionRequest(); + request.setLocalRepositoryPath(localRepo); + DefaultMavenExecutionRequestPopulator populator = getContainer() .lookup(DefaultMavenExecutionRequestPopulator.class); - populator.populateDefaults(session.getRequest()); + populator.populateDefaults(request); + + // Create session with proper repository system session + MavenSession session = new MavenSession(getContainer(), repositorySession, request, + new DefaultMavenExecutionResult()); + session.setCurrentProject(new MavenProject()); + getContainer().lookup(LegacySupport.class).setSession(session); MavenDependenciesResolverConfigurer resolver = (MavenDependenciesResolverConfigurer) getContainer() .lookup(MavenDependenciesResolver.class); - // the artifact must be pre-existing in the local repo, so the dep is added to pom.xml for this module. Test could be enhanced to fetch the artifact. + + // Get the remote repositories from the request + List remoteRepos = request.getRemoteRepositories(); + Collection deps = resolver.resolve("commons-io", "commons-io", "2.11.0", "jar", null, List.of(), - Integer.MAX_VALUE, session.getRequest().getRemoteRepositories().stream() + Integer.MAX_VALUE, remoteRepos.stream() .map(repo -> new MavenArtifactRepositoryReference() { @Override @@ -58,7 +85,7 @@ public String getUrl() { public String getId() { return repo.getId(); } - }).map(MavenArtifactRepositoryReference.class::cast) // + }).map(MavenArtifactRepositoryReference.class::cast) .toList(), session); assertEquals(deps.toString(), 1, deps.size()); From 122b661ea083a80365af076c25c2fcfa3bfb35ea Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Nov 2025 04:31:31 +0000 Subject: [PATCH 3/4] Replace org.apache.maven.repository.RepositorySystem with Aether Resolver API Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com> --- .../core/maven/MavenDependencyInjector.java | 20 ++--- .../p2resolver/P2DependencyResolver.java | 6 +- .../docbundle/DocletArtifactsResolver.java | 66 ++++++++------- .../P2ArtifactMappingToMavenRepoTest.java | 7 +- ...faultStandaloneDirectorRuntimeFactory.java | 4 - .../surefire/AbstractEclipseTestMojo.java | 47 ++++++----- .../surefire/TychoIntegrationTestMojo.java | 84 ++++++++++++------- 7 files changed, 136 insertions(+), 98 deletions(-) diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/maven/MavenDependencyInjector.java b/tycho-core/src/main/java/org/eclipse/tycho/core/maven/MavenDependencyInjector.java index 7a22d549ef..36a6a016d6 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/maven/MavenDependencyInjector.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/maven/MavenDependencyInjector.java @@ -38,11 +38,11 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.MavenArtifactRepository; +import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; import org.apache.maven.model.Dependency; import org.apache.maven.model.Model; import org.apache.maven.project.MavenProject; -import org.apache.maven.repository.RepositorySystem; -import org.apache.maven.settings.Settings; import org.codehaus.plexus.logging.Logger; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.tycho.ArtifactDescriptor; @@ -112,7 +112,7 @@ private static String getProjectKey(Dependency dependency) { public static void injectMavenDependencies(MavenProject project, DependencyArtifacts dependencies, DependencyArtifacts testDependencies, BundleReader bundleReader, Function descriptorMapping, Logger logger, - RepositorySystem repositorySystem, Settings settings, BuildPropertiesParser buildPropertiesParser, + BuildPropertiesParser buildPropertiesParser, TargetPlatformConfiguration configuration) { MavenDependencyInjector generator = new MavenDependencyInjector(project, bundleReader, descriptorMapping, logger); @@ -160,6 +160,7 @@ public static void injectMavenDependencies(MavenProject project, DependencyArtif .map(MavenGAVLocation.class::cast).flatMap(location -> location.getRepositoryReferences().stream()) .toList(); if (repositoryReferences != null && !repositoryReferences.isEmpty()) { + // Update legacy ArtifactRepository list Map repositoryMap = project.getRemoteArtifactRepositories().stream() .collect(Collectors.toMap(MavenDependencyInjector::getId, Function.identity(), (a, b) -> a, LinkedHashMap::new)); @@ -167,19 +168,18 @@ public static void injectMavenDependencies(MavenProject project, DependencyArtif String id = getId(reference); ArtifactRepository artifactRepository = repositoryMap.get(id); if (artifactRepository == null) { - repositoryMap.put(id, - repositorySystem.createArtifactRepository(id, reference.getUrl(), null, null, null)); + MavenArtifactRepository newRepo = new MavenArtifactRepository(); + newRepo.setId(id); + newRepo.setUrl(reference.getUrl()); + newRepo.setLayout(new DefaultRepositoryLayout()); + repositoryMap.put(id, newRepo); } else if (!artifactRepository.getUrl().equals(reference.getUrl())) { logger.warn("Target defines an artifact repository with the ID " + id + " but there is already a repository for that ID mapped to a different URL! (target URL = " + reference.getUrl() + ", existing URL = " + artifactRepository.getUrl()); } } - List artifactRepositories = new ArrayList<>(repositoryMap.values()); - repositorySystem.injectMirror(artifactRepositories, settings.getMirrors()); - repositorySystem.injectProxy(artifactRepositories, settings.getProxies()); - repositorySystem.injectAuthentication(artifactRepositories, settings.getServers()); - project.setRemoteArtifactRepositories(artifactRepositories); + project.setRemoteArtifactRepositories(new ArrayList<>(repositoryMap.values())); } } diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2DependencyResolver.java b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2DependencyResolver.java index 56085654f0..9dfc3b6b35 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2DependencyResolver.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2DependencyResolver.java @@ -38,7 +38,6 @@ import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.LegacySupport; import org.apache.maven.project.MavenProject; -import org.apache.maven.repository.RepositorySystem; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; @@ -108,9 +107,6 @@ public class P2DependencyResolver implements DependencyResolver, Initializable { @Requirement private BundleReader bundleReader; - @Requirement - private RepositorySystem repositorySystem; - @Requirement private TychoProjectManager projectManager; @@ -435,7 +431,7 @@ public void injectDependenciesIntoMavenModel(MavenProject project, TychoProject descriptorMapping = null; } MavenDependencyInjector.injectMavenDependencies(project, dependencyArtifacts, testDependencyArtifacts, - bundleReader, descriptorMapping, logger, repositorySystem, context.getSession().getSettings(), + bundleReader, descriptorMapping, logger, buildPropertiesParser, configuration); } diff --git a/tycho-extras/tycho-document-bundle-plugin/src/main/java/org/eclipse/tycho/extras/docbundle/DocletArtifactsResolver.java b/tycho-extras/tycho-document-bundle-plugin/src/main/java/org/eclipse/tycho/extras/docbundle/DocletArtifactsResolver.java index 8573b3d4a7..63c95923ce 100644 --- a/tycho-extras/tycho-document-bundle-plugin/src/main/java/org/eclipse/tycho/extras/docbundle/DocletArtifactsResolver.java +++ b/tycho-extras/tycho-document-bundle-plugin/src/main/java/org/eclipse/tycho/extras/docbundle/DocletArtifactsResolver.java @@ -20,17 +20,18 @@ import javax.inject.Named; import javax.inject.Singleton; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.resolver.ArtifactResolutionException; -import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; -import org.apache.maven.artifact.resolver.ArtifactResolutionResult; -import org.apache.maven.artifact.resolver.ResolutionErrorHandler; +import org.apache.maven.RepositoryUtils; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.LegacySupport; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; -import org.apache.maven.repository.RepositorySystem; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.resolution.DependencyRequest; +import org.eclipse.aether.resolution.DependencyResolutionException; +import org.eclipse.aether.resolution.DependencyResult; @Named @Singleton @@ -39,9 +40,6 @@ public class DocletArtifactsResolver { @Inject private RepositorySystem repositorySystem; - @Inject - private ResolutionErrorHandler resolutionErrorHandler; - @Inject private LegacySupport legacySupport; @@ -49,10 +47,8 @@ public DocletArtifactsResolver() { // needed for plexus } - DocletArtifactsResolver(RepositorySystem repositorySystem, ResolutionErrorHandler resolutionErrorHandler, - LegacySupport legacySupport) { + DocletArtifactsResolver(RepositorySystem repositorySystem, LegacySupport legacySupport) { this.repositorySystem = repositorySystem; - this.resolutionErrorHandler = resolutionErrorHandler; this.legacySupport = legacySupport; } @@ -76,23 +72,37 @@ public Set resolveArtifacts(List dependencies) throws MojoEx MavenProject project = session.getCurrentProject(); for (Dependency dependency : dependencies) { - Artifact artifact = repositorySystem.createDependencyArtifact(dependency); - ArtifactResolutionRequest request = new ArtifactResolutionRequest(); - request.setArtifact(artifact); - request.setResolveRoot(true).setResolveTransitively(true); - request.setLocalRepository(session.getLocalRepository()); - request.setRemoteRepositories(project.getPluginArtifactRepositories()); - request.setOffline(session.isOffline()); - request.setForceUpdate(session.getRequest().isUpdateSnapshots()); - ArtifactResolutionResult result = repositorySystem.resolve(request); - try { - resolutionErrorHandler.throwErrors(request, result); - } catch (ArtifactResolutionException e) { - throw new MojoExecutionException("Failed to resolve doclet artifact " + dependency.getManagementKey(), - e); + String classifier = dependency.getClassifier(); + String extension = dependency.getType() != null ? dependency.getType() : "jar"; + org.eclipse.aether.artifact.Artifact aetherArtifact; + if (classifier != null && !classifier.isEmpty()) { + aetherArtifact = new DefaultArtifact(dependency.getGroupId(), + dependency.getArtifactId(), classifier, extension, + dependency.getVersion()); + } else { + aetherArtifact = new DefaultArtifact(dependency.getGroupId(), + dependency.getArtifactId(), "", extension, + dependency.getVersion()); } - for (Artifact resolvedArtifact : result.getArtifacts()) { - files.add(resolvedArtifact.getFile().getAbsolutePath()); + + CollectRequest collectRequest = new CollectRequest(); + collectRequest.setRoot(new org.eclipse.aether.graph.Dependency(aetherArtifact, null)); + collectRequest.setRepositories(RepositoryUtils.toRepos(project.getPluginArtifactRepositories())); + + DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, null); + + try { + DependencyResult result = repositorySystem.resolveDependencies(session.getRepositorySession(), dependencyRequest); + for (var ar : result.getArtifactResults()) { + if (ar.isResolved()) { + org.eclipse.aether.artifact.Artifact resolved = ar.getArtifact(); + if (resolved != null && resolved.getFile() != null) { + files.add(resolved.getFile().getAbsolutePath()); + } + } + } + } catch (DependencyResolutionException e) { + throw new MojoExecutionException("Failed to resolve doclet artifact " + dependency.getManagementKey(), e); } } diff --git a/tycho-its/src/test/java/org/eclipse/tycho/test/p2Repository/P2ArtifactMappingToMavenRepoTest.java b/tycho-its/src/test/java/org/eclipse/tycho/test/p2Repository/P2ArtifactMappingToMavenRepoTest.java index d94b430cba..d78b3eaab3 100644 --- a/tycho-its/src/test/java/org/eclipse/tycho/test/p2Repository/P2ArtifactMappingToMavenRepoTest.java +++ b/tycho-its/src/test/java/org/eclipse/tycho/test/p2Repository/P2ArtifactMappingToMavenRepoTest.java @@ -15,13 +15,14 @@ import java.nio.file.Files; import org.apache.maven.it.Verifier; -import org.apache.maven.repository.RepositorySystem; import org.eclipse.tycho.test.AbstractTychoIntegrationTest; import org.eclipse.tycho.test.util.ResourceUtil; import org.junit.Test; public class P2ArtifactMappingToMavenRepoTest extends AbstractTychoIntegrationTest { + private static final String MAVEN_CENTRAL_URL = "https://repo.maven.apache.org/maven2"; + @Test public void testMapperReferenceMavenCentral() throws Exception { Verifier verifier = getVerifier("p2Repository.mavenRepo"); @@ -32,8 +33,8 @@ public void testMapperReferenceMavenCentral() throws Exception { File artifactsXML = new File(repository, "artifacts.xml"); assertTrue( artifactsXML.getAbsoluteFile() + " does not contain required line " - + RepositorySystem.DEFAULT_REMOTE_REPO_URL, + + MAVEN_CENTRAL_URL, Files.readAllLines(artifactsXML.toPath()).stream() - .anyMatch(line -> line.contains(RepositorySystem.DEFAULT_REMOTE_REPO_URL))); + .anyMatch(line -> line.contains(MAVEN_CENTRAL_URL))); } } diff --git a/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/runtime/DefaultStandaloneDirectorRuntimeFactory.java b/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/runtime/DefaultStandaloneDirectorRuntimeFactory.java index af575a0fcf..616a68d70c 100644 --- a/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/runtime/DefaultStandaloneDirectorRuntimeFactory.java +++ b/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/runtime/DefaultStandaloneDirectorRuntimeFactory.java @@ -28,7 +28,6 @@ import javax.inject.Singleton; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.repository.RepositorySystem; import org.codehaus.plexus.logging.Logger; import org.eclipse.core.runtime.CoreException; import org.eclipse.equinox.p2.core.IProvisioningAgent; @@ -47,9 +46,6 @@ @Singleton public class DefaultStandaloneDirectorRuntimeFactory implements StandaloneDirectorRuntimeFactory { - @Inject - private RepositorySystem repositorySystem; - @Inject DirectorRuntime bootstrapDirector; diff --git a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java index 689029b013..51bfc066d7 100644 --- a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java +++ b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java @@ -41,23 +41,24 @@ import javax.inject.Inject; import javax.inject.Named; +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.resolver.ArtifactResolutionException; -import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; -import org.apache.maven.artifact.resolver.ArtifactResolutionResult; -import org.apache.maven.artifact.resolver.ResolutionErrorHandler; import org.apache.maven.model.Dependency; import org.apache.maven.model.Repository; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.repository.RepositorySystem; import org.apache.maven.surefire.api.booter.ProviderParameterNames; import org.apache.maven.surefire.api.util.ScanResult; import org.apache.maven.surefire.booter.BooterConstants; import org.apache.maven.surefire.booter.PropertiesWrapper; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.cli.CommandLineUtils; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.ArtifactResult; import org.eclipse.equinox.internal.p2.metadata.IRequiredCapability; import org.eclipse.equinox.p2.metadata.IRequirement; import org.eclipse.equinox.spi.p2.publisher.PublisherHelper; @@ -328,9 +329,6 @@ public abstract class AbstractEclipseTestMojo extends AbstractTestMojo { @Inject protected RepositorySystem repositorySystem; - @Inject - private ResolutionErrorHandler resolutionErrorHandler; - @Inject private Map projectTypes; @@ -1215,23 +1213,34 @@ private List getFrameworkExtensions() throws MojoExecutionException { if (frameworkExtensions != null) { for (Dependency frameworkExtension : frameworkExtensions) { - Artifact artifact = repositorySystem.createDependencyArtifact(frameworkExtension); - ArtifactResolutionRequest request = new ArtifactResolutionRequest(); - request.setArtifact(artifact); - request.setResolveRoot(true).setResolveTransitively(false); - request.setLocalRepository(session.getLocalRepository()); + String classifier = frameworkExtension.getClassifier(); + String extension = frameworkExtension.getType() != null ? frameworkExtension.getType() : "jar"; + org.eclipse.aether.artifact.Artifact aetherArtifact; + if (classifier != null && !classifier.isEmpty()) { + aetherArtifact = new DefaultArtifact(frameworkExtension.getGroupId(), + frameworkExtension.getArtifactId(), classifier, extension, + frameworkExtension.getVersion()); + } else { + aetherArtifact = new DefaultArtifact(frameworkExtension.getGroupId(), + frameworkExtension.getArtifactId(), "", extension, + frameworkExtension.getVersion()); + } + + ArtifactRequest request = new ArtifactRequest(); + request.setArtifact(aetherArtifact); // XXX wrong repositories -- these are user artifacts, not plugin artifacts - request.setRemoteRepositories(project.getPluginArtifactRepositories()); - request.setOffline(session.isOffline()); - request.setForceUpdate(session.getRequest().isUpdateSnapshots()); - ArtifactResolutionResult result = repositorySystem.resolve(request); + request.setRepositories(RepositoryUtils.toRepos(project.getPluginArtifactRepositories())); + try { - resolutionErrorHandler.throwErrors(request, result); + ArtifactResult result = repositorySystem.resolveArtifact(session.getRepositorySession(), request); + org.eclipse.aether.artifact.Artifact resolved = result.getArtifact(); + if (resolved != null && resolved.getFile() != null) { + files.add(resolved.getFile()); + } } catch (ArtifactResolutionException e) { throw new MojoExecutionException( "Failed to resolve framework extension " + frameworkExtension.getManagementKey(), e); } - files.add(artifact.getFile()); } } diff --git a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/TychoIntegrationTestMojo.java b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/TychoIntegrationTestMojo.java index 60f1755c2a..ce57082159 100644 --- a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/TychoIntegrationTestMojo.java +++ b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/TychoIntegrationTestMojo.java @@ -16,15 +16,14 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; -import org.apache.maven.artifact.resolver.ArtifactResolutionResult; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.descriptor.PluginDescriptor; @@ -34,6 +33,13 @@ import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.surefire.api.util.ScanResult; import org.apache.maven.surefire.booter.PropertiesWrapper; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.graph.DependencyFilter; +import org.eclipse.aether.resolution.DependencyRequest; +import org.eclipse.aether.resolution.DependencyResolutionException; +import org.eclipse.aether.resolution.DependencyResult; +import org.eclipse.aether.util.filter.DependencyFilterUtils; import org.eclipse.sisu.equinox.launching.EquinoxInstallationDescription; import org.eclipse.tycho.ClasspathEntry; import org.eclipse.tycho.PackagingType; @@ -166,9 +172,9 @@ protected void setupTestBundles(Set testFrameworkBundles, super.setupTestBundles(Collections.emptySet(), testRuntime, provider); for (final var dependency : dependencies) { - final var resolveArtifact = resolveDependency(dependency); + final var resolvedArtifacts = resolveDependency(dependency); - for (final var artifact : resolveArtifact.getArtifacts()) { + for (final var artifact : resolvedArtifacts) { final var file = artifact.getFile(); if (file != null) { @@ -217,30 +223,50 @@ protected boolean useMetadataDirectory(ReactorProject otherProject) { return meta; } - private ArtifactResolutionResult resolveDependency(final Dependency dependency) { - final var artifact = repositorySystem.createDependencyArtifact(dependency); - final var remoteRepositories = new ArrayList(32); - remoteRepositories.addAll(pluginRemoteRepositories); - remoteRepositories.addAll(projectRemoteRepositories); - - final var request = new ArtifactResolutionRequest()// - .setOffline(session.isOffline())// - .setArtifact(artifact)// - .setLocalRepository(localRepository)// - .setResolveTransitively(true)// - .setCollectionFilter(new ProviderDependencyArtifactFilter())// - .setRemoteRepositories(remoteRepositories); - return repositorySystem.resolve(request); - } - - private static final class ProviderDependencyArtifactFilter implements ArtifactFilter { - static final Collection SCOPES = List.of(Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE_PLUS_RUNTIME, - Artifact.SCOPE_RUNTIME); - - @Override - public boolean include(final Artifact artifact) { - final var scope = artifact.getScope(); - return !artifact.isOptional() && (scope == null || SCOPES.contains(scope)); + private Set resolveDependency(final Dependency dependency) throws MojoExecutionException { + String classifier = dependency.getClassifier(); + String extension = dependency.getType() != null ? dependency.getType() : "jar"; + org.eclipse.aether.artifact.Artifact aetherArtifact; + if (classifier != null && !classifier.isEmpty()) { + aetherArtifact = new DefaultArtifact(dependency.getGroupId(), + dependency.getArtifactId(), classifier, extension, + dependency.getVersion()); + } else { + aetherArtifact = new DefaultArtifact(dependency.getGroupId(), + dependency.getArtifactId(), "", extension, + dependency.getVersion()); + } + + List remoteRepositories = new java.util.ArrayList<>(); + remoteRepositories.addAll(RepositoryUtils.toRepos(pluginRemoteRepositories)); + remoteRepositories.addAll(RepositoryUtils.toRepos(projectRemoteRepositories)); + + CollectRequest collectRequest = new CollectRequest(); + collectRequest.setRoot(new org.eclipse.aether.graph.Dependency(aetherArtifact, null)); + collectRequest.setRepositories(remoteRepositories); + + // Filter to include compile and runtime scopes, exclude optional dependencies + DependencyFilter filter = DependencyFilterUtils.classpathFilter( + org.eclipse.aether.util.artifact.JavaScopes.COMPILE, + org.eclipse.aether.util.artifact.JavaScopes.RUNTIME); + + DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, filter); + + try { + DependencyResult result = repositorySystem.resolveDependencies(session.getRepositorySession(), dependencyRequest); + Set artifacts = new HashSet<>(); + for (var ar : result.getArtifactResults()) { + if (ar.isResolved()) { + org.eclipse.aether.artifact.Artifact resolved = ar.getArtifact(); + if (resolved != null && resolved.getFile() != null) { + Artifact mavenArtifact = RepositoryUtils.toArtifact(resolved); + artifacts.add(mavenArtifact); + } + } + } + return artifacts; + } catch (DependencyResolutionException e) { + throw new MojoExecutionException("Failed to resolve dependency " + dependency.getManagementKey(), e); } } } From bf9c53dc5cd36392cf9314509b0b83d11be9efe2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Nov 2025 04:39:31 +0000 Subject: [PATCH 4/4] Address code review: use null for empty classifier, use public API for test Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com> --- .../MavenDependenciesResolverConfigurer.java | 2 +- .../maven/MavenDependenciesResolverTest.java | 16 +++++++--------- .../docbundle/DocletArtifactsResolver.java | 2 +- .../tycho/surefire/AbstractEclipseTestMojo.java | 2 +- .../tycho/surefire/TychoIntegrationTestMojo.java | 2 +- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/tycho-core/src/main/java/org/eclipse/tycho/osgi/configuration/MavenDependenciesResolverConfigurer.java b/tycho-core/src/main/java/org/eclipse/tycho/osgi/configuration/MavenDependenciesResolverConfigurer.java index 15be445dd1..5513391064 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/osgi/configuration/MavenDependenciesResolverConfigurer.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/osgi/configuration/MavenDependenciesResolverConfigurer.java @@ -82,7 +82,7 @@ public Collection resolve(String groupId, String artifactId, String version, if (classifier != null && !classifier.isEmpty()) { aetherArtifact = new DefaultArtifact(groupId, artifactId, classifier, extension, version); } else { - aetherArtifact = new DefaultArtifact(groupId, artifactId, "", extension, version); + aetherArtifact = new DefaultArtifact(groupId, artifactId, null, extension, version); } logger.debug("Resolving " + aetherArtifact); diff --git a/tycho-core/src/test/java/org/eclipse/tycho/core/maven/MavenDependenciesResolverTest.java b/tycho-core/src/test/java/org/eclipse/tycho/core/maven/MavenDependenciesResolverTest.java index c0005e5215..c6c25e8929 100644 --- a/tycho-core/src/test/java/org/eclipse/tycho/core/maven/MavenDependenciesResolverTest.java +++ b/tycho-core/src/test/java/org/eclipse/tycho/core/maven/MavenDependenciesResolverTest.java @@ -13,11 +13,11 @@ import java.io.IOException; import java.nio.file.Files; import java.util.Collection; -import java.util.Date; import java.util.List; import org.apache.commons.io.FileUtils; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.LegacyLocalRepositoryManager; import org.apache.maven.execution.DefaultMavenExecutionRequest; import org.apache.maven.execution.DefaultMavenExecutionRequestPopulator; import org.apache.maven.execution.DefaultMavenExecutionResult; @@ -31,8 +31,7 @@ import org.codehaus.plexus.PlexusContainerException; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; -import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.RepositorySystemSession; import org.eclipse.tycho.MavenArtifactRepositoryReference; import org.eclipse.tycho.core.DependencyResolutionException; import org.eclipse.tycho.core.MavenDependenciesResolver; @@ -46,12 +45,6 @@ public void testResolveCommonsIO() throws DependencyResolutionException, PlexusC ComponentLookupException, MavenExecutionRequestPopulationException, IOException, Exception { File localRepo = Files.createTempDirectory("testResolveCommonsIO").toFile(); - // Create a properly configured repository session - DefaultRepositorySystemSession repositorySession = MavenRepositorySystemUtils.newSession(); - LocalRepository localRepository = new LocalRepository(localRepo); - repositorySession.setLocalRepositoryManager( - new SimpleLocalRepositoryManagerFactory().newInstance(repositorySession, localRepository)); - // Create the Maven execution request MavenExecutionRequest request = new DefaultMavenExecutionRequest(); request.setLocalRepositoryPath(localRepo); @@ -60,6 +53,11 @@ public void testResolveCommonsIO() throws DependencyResolutionException, PlexusC .lookup(DefaultMavenExecutionRequestPopulator.class); populator.populateDefaults(request); + // Create a properly configured repository session using LegacyLocalRepositoryManager + DefaultRepositorySystemSession baseSession = MavenRepositorySystemUtils.newSession(); + ArtifactRepository localRepository = request.getLocalRepository(); + RepositorySystemSession repositorySession = LegacyLocalRepositoryManager.overlay(localRepository, baseSession, null); + // Create session with proper repository system session MavenSession session = new MavenSession(getContainer(), repositorySession, request, new DefaultMavenExecutionResult()); diff --git a/tycho-extras/tycho-document-bundle-plugin/src/main/java/org/eclipse/tycho/extras/docbundle/DocletArtifactsResolver.java b/tycho-extras/tycho-document-bundle-plugin/src/main/java/org/eclipse/tycho/extras/docbundle/DocletArtifactsResolver.java index 63c95923ce..e5d8ab75f7 100644 --- a/tycho-extras/tycho-document-bundle-plugin/src/main/java/org/eclipse/tycho/extras/docbundle/DocletArtifactsResolver.java +++ b/tycho-extras/tycho-document-bundle-plugin/src/main/java/org/eclipse/tycho/extras/docbundle/DocletArtifactsResolver.java @@ -81,7 +81,7 @@ public Set resolveArtifacts(List dependencies) throws MojoEx dependency.getVersion()); } else { aetherArtifact = new DefaultArtifact(dependency.getGroupId(), - dependency.getArtifactId(), "", extension, + dependency.getArtifactId(), null, extension, dependency.getVersion()); } diff --git a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java index 51bfc066d7..1ffb587858 100644 --- a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java +++ b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java @@ -1222,7 +1222,7 @@ private List getFrameworkExtensions() throws MojoExecutionException { frameworkExtension.getVersion()); } else { aetherArtifact = new DefaultArtifact(frameworkExtension.getGroupId(), - frameworkExtension.getArtifactId(), "", extension, + frameworkExtension.getArtifactId(), null, extension, frameworkExtension.getVersion()); } diff --git a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/TychoIntegrationTestMojo.java b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/TychoIntegrationTestMojo.java index ce57082159..acfb61b193 100644 --- a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/TychoIntegrationTestMojo.java +++ b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/TychoIntegrationTestMojo.java @@ -233,7 +233,7 @@ private Set resolveDependency(final Dependency dependency) throws Mojo dependency.getVersion()); } else { aetherArtifact = new DefaultArtifact(dependency.getGroupId(), - dependency.getArtifactId(), "", extension, + dependency.getArtifactId(), null, extension, dependency.getVersion()); }