We're using quartz (the java API) for job scheduling. This works well. Now I'm trying to generalize some things with it. The quartz api requires a job class as parameter which extends the Job interface. This makes passing in arguments via a constructor impossible.
We have a set of jobs which should all do the same, execute a check, if true then invoke an action, for example:
class SimpleJob extends Job {
def execute(context: JobExecutionContext) {
val check = classOf[SimpleCheck].asInstanceOf[Class[Check]].newInstance()
val result = check.execute(context.getJobDetail.getJobDataMap)
if (result.shouldInvokeAction) {
Action(result).execute
}
}
A quartz job is then instantiated by invoking:
newJob(classOf[SimpleJob]).with...
This works.
The goals is to re-use this logic for different types of checks Question: Can I use the scala type system in such a way that I can have one typed JobClass which can be re-used to execute any subclass of Check?
I've come up with the following solution:
class GenericJobRule[J <: Check](implicit m: Manifest[J]) extends Job {
def execute(context: JobExecutionContext) {
val check = m.erasure.newInstance().asInstanceOf[J]
val result = check.execute(context.getJobDetail.getJobDataMap)
if (result.shouldInvokeAction) {
Action(result).execute
}
}
}
A job can now be instantiated like this:
newJob(classOf[GenericJobRule[PerformanceCheck]])
This works, however I think the instantiation and casting kind-of bypasses the whole idea of type-checking. Is there any better way to do this? Maybe we should rethink our design as well...
Thanks, Albert