Missed Team ’24? Catch up on announcements here.

×
Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Scheduled tasks in Jira 6.3.7

Mike Wells
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 3, 2014

I upgraded my JIRA instance to 6.3.7 today and have noticed that the scheduler-config.xml file no longer exists in atlassian-jira/WEB-INF/classes. Also the quartz.properties file is not either there. I beleive this may have changed back in 6.3.1.

With that in mind is there a new way to schedule jobs in Jira? I know that you can use the SAL and PluginScheduler but this seems to have a limitation that it runs every minute and you can't, easily, use a Cron Expression.

So as of now I have a jar file that implements org.quartz.Job interface that resides in atlassian-jira/WEB-INF/lib, however this isn't being called and I assume it has something to do with the lack of scheduler XML file?

Anyone have the same problem or have a solution?

 

*** UPDATE ***

Per request from comments below here is my implementation of the SAL PluginJob solution as per the example https://developer.atlassian.com/display/DOCS/Scheduling+Events+via+SAL+Tutorial

 

package com.dsasystems.plugins.jobs;
public interface IRecurringIssueJob{
    public void reschedule(long interval);
}
package com.dsasystems.plugins.jobs;

import java.util.Date;
import java.util.HashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.atlassian.sal.api.lifecycle.LifecycleAware;
import com.atlassian.sal.api.scheduling.PluginScheduler;


public class RecurringIssueJobImpl implements IRecurringIssueJob, LifecycleAware {

    public static final Logger log = LoggerFactory.getLogger(RecurringIssueJobImpl.class);
    
    static final String KEY = RecurringIssueJobImpl.class.getName() + ":instance";
    private static final String JOB_NAME = RecurringIssueJobImpl.class.getName() + ":job";
    private long interval = 5000L;
    private final PluginScheduler pluginScheduler;
    private Date lastRun = null;
    
    public RecurringIssueJobImpl(PluginScheduler pluginScheduler) {
        this.pluginScheduler = pluginScheduler;
    }

    @Override
    public void onStart() {
        reschedule(interval);
        
    }
    
    @Override
    public void reschedule(long interval) {
        this.interval = interval;
        pluginScheduler.scheduleJob(
                        JOB_NAME,                   // unique name of the job
                        RecurringIssueTask.class,     // class of the job
                        new HashMap<String,Object>() {{
                            put(KEY, RecurringIssueJobImpl.this);
                        }},                         // data that needs to be passed to the job
                        new Date(),                 // the time the job is to start
                        interval);                  // interval between repeats, in milliseconds
        log.info(String.format("Twitter search task scheduled to run every %dms", interval));

    }
    
    void setLastRun(Date lastRun) {
        this.lastRun = lastRun;
    }
    

}
package com.dsasystems.plugins.jobs;
import java.util.Date;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.atlassian.sal.api.scheduling.PluginJob;
public class RecurringIssueTask implements PluginJob {
    public static final Logger log = LoggerFactory.getLogger(RecurringIssueTask.class);
    
    @Override
    public void execute(Map<String, Object> jobDataMap) {
        final RecurringIssueJobImpl job = (RecurringIssueJobImpl)jobDataMap.get(RecurringIssueJobImpl.KEY);
        assert job != null;
        job.setLastRun(new Date());
        log.debug("Execute recurring issue job");
    }
}
<dependency>
	<groupId>com.atlassian.sal</groupId>
	<artifactId>sal-api</artifactId>
	<version>2.10.0</version>
	<scope>provided</scope>
</dependency>
<component-import key="pluginScheduler">
    <description>SAL Scheduler</description>
    <interface>com.atlassian.sal.api.scheduling.PluginScheduler</interface>
</component-import>

<component key="RecurringIssuesJob" class="com.dsasystems.plugins.jobs.RecurringIssueJobImpl" system="true" public="true">
        <description>The plugin component that handles recurring issue</description>
        <interface>com.atlassian.sal.api.lifecycle.LifecycleAware</interface>
        <interface>com.dsasystems.plugins.jobs.IRecurringIssueJob</interface>
</component>

 

After installing the plugin it is shown as registered in the scheduler details

 

image2014-10-6 10:11:30.png

For some reason the Schedule is 1 minute, but I set the interval to 5000ms

The atlassian log file confirms the 1 minute schedule

