= Vert.x Application Launcher
:toc: left

In essence, launching a Vert.x application is not a complex task: write a class with a `main` method, create a Vert.x instance and deploy the main verticle.

But, very often, the same problems must be solved, for example:

* configuring the number of verticle instances
* deploying the main verticle with a specific `link:../../apidocs/io/vertx/core/ThreadingModel.html[threading model]`
* creating a clustered Vert.x instance
* properly closing Vert.x when the JVM is asked to stop via signals

The Vert.x application launcher is a tool which addresses such concerns, without repeating the same code in every project.

NOTE: This module, introduced in Vert.x 5, replaces the Vert.x 4 `io.vertx.core.Launcher`.

WARNING: This module has _Tech Preview_ status, this means the API can change between versions.

== Dependencies setup

To use the Vert.x Application Launcher, add the following dependency to the _dependencies_ section of your build descriptor:

* Maven (in your `pom.xml`):

[source,xml]
----
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-launcher-application</artifactId>
  <version>5.0.0.CR3</version>
</dependency>
----

* Gradle (in your `build.gradle` file):

[source,groovy]
----
dependencies {
  compile 'io.vertx:vertx-launcher-application:5.0.0.CR3'
}
----

== Getting started

To start your Vert.x application, use `link:../../apidocs/io/vertx/launcher/application/VertxApplication.html[VertxApplication]` as the main class.

[source,shell]
----
# Assuming the command is executed on a Unix-like system which has the classpath configured in the CLASSPATH environment variable.
java -cp $CLASSPATH io.vertx.launcher.application.VertxApplication my.app.MainVerticle
----

If your application is packaged as an executable JAR, having the `Main-Class` attribute set to `io.vertx.launcher.application.VertxApplication` in the `META-INF/MANIFEST.MF` file, the command can be simplified.

[source,shell]
----
java -jar myapp.jar my.app.MainVerticle
----

=== Command line arguments

=== Main verticle parameter

The `link:../../apidocs/io/vertx/launcher/application/VertxApplication.html[VertxApplication]` main class accepts a single parameter, which is the name of the main verticle to deploy.

This parameter is optional if your application is packaged as an executable JAR having, in the `META-INF/MANIFEST.MF` file:

* the `Main-Class` attribute set to `io.vertx.launcher.application.VertxApplication` (or a subclass, as explained below), and
* the `Main-Verticle` attribute set to the name of the main verticle.

.`META-INF/MANIFEST.MF` file
----
Main-Class: io.vertx.launcher.application.VertxApplication
Main-Verticle: my.app.MainVerticle
----

=== Options

In addition to the main verticle parameter, the `link:../../apidocs/io/vertx/launcher/application/VertxApplication.html[VertxApplication]` main class accepts several options.

*-options, --options, -vertx-options, --vertx-options*=_<vertxOptionsStr>_::
Specifies the Vert.x options.
+
It should reference either a JSON file which represents the options OR be a JSON string.

*-c*, *-cluster, --cluster*::
If specified, then the Vert.x instance will form a cluster with any other Vert.x instances on the network.

*-cluster-port, --cluster-port*=_<clusterPort>_::
Port to use for cluster communication.
+
By default, a spare random port is chosen.

*-cluster-host, --cluster-host*=_<clusterHost>_::
Host to bind to for cluster communication.
+
If this is not specified, Vert.x will attempt to choose one from the available interfaces.

*-cluster-public-port, --cluster-public-port*=_<clusterPublicPort>_::
Public port to use for cluster communication.
+
By default, Vert.x uses the same as the cluster port.

*-cluster-public-host, --cluster-public-host*=_<clusterPublicHost>_::
Public host to bind to for cluster communication.
+
By default, Vert.x uses the same as the cluster host.

*-deployment-options, --deployment-options*=_<deploymentOptionsStr>_::
Specifies the main verticle deployment options.

*-w*, *-worker, --worker*::
If specified, then the main verticle is deployed with the worker threading model.
+
Takes precedence over the value defined in deployment options.

*-vt*, *-virtual-thread, --virtual-thread*::
If specified, then the main verticle is deployed with the virtual thread threading model.
+
Takes precedence over the value defined in deployment options.

*-instances, --instances*=_<instances>_::
Specifies how many instances of the verticle will be deployed.
+
Takes precedence over the value defined in deployment options.

*-conf, --conf*=_<configStr>_::
Specifies configuration that should be provided to the verticle.
+
It should reference either a JSON file which represents the options OR be a JSON string.

*-h*, *-help, --help*::
Display a help message.

== Extensibility

=== Hooks

Sometimes, it is useful to change the default behavior depending on the environment, or the configuration.
Or, perhaps, you would like to execute some actions after Vert.x has started.

For such cases, you can create a main class and an instance of `link:../../apidocs/io/vertx/launcher/application/VertxApplication.html[VertxApplication]` using hooks.

[source,java]
.`main` method implementation
----
VertxApplicationHooks hooks = new VertxApplicationHooks() {
  @Override
  public void beforeStartingVertx(HookContext context) {
    VertxOptions vertxOptions = context.vertxOptions();
    // You could customize the metrics/tracer options here
  }

  @Override
  public void afterVerticleDeployed(HookContext context) {
    System.out.println("Hooray!");
  }
};
VertxApplication app = new VertxApplication(args, hooks);
app.launch();
----

Please refer to the `link:../../apidocs/io/vertx/launcher/application/VertxApplicationHooks.html[VertxApplicationHooks]` and `link:../../apidocs/io/vertx/launcher/application/HookContext.html[HookContext]` documentation for further details about the hooks.

=== Subclassing

If you need further control on the Vert.x Application Launcher behavior, consider subclassing it.
In this case, you will be able to invoke a special constructor that lets you decide whether, on failure:

* the application should print usage (help message) to `stdout`, and
* the application should exit the JVM with a specific code.