Autowiring is supported for Job plugin modules in Confluence 4.0.1 and later.
As described in CONF-20162, there is no autowiring for Job Modules prior to Confluence 4.0.1. In plugins 1 dependencies could be easily fetched from the ContainerManager. In plugins 2 this is not always the case. There is a workaround however. Instead of using a job module, use a regular component module that extends JobDetail.
In your atlassian-plugin.xml declare the trigger as usual and make it point to a JobDetail that is a component module, rather than a job module.
1 2<atlassian-plugin> <!-- ... --> <component key="sampleJobDetail" name="A sample Job Detail" class="com.example.SampleJobDetail"> <description>This SampleJobDetail is a component module that will be autowired by Srping.</description> <interface>org.quartz.JobDetail</interface> </component> <trigger key="sampleJobTrigger" name="Sample Job Trigger"> <job key="sampleJobDetail"/> <schedule cron-expression="0/2 * * * * ?"/> </trigger> <!-- ... --> </atlassian-plugin>
The Detail object itself is, or can be, fairly trivial. It needs to be autowired with the dependencies you need, and it needs to call the super constructor with the class of the actual job to run.
1 2/** * This class allows Spring dependencies to be injected into {@link SampleJob}. * A bug in Confluence's auto-wiring prevents Job components from being auto-wired. */ public class SampleJobDetail extends JobDetail { private final SampleDependency sampleDependency; /** * Constructs a new SampleJobDetail. Calling the parent constructor is what registers the {@link SampleJob} * as a job type to be run. * * @param sampleDependency the dependency required to perform the job. Will be autowired. */ public SampleJobDetail(SampleDependency sampleDependency) { super(); setName(SampleJobDetail.class.getSimpleName()); setJobClass(SampleJob.class); this.sampleDependency = sampleDependency; } public SampleDependency getSampleDependency() { return sampleDependency; } }
Finally the Job itself can now retrieve anything it wants from the Detail which is retrieved from the jobExecutionContext. It does have to cast the the appropriate Detail class first.
1 2/** * Job for doing something on a regular basis. */ public class SampleJob extends AbstractJob { public void doExecute(JobExecutionContext jobExecutionContext) throws JobExecutionException { SampleJobDetail jobDetail = (SampleJobDetail) jobExecutionContext.getJobDetail(); jobDetail.getSampleDependency().doTheThingYouNeedThisComponentFor(); } }
You can see an example of this in the WebDAV plugin. Look at ConfluenceDavSessionInvalidatorJob and ConfluenceDavSessionInvalidatorJobDetail.
Rate this page: