History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: QUARTZ-399
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Critical Critical
Assignee: James House
Reporter: daniel
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Quartz Scheduler

StackOverflowError caused by the Triggers dataMap containing data.

Created: 03/Apr/06 10:15 PM   Updated: 24/Dec/07 01:30 AM
Component/s: Core, Triggers
Affects Version/s: 1.5.1, 1.5.2
Fix Version/s: 1.6


 Description  « Hide
Scheduling a trigger that contains data in its data map will consistently result in a StackOverflowError. Here is a snippet of the stacktrace:

Exception in thread "DefaultQuartzScheduler_QuartzSchedulerThread" java.lang.StackOverflowError
at java.util.HashMap$KeyIterator.<init>(HashMap.java:821)
at java.util.HashMap$KeyIterator.<init>(HashMap.java:821)
at java.util.HashMap.newKeyIterator(HashMap.java:835)
at java.util.HashMap$KeySet.iterator(HashMap.java:867)
at java.util.Collections$UnmodifiableCollection$1.<init>(Collections.java:1007)
at java.util.Collections$UnmodifiableCollection.iterator(Collections.java:1006)
at java.util.Collections$UnmodifiableCollection$1.<init>(Collections.java:1007)
at java.util.Collections$UnmodifiableCollection.iterator(Collections.java:1006)
at java.util.Collections$UnmodifiableCollection$1.<init>(Collections.java:1007)
at java.util.Collections$UnmodifiableCollection.iterator(Collections.java:1006)

and on and on and on..

I am seeing this problem consistently after 4914 trigger fires.

This problem can be reproduced consistently using the following code:

SchedulerFactory schedFact = new StdSchedulerFactory();
        Scheduler quartzScheduler = schedFact.getScheduler();
        quartzScheduler.start();

// register the callback job.
        JobDetail detail = new JobDetail("b", "b", NoopJob.class);

Trigger trigger = new SimpleTrigger("name", "group", "b", "b", new Date(), null, SimpleTrigger.REPEAT_INDEFINITELY, 50);
        trigger.getJobDataMap().put("a", "a");
        quartzScheduler.scheduleJob(detail, trigger);

where NoopJob.class is a base implementation that does nothing.

The problem is that during each firing of the trigger, the JobExecutionContext calls setMutable(false) on the triggers JobDataMap. This wraps what turns out to be the same map in an UnmodifiableCollection over and over again. It appears that the setMutable method on the JobDataMap should be a little smarter, and only 'wrap' if it is mutable.

Cheers,
-Daniel

 All   Comments   Change History      Sort Order:
daniel - [03/Apr/06 10:51 PM ]
modifying the DirtyFlagMap with the following fixes the above problem:

public void setMutable(boolean mutable) {
if (this.locked == !mutable)
{
// this map is already in the correct state, there is nothing
// more that needs to be done here.
return;
}
        this.locked = !mutable;
        if(locked)
            map = Collections.unmodifiableMap(map);
        else
            map = new HashMap(map);
    }

Jasper Rosenberg - [13/Apr/06 08:10 AM ]
How interesting. This must only be happening with the RAMJobStore, since with a database store the Trigger JobDataMap is loaded fresh from the database every time.

daniel - [13/Apr/06 08:17 AM ]
Yes, we are using the RAMJobStore.

-Daniel

Jasper Rosenberg - [13/Apr/06 08:29 AM ]
Applied the provided patch. Thanks!