Command line

The Axelor Open Platform can be built as a command line application.

CLI is in beta. Use it with caution till it is promoted GA.

Command line app

The command line application, ie distribution contents, can be built with the following Gradle command:

$ ./gradlew installDist

The distribution contents will be generated at build/install/{project-name} folder which includes:

  • extracted war application in the app/ directory

  • launcher script dependencies in the lib/

  • directory and executable scripts in the bin/ directory.

The bundle also includes a README.txt file with usage instructions and a LICENSE file by default. All the files in the src/main/dist directory will automatically be included in the distribution.

To package the distribution contents into a ZIP or a TAR archive, run either distZip or distTar (or assembleDist for both). The files are created at build/distributions/{project-name}-{project.version}.{ext}.

Java 21 or higher is required to run the command line application.

Command line tool

The axelor script, located in bin/ directory, is an executable command line tool that can be used to execute various commands provided by the app:

$ axelor --help

You would see something like this:

Usage: axelor [-hV] [-c=FILE] [COMMAND]
  -c, --config=FILE   Path to axelor config file.
  -h, --help          Show this help message and exit.
  -V, --version       Print version information and exit.
Commands:
  run       Run the application.
  database  Perform database maintenance operations.

To know how to use the supported commands, call the tool like this:

$ axelor run --help
$ axelor database --help

The -c option can be used to provide axelor config file.

$ axelor -c /path/to/axelor-config.properties run

Built-in commands

run

Start the embedded Tomcat server.

$ axelor run [OPTIONS]
Option Description

--port=<port>

The Tomcat port number. Defaults to 8080.

--base-dir=<path>

The Tomcat base directory.

--context-path=<path>

The webapp context path.

--proxy-url=<url>

Set proxy URL if running behind a reverse proxy.

--max-threads=<n>

Set the maximum number of worker threads.

--cache-max-size=<n>

Set the maximum cache size for resources.

database

Perform database maintenance operations. Requires a subcommand.

$ axelor database [SUBCOMMAND]

database init

Initialize the database (schema creation and demo data import).

$ axelor database init

database update

Update the database schema. Optionally restrict the update to specific modules.

$ axelor database update [OPTIONS]
Option Description

-m, --module=<module>

Specify the module to update. Can be repeated to update multiple modules.

Example:

$ axelor database update --module axelor-sale --module axelor-purchase

database migrate

Run the Liquibase migration scripts.

$ axelor database migrate

database encrypt

Encrypt or re-encrypt all encrypted field values. This command should be run in the following situations:

  • Initial encryption — encryption settings were not configured initially, and you now want to encrypt existing plain-text field values. No extra configuration is needed.

  • Password rotation — set encryption.old-password to the previous password. encryption.old-algorithm is not required and defaults to the current encryption.algorithm.

  • Algorithm change — set encryption.old-algorithm to the previous algorithm. encryption.old-password is not required and defaults to the current encryption.password.

  • Password and algorithm change — set both encryption.old-password and encryption.old-algorithm to their respective previous values.

$ axelor database encrypt
After the command completes successfully, remove any encryption.old-password or encryption.old-algorithm entries from axelor-config.properties.

Custom commands

The app modules can provide additional commands by implementing com.axelor.app.cli.CliCommand or more conveniently by extending com.axelor.app.cli.AbstractCliCommand which provide helper methods to execute tasks inside container or persistence sessions.

The custom commands are automatically discovered using the MetaScanner that efficiently scans only Axelor modules to find all implementations of com.axelor.app.cli.CliCommand.

The commands should use picocli annotations:

package com.axelor.some.cli;

import com.axelor.app.cli.AbstractCliCommand;
import java.util.Optional;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

@Command(name = "hello", description = "Show hello message.")
public class HelloCommand extends AbstractCliCommand {

  @Option(names = "--message", description="Specify alternative message.")
  private String message;

  public void run() {
    String msg = Optional.ofNullable(message).orElse("Hello World!!!");
    System.out.println(msg);
  }
}

The HelloCommand will be automatically discovered at runtime using the MetaScanner. No additional configuration is required - simply implementing the CliCommand interface is sufficient.

The hello command will be available with the axelor tool:

$ axelor hello --message "Awesome!"

The AbstractCliCommand class provide two helper methods:

  • withContainer(Runnable) - run the task within the Guice container

  • withSession(Runnable) - same as withContainer but persistence service is automatically started

package com.axelor.some.cli;

import com.axelor.app.cli.AbstractCliCommand;
import com.axelor.inject.Beans;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

@Command(name = "some", description = "Do something.")
public class SomeCommand extends AbstractCliCommand {

  public void run() {
    // persistence service is not started automatically
    withContainer(() -> { (1)
      SomeService service = Beans.get(SomeService.class);
      service.doSomeThing();
    });

    // persistence service started automatically
    withSession(() -> { (2)
      AnotherService service = Beans.get(AnotherService.class);
      service.doSomeThing();
    });
  }
}
  1. use withContainer if you need dependency injection support

  2. use withSession if you need persistence support