0

I'm trying to get the output of a Maven command in a static block - specifically - resolve the location of the local repository location to a static variable.

The application hangs only when the OutputHandler is a lambda (not a method reference) and only when it's in a static initialiser (not just a static method).

Take the following minimised example:

pom.xml:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.me</groupId>
    <artifactId>maven-invoker-test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven.shared</groupId>
            <artifactId>maven-invoker</artifactId>
            <version>3.2.0</version>
        </dependency>
    </dependencies>
</project>

InvokerTest.java:

package maveninvokertest;

import java.io.File;
import java.util.Collections;
import org.apache.maven.shared.invoker.*;

public class InvokerTest {
    static {
        // doTest();
    }

    public static void main(final String[] args) {
        doTest();
    }

    /**
     * Run {@link #runMaven(InvocationOutputHandler)} against a method reference and lambda, both outputting to
     * {@link System#out}
     */
    private static void doTest() {
        System.out.println("Method Reference:");
        runMaven(System.out::println);

        System.out.println("Lambda:");
        runMaven(line -> System.out.println(line));
    }

    /** Run the {@code validate} command against Maven, outputting to {@code outputHandler} */
    private static void runMaven(final InvocationOutputHandler outputHandler) {

        try {
            final InvocationRequest request = new DefaultInvocationRequest();

            request.setMavenExecutable(new File("/opt/homebrew/bin/mvn"));
            request.setGoals(Collections.singletonList("validate"));

            request.setOutputHandler(outputHandler);

            System.out.println(new DefaultInvoker().execute(request).getExitCode());
        } catch (final Throwable t) {
            t.printStackTrace();
        }
    }
}

This application runs some dummy goal, printing the output to the console and completing normally:

Method Reference:
[WARN] Maven will be executed in interactive mode, but no input stream has been configured for this MavenInvoker instance.
[INFO] Scanning for projects...
[INFO] 
[INFO] --------------------------< com.me:maventest >--------------------------
[INFO] Building maven-invoker-test 0.0.1-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.038 s
[INFO] Finished at: 2023-08-09T11:23:57+01:00
[INFO] ------------------------------------------------------------------------
0
Lambda:
[WARN] Maven will be executed in interactive mode, but no input stream has been configured for this MavenInvoker instance.
[INFO] Scanning for projects...
[INFO] 
[INFO] --------------------------< com.me:maventest >--------------------------
[INFO] Building maven-invoker-test 0.0.1-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.040 s
[INFO] Finished at: 2023-08-09T11:23:58+01:00
[INFO] ------------------------------------------------------------------------
0

Now lets move the doTest call from the main method into the static initialiser block:

InvokerTest.java:

package maveninvokertest;

import java.io.File;
import java.util.Collections;
import org.apache.maven.shared.invoker.*;

public class InvokerTest {
    static {
        doTest();
    }

    public static void main(final String[] args) {
        // doTest();
    }

    /**
     * Run {@link #runMaven(InvocationOutputHandler)} against a method reference and lambda, both outputting to
     * {@link System#out}
     */
    private static void doTest() {
        System.out.println("Method Reference:");
        runMaven(System.out::println);

        System.out.println("Lambda:");
        runMaven(line -> System.out.println(line));
    }

    /** Run the {@code validate} command against Maven, outputting to {@code outputHandler} */
    private static void runMaven(final InvocationOutputHandler outputHandler) {

        try {
            final InvocationRequest request = new DefaultInvocationRequest();

            request.setMavenExecutable(new File("/opt/homebrew/bin/mvn"));
            request.setGoals(Collections.singletonList("validate"));

            request.setOutputHandler(outputHandler);

            System.out.println(new DefaultInvoker().execute(request).getExitCode());
        } catch (final Throwable t) {
            t.printStackTrace();
        }
    }
}

This should produce the same output, and yet instead...

Method Reference:
[WARN] Maven will be executed in interactive mode, but no input stream has been configured for this MavenInvoker instance.
[INFO] Scanning for projects...
[INFO] 
[INFO] --------------------------< com.me:maventest >--------------------------
[INFO] Building maventest 0.0.1-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.038 s
[INFO] Finished at: 2023-08-09T11:25:37+01:00
[INFO] ------------------------------------------------------------------------
0
Lambda:
[WARN] Maven will be executed in interactive mode, but no input stream has been configured for this MavenInvoker instance.

It gets this far and hangs.

Any ideas?

Jakg
  • 922
  • 12
  • 39

0 Answers0