Creating a New Dispatch Task Executor

Each Dispatch Task is created by implementing the DispatchTaskExecutor interface and can execute any logic. While Liferay DXP provides multiple out-of-the-box executors, you can create your own. Once created and deployed, you can add Dispatch Tasks to a Liferay instance.

Follow these steps to create your own implementation of the DispatchTaskExecutor interface:

  1. OSGI Component: Declare the module a Component within the OSGi framework using the @Component annotation.

  2. Service: Identify the module as a DispatchTaskExecutor.class service within the @Component annotation.

  3. OSGi Properties: Add the following properties to the @Component annotation.

    • defines the string used for the executor’s name in the Dispatch UI.


      If you want your Dispatch Task to use localized names, add a language key value for the property to the module’s resources/content/ file.

    • dispatch.task.executor.type: defines a unique type value to match the right Dispatch Task Executor and Dispatch Trigger.


      Values must be unique to ensure the correct executor matches. If a value is not unique, the log displays an error on startup indicating which executors have the same property value.

  4. DispatchTaskExecutor: Implement the DispatchTaskExecutor interface or extend an implementation of it (e.g., BaseDispatchTaskExecutor).


    Implementations of the DispatchTaskExecutor interface must handle status logs for Dispatch tasks, because the Dispatch framework depends on those logs to control the concurrent execution of tasks.

    For your convenience, Liferay provides the BaseDispatchTaskExecutor abstract class that logs the Dispatch task’s status as IN PROGRESS, SUCCESSFUL, or FAILED.

  5. Methods: If you’re implementing the DispatchTaskExecutor interface directly, override its execute() method to implement custom logic. If instead you’re extending the BaseDispatchTaskExecutor abstract class, override its doExecute() method.


    The getName() method is deprecated and replaced by the property.


    You can use the dispatchTrigger.getDispatchTaskSettings() method to fetch properties set in the Dispatch Task’s Settings editor.

The following sample module demonstrates how to create and deploy a custom Dispatch Task Executor to a Liferay instance.

Deploying the Sample Dispatch Task Executor

Start a new Liferay instance by running

docker run -it -m 8g -p 8080:8080 liferay/portal:

Sign in to Liferay at http://localhost:8080. Use the email address and the password test. When prompted, change the password to learn.

Then, follow these steps to download, build, and deploy the sample Dispatch Task Executor to the new Docker container:

  1. Download and unzip the example module.

    curl -O
  2. Run this gradlew command to build the JAR file and deploy it to your new Docker container:

    cd liferay-s7a3
    ./gradlew deploy$(docker ps -lq)

    The JAR is generated in the build/libs folder (i.e., s7a3-impl/build/libs/com.acme.s7a3.impl-1.0.0).

  3. Confirm the module was successfully deployed and started via the container console.

    Processing com.acme.s7a3.impl-1.0.0.jar
    STARTED com.acme.s7a3.impl-1.0.0 [1656]
  4. Verify the module is working by using it to add a new Dispatch Task to your Liferay instance.

    Add a new Dispatch Task using the new template.

    Once you’ve created the task, click on Run Now.

    Click Run Now for your new Dispatch Task.

    If successful, it should print the following message to the console when executed.

    INFO [liferay/dispatch/executor-2][S7A3DispatchTaskExecutor:30] Invoking #doExecute(DispatchTrigger, DispatchTaskExecutorOutput)

    You can also click the Dispatch Task and go to the Logs tab to see a list of all previous runs.

    View and manage logs for your Dispatch Task.

Code for the Sample Dispatch Task Executor

	property = {
		"", "dispatch.task.executor.type=s7a3"
	service = DispatchTaskExecutor.class
public class S7A3DispatchTaskExecutor extends BaseDispatchTaskExecutor {

	public void doExecute(
			DispatchTrigger dispatchTrigger,
			DispatchTaskExecutorOutput dispatchTaskExecutorOutput)
		throws IOException, PortalException {

		if (_log.isInfoEnabled()) {
				"Invoking #doExecute(DispatchTrigger, " +

	public String getName() {
		return "s7a3";

	private static final Log _log = LogFactoryUtil.getLog(


The module is declared an OSGi @Component and defines two properties: and dispatch.task.executor.type. It then identifies the module as a DispatchTaskExecutor.class service.

Following the @Component annotation, the module extends the BaseDispatchTaskExecutor abstract class and overrides the doExecute method. This method uses the LogFactoryUtil to display an INFO message in the console’s logs.