spring-boot-migrator
spring-boot-migrator copied to clipboard
Resolving jars fails if pom file only exists in .m2/repository
Describe the bug
In some situations a jar declared as dependency in a pom is not checked to exist but expected to be present when the .pom exists in .m2/repository.
Dependency resolution then fails if only the .pom exists but not the .jar.
To Reproduce
- Having
MavenPomDownloaderconfigured to useInMemoryMavenPomCache - Having
MavenArtifactDownloaderconfigured to use LocalMavenArtifactCache
- with no dependency dir in
~/.m2/repository, let’s say~/.m2/repository/org/slf4j/slf4j-api/1.7.30is empty 1.1. pom gets downloaded in memory :white_check_mark: 1.2. jar gets downloaded to~/.m2/repository/org/slf4j/slf4j-api/1.7.30:white_check_mark: - with a jar in the dependency dir
2.1 Nothing gets downloaded, jar is taken from
~/.m2/repository/org/slf4j/slf4j-api/1.7.30:white_check_mark: - with just the pom file in the dependency dir
3.1. The pom is taken from the dependency dir
~/.m2/repository/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.pom3.2. The jar is expected to be in this dir, BUT IT’S NOT :negative_squared_cross_mark:
Expected behavior
Either MavenPomDownloader should only check it's InMemoryMavenPomCache
Or LocalMavenArtifactCache should check if the jar actually exists and download it to .m2/repository if not but not expect it to exist because the pom exists in .m2.
Stacktrace
[INFO] Running org.springframework.sbm.mule.actions.wmq.WMQFlowTest
22:13:31.165 [main] ERROR o.s.s.b.i.RewriteMavenArtifactDownloader - Error while downloading dependencies
java.io.FileNotFoundException: /home/runner/.m2/repository/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar (No such file or directory)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:112)
at
Additional context
This test can be used, and by changing what's in (e.g. /Users/fkrueger/.m2/repository/org/slf4j/slf4j-api/1.7.30) the described behavior can be triggered
@Test
void test() {
String pomXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
" <modelVersion>4.0.0</modelVersion>\n" +
" <groupId>com.example</groupId>\n" +
" <artifactId>dummy-root</artifactId>\n" +
" <version>0.1.0-SNAPSHOT</version>\n" +
" <packaging>jar</packaging>\n" +
" <dependencies>\n" +
" <dependency>\n" +
" <groupId>com.ibm.mq</groupId>\n" +
" <artifactId>mq-jms-spring-boot-starter</artifactId>\n" +
" <version>2.6.4</version>\n" +
" </dependency>\n" +
" <dependency>\n" +
" <groupId>org.springframework.amqp</groupId>\n" +
" <artifactId>spring-rabbit</artifactId>\n" +
" <version>2.4.4</version>\n" +
" </dependency>\n" +
" <dependency>\n" +
" <groupId>org.springframework.integration</groupId>\n" +
" <artifactId>spring-integration-jms</artifactId>\n" +
" <version>5.5.8</version>\n" +
" </dependency>\n" +
" <dependency>\n" +
" <groupId>org.projectlombok</groupId>\n" +
" <artifactId>lombok</artifactId>\n" +
" <version>1.18.24</version>\n" +
" <scope>provided</scope>\n" +
" </dependency>\n" +
" </dependencies>\n" +
"\n" +
"</project>\n";
Xml.Document document = MavenParser.builder().build().parse(pomXml).get(0);
Optional<MavenResolutionResult> mrr = document.getMarkers().findFirst(MavenResolutionResult.class);
mrr.get().getDependencies().entrySet().stream()
.map(d -> d.getValue())
.flatMap(List::stream)
.map(d -> d.getRequested().getGav().toString())
.forEach(System.out::println);
Map<Path, Pom> map = Map.of(Path.of("pom.xml"), mrr.get().getPom().getRequested());
InMemoryExecutionContext ctx = new InMemoryExecutionContext();
MavenExecutionContextView ctxView = new MavenExecutionContextView(ctx);
ctxView.setPomCache(new InMemoryMavenPomCache());
MavenPomDownloader mavenPomDownloader = new MavenPomDownloader(map, ctxView);
MavenResolutionResult mavenResolutionResult = mrr.get().resolveDependencies(mavenPomDownloader, ctx);
mavenResolutionResult.getDependencies().entrySet().stream()
.map(e -> e.getValue())
.flatMap(List::stream)
.map(rd -> rd.toString())
.forEach(System.out::println);
assertThat(mavenResolutionResult.getDependencies().get(Scope.Compile).stream().anyMatch(d -> d.getGav().toString().contains("slf4j-api:1.7.30"))).isTrue();
MavenArtifactDownloader mavenArtifactDownloader = new MavenArtifactDownloader(new LocalMavenArtifactCache(Path.of(System.getProperty("user.home")).resolve(".m2/repository")), null, (t) -> t.printStackTrace());
ResolvedDependency resolvedDependency = mavenResolutionResult.getDependencies().get(Scope.Compile).stream().filter(d -> d.getGav().toString().contains("slf4j-api:1.7.30")).findFirst().get();
Path path = mavenArtifactDownloader.downloadArtifact(resolvedDependency);
System.out.println(path);
}