diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactResolver.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactResolver.java index 6c614d923..86784f024 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactResolver.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultArtifactResolver.java @@ -312,9 +312,10 @@ private List resolve( new LocalArtifactRequest( artifact, filteredRemoteRepositories, request.getRequestContext())); result.setLocalArtifactResult(local); - boolean found = (filter != null && local.isAvailable()) || isLocallyInstalled(local, versionResult); - // with filtering it is availability that drives logic - // without filtering it is simply presence of file that drives the logic + boolean found = (filter != null && local.isAvailable()) + || (filter == null && isLocallyInstalled(local, versionResult)); + // with filtering: availability drives the logic + // without filtering: simply presence of file drives the logic // "interop" logic with simple LRM leads to RRF breakage: hence is ignored when filtering in effect if (found) { if (local.getRepository() != null) { @@ -431,6 +432,18 @@ private List resolve( } } + /** + * This is the method that checks local artifact result if no RRF being used. Unlike with RRF, where only + * {@link LocalArtifactResult#isAvailable()} is checked, here we perform multiple checks: + * + * Note: the third check is interfering with RRF, as RRF may make list of remote repositories empty, that was + * originally non-empty, by eliminating remote repositories to consider. + * Hence, we may use this method ONLY if RRF is inactive. + */ private boolean isLocallyInstalled(LocalArtifactResult lar, VersionResult vr) { if (lar.isAvailable()) { return true; diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultArtifactResolverTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultArtifactResolverTest.java index 0dc8a1509..3dfce4f39 100644 --- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultArtifactResolverTest.java +++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/DefaultArtifactResolverTest.java @@ -34,6 +34,7 @@ import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.ArtifactProperties; import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.impl.RemoteRepositoryFilterManager; import org.eclipse.aether.impl.UpdateCheckManager; import org.eclipse.aether.impl.VersionResolver; import org.eclipse.aether.internal.impl.filter.DefaultRemoteRepositoryFilterManager; @@ -62,6 +63,7 @@ import org.eclipse.aether.resolution.VersionResult; import org.eclipse.aether.spi.connector.ArtifactDownload; import org.eclipse.aether.spi.connector.MetadataDownload; +import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter; import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilterSource; import org.eclipse.aether.spi.io.PathProcessorSupport; import org.eclipse.aether.transfer.ArtifactNotFoundException; @@ -90,7 +92,7 @@ public class DefaultArtifactResolverTest { private HashMap remoteRepositoryFilterSources; - private DefaultRemoteRepositoryFilterManager remoteRepositoryFilterManager; + private RemoteRepositoryFilterManager remoteRepositoryFilterManager; @BeforeEach void setup() { @@ -902,4 +904,102 @@ public VersionResult resolveVersion(RepositorySystemSession session, VersionRequ resolved = resolved.setFile(null); assertEquals(artifact, resolved); } + + @Test + void testCachedButFilteredOut() throws ArtifactResolutionException { + remoteRepositoryFilterManager = new RemoteRepositoryFilterManager() { + @Override + public RemoteRepositoryFilter getRemoteRepositoryFilter(RepositorySystemSession session) { + return new RemoteRepositoryFilter() { + @Override + public Result acceptArtifact(RemoteRepository remoteRepository, Artifact artifact) { + return new Result() { + @Override + public boolean isAccepted() { + return false; + } + + @Override + public String reasoning() { + return "REFUSED"; + } + }; + } + + @Override + public Result acceptMetadata(RemoteRepository remoteRepository, Metadata metadata) { + return new Result() { + @Override + public boolean isAccepted() { + return true; + } + + @Override + public String reasoning() { + return "OK"; + } + }; + } + }; + } + }; + session.setLocalRepositoryManager(new LocalRepositoryManager() { + public LocalRepository getRepository() { + return null; + } + + public String getPathForRemoteMetadata(Metadata metadata, RemoteRepository repository, String context) { + return null; + } + + public String getPathForRemoteArtifact(Artifact artifact, RemoteRepository repository, String context) { + return null; + } + + public String getPathForLocalMetadata(Metadata metadata) { + return null; + } + + public String getPathForLocalArtifact(Artifact artifact) { + return null; + } + + public LocalArtifactResult find(RepositorySystemSession session, LocalArtifactRequest request) { + LocalArtifactResult result = new LocalArtifactResult(request); + result.setAvailable(false); + try { + result.setFile(TestFileUtils.createTempFile("")); + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + + public void add(RepositorySystemSession session, LocalArtifactRegistration request) {} + + public LocalMetadataResult find(RepositorySystemSession session, LocalMetadataRequest request) { + LocalMetadataResult result = new LocalMetadataResult(request); + try { + result.setFile(TestFileUtils.createTempFile("")); + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + + public void add(RepositorySystemSession session, LocalMetadataRegistration request) {} + }); + + // rebuild resolver with our filter + resolver = setupArtifactResolver(new StubVersionResolver(), new StaticUpdateCheckManager(false)); + + ArtifactRequest request = new ArtifactRequest(artifact, null, ""); + request.addRepository(new RemoteRepository.Builder("id", "default", "file:///").build()); + + // resolver should throw + ArtifactResolutionException ex = + assertThrows(ArtifactResolutionException.class, () -> resolver.resolveArtifact(session, request)); + // message should contain present=true, available=false, filter message + assertTrue(ex.getMessage().contains("gid:aid:ext:ver (present, but unavailable): REFUSED")); + } }