spring-boot-migrator icon indicating copy to clipboard operation
spring-boot-migrator copied to clipboard

Resolving jars fails if pom file only exists in .m2/repository

Open fabapp2 opened this issue 3 years ago • 0 comments

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 MavenPomDownloader configured to use InMemoryMavenPomCache
  • Having MavenArtifactDownloader configured to use LocalMavenArtifactCache
  1. with no dependency dir in ~/.m2/repository , let’s say ~/.m2/repository/org/slf4j/slf4j-api/1.7.30 is 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:
  2. 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:
  3. 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.pom 3.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);
    }

fabapp2 avatar Jul 12 '22 09:07 fabapp2