What should I use in Confluence 8.x for one-time jobs? Upgrading from Job module to JobConfig

Hello fellow Conf devs,

I’ve got a pretty old plugin for Confluence I need to upgrade to work in Confluence 8.x. The issue is with one-time job scheduling.

During the initial installation, I’ve got an error:
createModuleDescriptor There was a problem loading the descriptor for module 'job' in plugin 'MyPlugin Confluence Connector'.\n Job module descriptors are no longer supported. Use JobConfig modules instead.

So, I also have a Jira version of this plugin which uses the JobRunner and com.atlassian.scheduler.SchedulerService to schedule a one-time job as well as cron jobs. This works fine.

In my Jira code that uses the atlassian-scheduler, I saw a comment like: “Uses SAL scheduler service, but Confluence doesn’t support that”.

I’m trying to get Confluence to use com.atlassian.scheduler.JobRunner as well as
com.atlassian.scheduler.SchedulerService. So, I can essentially have the same functionality I have in Jira.

Is it still true that as of Confluence 8.x, it still doesn’t support SchedulerService?

If so, how do I schedule a one-off job, for example to pull data off my web app?

Currently when I tried JobRunner, it says that the job cannot be manually started as an error.

This is very confusing and the documentation on what type of scheduling Confluence 8.x supports is completely lacking.

Any help would be greatly appreciated.

I can provide stripped down code samples of what I had/have.

Hi Rom,

We use exactly the same SchedulerService code to schedule cron and one time jobs in our apps across Jira, Confluence and Bitbucket. It is definitely supported in Confluence 8.

Maybe code samples and the error that you actually get when trying SchedulerService code on Confluence will help.

1 Like

Thank you, Richard,

I will definitely give this a try and try the same thing we did for Jira.

Do you perhaps know if Confluence 7.x also supports this?
It’s really unfortunate that there’s so little documentation on things like this.

Will update the thread with whatever I discover.

Hi Richard,

I currently converted our Confluence scheduling portion to what we’ve had for Jira since our Jira version’s been using the up-to-date JobConfig all along.

I have this piece of code:

JobConfig jobConfig = JobConfig.forJobRunnerKey(JobRunnerKey.of(RUN_ONCE_JOB_KEY))
				.withRunMode(RunMode.RUN_LOCALLY)
				.withParameters(createTaskParameters(forceStart, fullRescan))
				.withSchedule(Schedule.forInterval(INFINITE_INTERVAL, 
                                 startTime.getTime()));
schedulerService.scheduleJob(JobId.of(RUN_ONCE_JOB_KEY), jobConfig);

INFINITE_INTERVAL = 10000000L

This was done to trigger the job with a very long timeout and later unregister it.

schedulerService is com.atlassian.scheduler.SchedulerService and jobConfig is com.atlassian.scheduler.config.JobConfig.

The jobConfig gets initiated correctly when I debug, but the job never fires off.
The above is strictly for one-time jobs that trigger off a synchronize button being clicked.
Also in atlassian-plugin.xml I have the following for our regular scheduling:

<job-config name="Executes synchronization between the system and Confluence" key="d42defaultjob">
		<job key="d42ConfluenceUpdateDataTask" perClusterJob="true"/>
		<schedule cron-expression="0 0 0 * * ?" jitterSecs="5"/>
		<managed editable="true" keepingHistory="false" canRunAdhoc="true" canDisable="true" />
	</job-config>

Does anything look out of place? I would appreciate your opinion.
Thank you.

I think thats a little different to how we have our one off tasks configured.

We use:

.withSchedule(Schedule.runOnce(null))
                    .withRunMode(RUN_ONCE_PER_CLUSTER)

For our one off tasks - and always make sure to unschedule any tasks with the same id before scheduling the new one. (Maybe this is not an issue in your case though)

Otherwise, looks very similar (we use schedulerService Java API rather than job-config in atlassian-plugin.xml for our regularly scheduled tasks as well)