QuartzDeadlineManager throws error resulted in (Cannot invoke \"org.quartz.JobDetail.getJobDataMap()\" because \"jobDetail\" is null)

I use QuartzDeadlineManager to schedule some tasks. Recently, I received the error message

resulted in org.axonframework.commandhandling.CommandExecutionException(Cannot invoke "org.quartz.JobDetail.getJobDataMap()" because "jobDetail" is null)

I wonder what’s happening here. Basically, I have a command handler which will apply event and make some schedule using DeadlineManager. It may looks like this

@CommandHandler
fun handle(command: MakePaymentCommand, deadlineManager: DeadlineManager) {
    // apply some event
    deadlineManager.cancellAllWithinScope("payment-expires")
    deadlineManager.schedule(getNextExpireTime(), "payment-expires")
}

I wonder if I need to check existing of deadline schedule before cancel it like this.

if (hasSchedule()) {
  deadlineManager.cancellAllWithinScope("payment-expires")
}

Hoi Werapon,

It sounds to me like a deserialization issue in Quartz. The error comes from here, but that should be present. It might be helpful to check how it’s stored in the database. Did you change anything which might affect Quartz serialization?

It’s always safe to call cancel all, so that should not be a problem.

Thanks for your response,

For serialization, I recently changed something in XStream configuration according to this issue.

so basically I added this

@Configuration
class XstreamAutoConfig {
  @Bean
  fun xstream(): XStream {
    val xstream = XStream()
    xstream.allowTypesByWildcard(arrayOf("our.company.limited.**"))
    xstream.ignoreUnknownElements()
    return xstream
  }
}

We store quartz data in mongodb here’s how I configured the deadline manager.

 @Bean
  fun deadlineManager(config: org.axonframework.config.Configuration,transactionManager: TransactionManager, scheduler: Scheduler): QuartzDeadlineManager {
    return QuartzDeadlineManager
      .builder()
      .scopeAwareProvider(ConfigurationScopeAwareProvider(config))
      .transactionManager(transactionManager)
      .scheduler(scheduler)
      .refireImmediatelyPolicy(RefirePolicy.NEVER)
      .build()
  }

That’s likely the issue. I’m not sure what would be the best way to fix it. There should be some xml for Quartz stored in mongo. I use based on this, you can make a unit test to serializer that data using the specific configuration of Quartz. Likely it has the missing fields, that would give the nullpointer exception.

To fix it you probably need to add at least org.axonframework.deadline.quartz.** as wildcard.

Do you think it is possible that this issue could related to the connection problem. we use mongodb as a data store for scheduler (Quartz). Recently there’s some network problem that caused the application unable to connect with mongodb. so when it tried to execute jobDetail.getJobDataMap it returns null instead. Because sometimes this command handler works just fine sometimes it doesn’t. I’m not sure how deadline manager was implemented or how it handles when it’s unable to connect with the database.

It might be, as Quartz hasn’t changed a lot, and Mongo transactions were only added relatively recent. I can imagine only a part of the job was written. I’m not sure how Quartz maps it to collections, but if it uses multiple collections, that’s certainly possible.

Not sure if this storeJobInMongo is the same that you use in your project. To be frank, the one time I tried to setup Quartz with Mongo I gave up, because there was a mismatch in Mongo Client versions.