5

I'm trying to build a CLI in Java using PICOCLI and I'm STUCK at a very basic point. I simply cannot get my application to consumer an option and it's value. Here's my class:

package com.example.demo;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import picocli.CommandLine;

@SpringBootApplication

@CommandLine.Command(name = "Greet", header = "%n@|green Hello world demo|@")
class DemoApplication implements Runnable {

    @CommandLine.Option(names = {"-u", "--user"}, required = true, description = "The user name.")
    String userName;

    public void run() {
        System.out.println("Hello, " + userName);
    }

    public static void main(String... args) {
        CommandLine.run(new DemoApplication(), System.err, args);
    }
}

I then do a mvn package, cd target and java -jar demo-1.0.jar Greet -u pico but I'm only met with this:

Unmatched argument at index 0: 'Greet'

Hello world demo
Usage: Greet -u=<userName>
  -u, --user=<userName>   The user name.

I have run out of patience trying to print a simple message ! I do not know how else to solve this. Please help!

Saturnian
  • 1,686
  • 6
  • 39
  • 65

1 Answers1

4

If you invoke the command with java, you don't need to specify the command name Greet, just specify the command line options:

java -jar demo-1.0.jar -u pico

You can think of it this way: java -jar demo-1.0.jar is the Greet command.

You may want to use the Application Assembler Maven Plugin to create a launcher script, and name that launcher script Greet.

That way, users of your program can invoke it on the command line with this command:

Greet -u pico

The maven config for AppAssembler should look something like this:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>appassembler-maven-plugin</artifactId>
        <version>1.10</version>
        <configuration>
          <programs>
            <program>
              <mainClass>com.example.demo.DemoApplication</mainClass>
              <id>Greet</id>
            </program>
          </programs>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

UPDATE: I added a section to the user manual on how to run picocli-based applications.


UPDATE 2: I recommend upgrading to the latest version of picocli; version 4.0 introduced a new execute API with better support for exit codes and error handling.

In your example, that would look like this:


public static void main(String... args) {
  int exitCode = new CommandLine(new DemoApplication()).execute(args);
  System.exit(exitCode);
}
Remko Popma
  • 35,130
  • 11
  • 92
  • 114
  • Thank you so much for this! I had no idea why "Greet" wouldn't work! This is immensely helpful! Thank you :) – Saturnian Jul 23 '20 at 22:50
  • 1
    Thank you for bringing it up! It inspired me to improve the manual and add that new section on how to run picocli-based apps, as well as brush up to the Packaging part of the manual. :thumbs-up: – Remko Popma Jul 23 '20 at 23:04