Fork me on GitHub

Execute a Runnable instead of a main

You can use since version 3.2.0 a Runnable instead of providing a main class to exec:java:

pom.xml

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>3.5.0</version>
        <executions>
          <execution>
            ...
            <goals>
              <goal>java</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <mainClass>com.example.MyRunnableImplementation</mainClass>
          ...
        </configuration>
      </plugin>
    </plugins>
  </build>
   ...
</project>

The Runnable can be a plain class but can also get constructor injections:

  • systemProperties: Properties, session system properties
  • systemPropertiesUpdate: BiConsumer<String, String>, session system properties update callback (pass the key/value to update, null value means removal of the key)
  • userProperties: Properties, session user properties
  • userPropertiesUpdater: BiConsumer<String, String>, session user properties update callback (pass the key/value to update, null value means removal of the key)
  • projectProperties: Properties, project properties
  • projectPropertiesUpdater: BiConsumer<String, String>, project properties update callback (pass the key/value to update, null value means removal of the key)
  • highestVersionResolver: Function<String, String>, passing a groupId:artifactId you get the latest resolved version from the project repositories.

Lastly you can inject a custom maven component naming the Runnable constructor parameter with its type and replacing dots by underscores. If you need to provide a hint you can suffix previous type name by __hint_$yourhint (assuming it stays a valid java name). This kind of parameter injection must be typed `Object`.

Example:

public class HelloRunnable implements Runnable {
    private final Function<String, String> versionResolver;
    private final Properties properties;
    private final BiConsumer<String, String> updater;

    public HelloRunnable(
            final Function<String, String> highestVersionResolver,
            final Properties systemProperties,
            final BiConsumer<String, String> systemPropertiesUpdater) {
        this.versionResolver = highestVersionResolver;
        this.properties = systemProperties;
        this.updater = systemPropertiesUpdater;
    }

    public void run() {
        final String v = properties.getProperty("test.version");
        updater.accept("hello.runnable.output", v + ": " + (versionResolver != null));
    }
}