Skip to content

Commit

Permalink
Fix POM download (#5086)
Browse files Browse the repository at this point in the history
Cleanup
  • Loading branch information
BoykoAlex authored Feb 25, 2025
1 parent 8eddda2 commit 64a5356
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,11 @@ public Pom download(GroupArtifactVersion gav,
GroupArtifactVersion originalGav = gav;
gav = handleSnapshotTimestampVersion(gav);
List<String> uris = new ArrayList<>();

// Keep the repo and resolved GAV of the found JAR to avoid throwing if JAR is found
MavenRepository foundJarInRepo = null;
ResolvedGroupArtifactVersion foundResolvedGav = null;

for (MavenRepository repo : normalizedRepos) {
ctx.getResolutionListener().repository(repo, containingPom);
//noinspection DataFlowIssue
Expand All @@ -563,81 +568,89 @@ public Pom download(GroupArtifactVersion gav,
try {
File pomFile = new File(uri);
File jarFile = pomFile.toPath().resolveSibling(gav.getArtifactId() + '-' + versionMaybeDatedSnapshot + ".jar").toFile();

boolean jarFileExists = jarFile.exists();
boolean pomFileExists = pomFile.exists();
//NOTE:
// - The pom may exist without a .jar artifact if the pom packaging is "pom"
// - The jar may exist without a pom, if manually installed
if (!pomFile.exists() && !jarFile.exists()) {
if (!pomFileExists && !jarFileExists) {
continue;
}

RawPom rawPom;
if (pomFile.exists()) {
// If non-empty JAR found in local repo keep the repo and resolved GAV
if (foundJarInRepo == null && jarFile.length() > 0) {
foundJarInRepo = repo;
foundResolvedGav = resolvedGav;
}

if (pomFileExists) {
try (FileInputStream fis = new FileInputStream(pomFile)) {
rawPom = RawPom.parse(fis, Objects.equals(versionMaybeDatedSnapshot, gav.getVersion()) ? null : versionMaybeDatedSnapshot);
RawPom rawPom = RawPom.parse(fis, Objects.equals(versionMaybeDatedSnapshot, gav.getVersion()) ? null : versionMaybeDatedSnapshot);
Pom pom = rawPom.toPom(inputPath, repo).withGav(resolvedGav);

if (pom.getPackaging() == null || pom.hasJarPackaging()) {
if (!jarFileExists || jarFile.length() == 0) {
// The jar has not been downloaded, making this dependency unusable.
continue;
}
}

if (repo.getUri().equals(MavenRepository.MAVEN_LOCAL_DEFAULT.getUri())) {
// so that the repository path is the same regardless of username
pom = pom.withRepository(MavenRepository.MAVEN_LOCAL_USER_NEUTRAL);
}

if (!Objects.equals(versionMaybeDatedSnapshot, pom.getVersion())) {
pom = pom.withGav(pom.getGav().withDatedSnapshotVersion(versionMaybeDatedSnapshot));
}
mavenCache.putPom(resolvedGav, pom);
ctx.getResolutionListener().downloadSuccess(resolvedGav, containingPom);
sample.stop(timer.tags("outcome", "from maven local").register(Metrics.globalRegistry));
return pom;
}
} else {
// Record the absense of the pom file
ctx.getResolutionListener().downloadError(gav, uris, (containingPom == null) ? null : containingPom.getRequested());
// infer rawPom from jar
rawPom = rawPomFromGav(gav);
}

Pom pom = rawPom.toPom(inputPath, repo).withGav(resolvedGav);

if (pom.getPackaging() == null || pom.hasJarPackaging()) {
if (!jarFile.exists() || jarFile.length() == 0) {
// The jar has not been downloaded, making this dependency unusable.
continue;
}
}

if (repo.getUri().equals(MavenRepository.MAVEN_LOCAL_DEFAULT.getUri())) {
// so that the repository path is the same regardless of username
pom = pom.withRepository(MavenRepository.MAVEN_LOCAL_USER_NEUTRAL);
}

if (!Objects.equals(versionMaybeDatedSnapshot, pom.getVersion())) {
pom = pom.withGav(pom.getGav().withDatedSnapshotVersion(versionMaybeDatedSnapshot));
}
mavenCache.putPom(resolvedGav, pom);
ctx.getResolutionListener().downloadSuccess(resolvedGav, containingPom);
sample.stop(timer.tags("outcome", "from maven local").register(Metrics.globalRegistry));
return pom;
} catch (IOException e) {
// unable to read the pom from a file-based repository.
repositoryResponses.put(repo, e.getMessage());
}
} else {
try {
RawPom rawPom;
try {
byte[] responseBody = requestAsAuthenticatedOrAnonymous(repo, uri.toString());
rawPom = RawPom.parse(

Path inputPath = Paths.get(gav.getGroupId(), gav.getArtifactId(), gav.getVersion());
RawPom rawPom = RawPom.parse(
new ByteArrayInputStream(responseBody),
Objects.equals(versionMaybeDatedSnapshot, gav.getVersion()) ? null : versionMaybeDatedSnapshot
);
Pom pom = rawPom.toPom(inputPath, repo).withGav(resolvedGav);
if (!Objects.equals(versionMaybeDatedSnapshot, pom.getVersion())) {
pom = pom.withGav(pom.getGav().withDatedSnapshotVersion(versionMaybeDatedSnapshot));
}
mavenCache.putPom(resolvedGav, pom);
ctx.getResolutionListener().downloadSuccess(resolvedGav, containingPom);
sample.stop(timer.tags("outcome", "downloaded").register(Metrics.globalRegistry));
return pom;
} catch (HttpSenderResponseException e) {
repositoryResponses.put(repo, e.getMessage());
// When `pom` is not found, try to see if `jar` exists for the same GAV
if (!e.isClientSideException() || !jarExistsForPomUri(repo, uri.toString())) {
throw e;
}

// JAR has been found but not the POM. Keep the repo and GAV if not already kept
if (foundJarInRepo == null) {
foundJarInRepo = repo;
foundResolvedGav = resolvedGav;
}

// Record the absense of the pom file
ctx.getResolutionListener().downloadError(gav, uris, (containingPom == null) ? null : containingPom.getRequested());

// Continue with a recreated pom
rawPom = rawPomFromGav(gav);
}
Path inputPath = Paths.get(gav.getGroupId(), gav.getArtifactId(), gav.getVersion());
Pom pom = rawPom.toPom(inputPath, repo).withGav(resolvedGav);
if (!Objects.equals(versionMaybeDatedSnapshot, pom.getVersion())) {
pom = pom.withGav(pom.getGav().withDatedSnapshotVersion(versionMaybeDatedSnapshot));
}
mavenCache.putPom(resolvedGav, pom);
ctx.getResolutionListener().downloadSuccess(resolvedGav, containingPom);
sample.stop(timer.tags("outcome", "downloaded").register(Metrics.globalRegistry));
return pom;
} catch (HttpSenderResponseException e) {
repositoryResponses.put(repo, e.getMessage());
if (e.isClientSideException()) {
Expand All @@ -655,10 +668,24 @@ public Pom download(GroupArtifactVersion gav,
repositoryResponses.put(repo, "Did not attempt to download because of a previous failure to retrieve from this repository.");
}
}
ctx.getResolutionListener().downloadError(gav, uris, (containingPom == null) ? null : containingPom.getRequested());
sample.stop(timer.tags("outcome", "unavailable").register(Metrics.globalRegistry));
throw new MavenDownloadingException("Unable to download POM: " + gav + '.', null, originalGav)
.setRepositoryResponses(repositoryResponses);
if (foundJarInRepo != null && foundResolvedGav != null) {
// IF JAR has been found return the artificially created POM not to throw exception
RawPom rawPom = rawPomFromGav(gav);
Path inputPath = Paths.get(gav.getGroupId(), gav.getArtifactId(), gav.getVersion());
Pom pom = rawPom.toPom(inputPath, foundJarInRepo).withGav(foundResolvedGav);
if (!Objects.equals(versionMaybeDatedSnapshot, pom.getVersion())) {
pom = pom.withGav(pom.getGav().withDatedSnapshotVersion(versionMaybeDatedSnapshot));
}
mavenCache.putPom(foundResolvedGav, pom);
ctx.getResolutionListener().downloadSuccess(foundResolvedGav, containingPom);
sample.stop(timer.tags("outcome", "downloaded").register(Metrics.globalRegistry));
return pom;
} else {
ctx.getResolutionListener().downloadError(gav, uris, (containingPom == null) ? null : containingPom.getRequested());
sample.stop(timer.tags("outcome", "unavailable").register(Metrics.globalRegistry));
throw new MavenDownloadingException("Unable to download POM: " + gav + '.', null, originalGav)
.setRepositoryResponses(repositoryResponses);
}
}

private RawPom rawPomFromGav(GroupArtifactVersion gav) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,11 @@
import org.openrewrite.*;
import org.openrewrite.ipc.http.HttpSender;
import org.openrewrite.ipc.http.HttpUrlConnectionSender;
import org.openrewrite.maven.MavenDownloadingException;
import org.openrewrite.maven.MavenExecutionContextView;
import org.openrewrite.maven.MavenParser;
import org.openrewrite.maven.MavenSettings;
import org.openrewrite.maven.*;
import org.openrewrite.maven.http.OkHttpSender;
import org.openrewrite.maven.tree.*;
import org.openrewrite.test.RewriteTest;
import org.openrewrite.xml.tree.Xml;

import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
Expand Down Expand Up @@ -1298,4 +1296,34 @@ public MockResponse dispatch(RecordedRequest recordedRequest) {
}
}
}

@Test
void resolveDependencies() throws MavenDownloadingExceptions {
Xml.Document doc = (Xml.Document) MavenParser.builder().build().parse("""
<project>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
""").toList().get(0);
MavenResolutionResult resolutionResult = doc.getMarkers().findFirst(MavenResolutionResult.class).orElseThrow();
resolutionResult = resolutionResult.resolveDependencies(new MavenPomDownloader(Collections.emptyMap(), new InMemoryExecutionContext(), null, null), new InMemoryExecutionContext());
List<ResolvedDependency> deps = resolutionResult.getDependencies().get(Scope.Compile);
assertThat(deps).hasSize(34);
}


}

0 comments on commit 64a5356

Please sign in to comment.