Introducing Command Mode

Ever wanted to use Quarkus awesome API’s and full feature set from a command line application ?

Did you need to run a scheduled batch job now and then and not wanting to embed it into your main Quarkus built service ?

3xwzsh

Quarkus has thus far been used to write applications that runs via an endpoint i.e. long running webserver via http or short-lived function in a serverless environment.

In Quarkus 1.4 command mode lets you write apps that run without an endpoint and optionally exits immediately.

This enables you to use Quarkus for writing a whole new style of applications - think command line clients (CLI), batch scripts, console apps, etc.

How to use it

Below is a simple GreetingMain class which uses the traditional GreetingService from all our quickstarts.

import io.quarkus.runtime.QuarkusApplication;
import io.quarkus.runtime.annotations.QuarkusMain;

@QuarkusMain    (1)
public class GreetingMain implements QuarkusApplication {
  @Inject (2)
  GreetingService service;

  @Override
  public int run(String... args) throws Exception {   (3)

    if (args.length>0) {
      System.out.println(service.greeting(arg[0]));
    } else {
      System.out.println(service.greeting(""));
    }

    return 0;
 }
}
1 The @QuarkusMain annotation tells Quarkus that this is the main entry point. <.> The run method is invoked once Quarkus starts, and the application stops when it finishes. If you would like to access request scoped beans you can annotate the run method with @ActivateRequestContext. This is useful to write or reuse your existing business logic using i.e. Hibernate Panache Entity beans query methods.

You can add this to a GreetingMain.java and compile to a .jar or to full native (using mvnw package -Dnative) and when run you get something like:

 ./target/getting-started-command-mode-1.0-SNAPSHOT-runner commando
__  ____  __  _____   ___  __ ____  ______
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2020-04-25 00:14:38,999 INFO  [io.quarkus] (main) getting-started-command-mode 1.0-SNAPSHOT (powered by Quarkus 999-SNAPSHOT) started in 0.005s.
2020-04-25 00:14:38,999 INFO  [io.quarkus] (main) Profile prod activated.
2020-04-25 00:14:38,999 INFO  [io.quarkus] (main) Installed features: [cdi]
hello commando
2020-04-25 00:14:38,999 INFO  [io.quarkus] (main) getting-started-command-mode stopped in 0.000s

Clean output

When working with a cli the default console log output can be verbose. For now the best way to turn that off is by setting the following properties:

quarkus.banner.enabled=false ```

These could be set in a custom profile called `cli` by adding a `%cli.`
prefix.

This has some issues and possible solution are being discussed in issue
https://github.com/quarkusio/quarkus/issues/8871[#8871].

=== Development mode

Command mode works with `quarkus:dev` aka. dev-mode.

When you run with `mvn quarkus:dev` you can add `-Dquarkus.args=yourvalue`
as arguments you want to pass into the command line.

`quarkusargs` will be split on whitespace and honors escaped quotes to. Thus
with `mvn quarkus:dev -Dquarkus.args="foo bar \"baz qux\""` the app will
start and after end look like this:

[source, shell]
----
foo
bar
baz qux
Quarkus application exited with code 0
Press Enter to restart or Ctrl + C to quit
----

You can now Press Enter multiple times to force a rerun and if you edited
source code Press Enter will trigger build and then restart with no real
overhead.

=== Main methods

As part of adding command mode via a `@QuarkusMain` annotated class you can
now have your own `static void main()` method. Below snippet is the minimum
to run Quarkus from a main method.

[source, java]
----
static void main(String ...args) {
    Quarkus.run(args);
}
----

To use it with the above `@QuarksMain` class would look something like this:

[source, java]
----
static void main(String ...args) {
    Quarkus.run(GreetingMain.class, args);
}
----

That is all. This allows you to not only customize start/stop of your Quarks
app and what many asked for: ability to launch/debug a Quarkus app directly
from an IDE.

You can see a fully working example of these classes in the
https://github.com/quarkusio/quarkus-quickstarts/tree/development/getting-started-command-mode[command-mode
quickstart].

=== Minimal CLI App

It is worth noticing that your cli app can still be serving out an endpoint
- in fact, in the default app as we just made the rest endpoint is still
starting and running. You just don't notice it. Quarkus is that fast.

In case you truly want a minimal extension you remove the `quarkus-resteasy`
extension in your `pom.xml` and put `arc` instead.

Then nothing else than your Quarkus main class will be run.

=== What is next ?

You tell us! What would you like to do with a command app with Quarkus ?

For now we are enjoying writing CLI's but how many others will join us!

Let us know of your ideas at https://github.com/quarkusio/quarkus/issues.