
|
If you were logged in you would be able to see more operations.
|
|
|
|
|
| Component/s: |
None
|
| Affects Version/s: |
1.4.3
|
| Fix Version/s: |
1.4.4
|
|
|
File RAMJobStore.java, class TriggerComparator, method compare():
public int compare(Object obj1, Object obj2) {
TriggerWrapper trig1 = (TriggerWrapper) obj1;
TriggerWrapper trig2 = (TriggerWrapper) obj2;
int comp = trig1.trigger.compareTo(trig2.trigger);
if (comp == 0)
return trig1.trigger.hashCode() - trig2.trigger.hashCode();
return comp;
}
The problem is with this line: return trig1.trigger.hashCode() - trig2.trigger.hashCode();
Hash code may generate exteme numbers, basically you could run in a situation like:
Integer.MIN_VALUE - Integer.MAX_VALUE
per comparator contract this should be a negative number, however due to overflow it might not be.
This problem completely breaks Quartz functionality when it occurs.
The easy fix is to replace the line with: return trig1.trigger.getFullName().compareTo(trig2.trigger.getFullName());
Illustrative example of the problem:
TreeSet set = new TreeSet(new TriggerComparator());
for (int n = 1; n < 7; n++)
{
CronTrigger cr = new CronTrigger("Trigger1", n + "MemGroup");
cr.setCronExpression("00 00 16 * * ?");
TriggerWrapper tw = new TriggerWrapper(cr);
set.add(tw);
}
for (int n = 0; n < 7; n++)
{
CronTrigger cr = new CronTrigger("Trigger1", n + "MemGroup");
cr.setCronExpression("00 00 16 * * ?");
TriggerWrapper tw = new TriggerWrapper(cr);
set.remove(tw);
}
After this code runs -- TreeSet is not empty due to comparator problems.
Another example: see attached configuration files. With them only two tasks are ever run.
|
|
Description
|
File RAMJobStore.java, class TriggerComparator, method compare():
public int compare(Object obj1, Object obj2) {
TriggerWrapper trig1 = (TriggerWrapper) obj1;
TriggerWrapper trig2 = (TriggerWrapper) obj2;
int comp = trig1.trigger.compareTo(trig2.trigger);
if (comp == 0)
return trig1.trigger.hashCode() - trig2.trigger.hashCode();
return comp;
}
The problem is with this line: return trig1.trigger.hashCode() - trig2.trigger.hashCode();
Hash code may generate exteme numbers, basically you could run in a situation like:
Integer.MIN_VALUE - Integer.MAX_VALUE
per comparator contract this should be a negative number, however due to overflow it might not be.
This problem completely breaks Quartz functionality when it occurs.
The easy fix is to replace the line with: return trig1.trigger.getFullName().compareTo(trig2.trigger.getFullName());
Illustrative example of the problem:
TreeSet set = new TreeSet(new TriggerComparator());
for (int n = 1; n < 7; n++)
{
CronTrigger cr = new CronTrigger("Trigger1", n + "MemGroup");
cr.setCronExpression("00 00 16 * * ?");
TriggerWrapper tw = new TriggerWrapper(cr);
set.add(tw);
}
for (int n = 0; n < 7; n++)
{
CronTrigger cr = new CronTrigger("Trigger1", n + "MemGroup");
cr.setCronExpression("00 00 16 * * ?");
TriggerWrapper tw = new TriggerWrapper(cr);
set.remove(tw);
}
After this code runs -- TreeSet is not empty due to comparator problems.
Another example: see attached configuration files. With them only two tasks are ever run. |
Show » |
|
Thanks for the good detail on this problem.