Documentation

Creating a New Job Scheduler Task Executor

Each Job Scheduler 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 Job Scheduler 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.

    • dispatch.task.executor.name: defines the string used for the executor’s name in the Job Scheduler UI.

      Note

      If you want your Job Scheduler Task to use localized names, add a language key value for the dispatch.task.executor.name property to the module’s resources/content/Language.properties file.

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

      Note

      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).

    Important

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

    For your convenience, Liferay provides the BaseDispatchTaskExecutor abstract class that logs the Job Scheduler 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.

    Note

    The getName() method is deprecated and replaced by the dispatch.task.executor.name property.

    Tip

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

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

Deploying the Sample Job Scheduler Task Executor

Start a new Liferay instance by running

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

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

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

  1. Download and unzip the example module.

    curl https://learn.liferay.com/dxp/latest/en/building-applications/core-frameworks/job-scheduler-framework/liferay-s7a3.zip -O
    
    unzip liferay-s7a3.zip
    
  2. Run this gradlew command to build the JAR file and deploy it to your new Docker container:

    cd liferay-s7a3
    
    ./gradlew deploy -Ddeploy.docker.container.id=$(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 Job Scheduler Task to your Liferay instance.

    Add a new Job Scheduler Task using the new template.

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

    Click Run Now for your new Job Scheduler 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 task and go to the Logs tab to see a list of all previous runs.

    View and manage logs for your Job Scheduler Task.

Code for the Sample Job Scheduler Task Executor

@Component(
	property = {
		"dispatch.task.executor.name=s7a3", "dispatch.task.executor.type=s7a3"
	},
	service = DispatchTaskExecutor.class
)
public class S7A3DispatchTaskExecutor extends BaseDispatchTaskExecutor {

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

		if (_log.isInfoEnabled()) {
			_log.info(
				"Invoking #doExecute(DispatchTrigger, " +
					"DispatchTaskExecutorOutput)");
		}
	}

	@Override
	public String getName() {
		return "s7a3";
	}

	private static final Log _log = LogFactoryUtil.getLog(
		S7A3DispatchTaskExecutor.class);

}

The module is declared an OSGi @Component and defines two properties: dispatch.task.executor.name 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.