(I'm reposting issue
QUARTZ-106 here, since I cannot see how to re-open an issue in opensymphony JIRA).
As described in
QUARTZ-106, the trigger returned by timeTriggers.first() can't be removed, since it's nextFireTime is set to null. If I'm right, RAMJobStore.triggerFired supposes the acquired trigger to be removed from the timeTriggers tree set. This might not hold true, if the trigger was replaced between acquiring and triggering, since the new trigger is added to timeTriggers.
To be sure that the fired trigger is not contained in timeTriggers, the attached patch removes it's TriggerWrapper before calculating it's next fire time.