2014-10-06 10:05:40,503 atlassian-scheduler-quartz1.local_Worker-3 DEBUG      [dsasystems.plugins.jobs.RecurringIssueTask] Execute recurring issue job
2014-10-06 10:06:40,504 atlassian-scheduler-quartz1.local_Worker-3 DEBUG      [dsasystems.plugins.jobs.RecurringIssueTask] Execute recurring issue job
2014-10-06 10:07:40,503 atlassian-scheduler-quartz1.local_Worker-3 DEBUG      [dsasystems.plugins.jobs.RecurringIssueTask] Execute recurring issue job
2014-10-06 10:08:40,503 atlassian-scheduler-quartz1.local_Worker-3 DEBUG      [dsasystems.plugins.jobs.RecurringIssueTask] Execute recurring issue job
2014-10-06 10:09:40,503 atlassian-scheduler-quartz1.local_Worker-3 DEBUG      [dsasystems.plugins.jobs.RecurringIssueTask] Execute recurring issue job
2014-10-06 10:10:40,504 atlassian-scheduler-quartz1.local_Worker-3 DEBUG      [dsasystems.plugins.jobs.RecurringIssueTask] Execute recurring issue job

I know this solution fits closest to my needs, but I can't figure out why the interval is always one minute?

1 answer

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

0 votes
Norman Abramovitz
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 3, 2014

Please see the previous answer to a similar question.  periodic tasks in jira.

Mike Wells
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 3, 2014

Are you referring to the SAL Plugin scheduler or the service? The scheduler won't work because it seems to execute every minute only. I'm not sure how I could apply the service solution to my problem?

Norman Abramovitz
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 5, 2014

You are missing the point, the SAL scheduler should run your task at your time interval or greater specified by your interval parameter to reschedule. You can look at the documentation example and see that it is scheduled to run every 5 seconds. So most likely your scheduled task is not registered correctly or your interval value is incorrect. Hard to know without looking at your code and xml.

Norman Abramovitz
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 5, 2014

Maybe this previous answer might help point you in the right direction. https://answers.atlassian.com/questions/251623/scheduling-via-sal-does-not-give-required-output

Mike Wells
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 5, 2014

Norman Abramovitz - I updated the question with my plugin and issue

Mike Wells
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 6, 2014

It would seem the job is not being rescheduled, the logging within the reschedule method is never printed. My understanding is that the onStart method is called elsewhere, as a way to make sure that the system is fully started first.

Mike Wells
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 6, 2014

Well I see the reschedule is done once at the beginning but the interval never seems to be honored. 2014-10-06 11:30:08,010 ThreadPoolAsyncTaskExecutor::Thread 29 DEBUG mikewells 685x1544x2 bqmlr 192.168.201.215 /rest/plugins/1.0/available/featured [dsasystems.plugins.jobs.RecurringIssueJobImpl] Recurring issue job scheduled to run every 5000ms

Norman Abramovitz
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 6, 2014

I will take a closer look when I am off my work hours.

Mike Wells
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 8, 2014

I also tried this with an interval of 2 minutes, it had no impact on the interval. Still 1 minute.

Prakhar Srivastav June 3, 2016

Hi @Mike Wells

I am trying to emulate your above code and getting failed. The job is not being scheduled in scheduler details as well. I am getting the following error :

2016-06-03 18:13:32,294 ThreadPoolAsyncTaskExecutor::Thread 42 ERROR      [extender.internal.activator.ContextLoaderListener] Application context refresh failed (NonValidatingOsgiBundleXmlApplicationContext(bundle=com.atlassian.example.scheduling, config=osgibundle:/META-INF/spring/*.xml))
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'RecurringIssueJobImpl': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.atlassian.example.scheduling.api.RecurringIssueJobImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.atlassian.example.scheduling.api.RecurringIssueJobImpl.<init>()
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:883)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:839)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:440)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:69)
	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:355)
	at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320)
	at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:132)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.atlassian.example.scheduling.api.RecurringIssueJobImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.atlassian.example.scheduling.api.RecurringIssueJobImpl.<init>()
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:58)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:877)
	... 20 more
Caused by: java.lang.NoSuchMethodException: com.atlassian.example.scheduling.api.RecurringIssueJobImpl.<init>()
	at java.lang.Class.getConstructor0(Class.java:3082)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:54)
	... 21 more
2016-06-03 18:13:33,274 UpmAsynchronousTaskManager:thread-3 INFO admin 1084x148x1 1ekbet7 0:0:0:0:0:0:0:1 /rest/plugins/1.0/ [atlassian.plugin.manager.PluginEnabler] Plugin 'com.atlassian.example.scheduling' is now DISABLED

 

Please help.

Regards

Prakhar

overnight dev September 21, 2016

noting ever works on atlassian! Get used to that...

TAGS
AUG Leaders

Atlassian Community Events