|
|
|
Possible interest: https://issues.apache.org/jira/browse/DERBY-1368
A bit more testing and now it makes sense.
If the JobData is null, the serializeObject + setBytes code is such that an empty ByteArrayOutputStream.toByteArray() gets inserted and not null. This shouldn't be an issue because even if null gets into setBytes then it will a new byte[0]. However when getObjectFromBlob in CloudscapeDelegate reads this it only checks for inputBytes being null and not for it being an empty byte array. So for the CloudscapeDelegate the custom code needs to be changed to also check for an empty array. The PostgreSQLDelegate already contains this fix. For the HSQLDelegate I would hazard that the binaryInput.available() == 0 check found in the StdJDBCDelegate would be needed here. The PointBaseDelegate and MSSQLDelegate both look like they could also do with the binaryInput.available check. Additionally, the StdJDBCDelegate class seems to work fine against the latest version of Derby so the CloudscapeDelegate class can have its implementation of the method removed and be deprecated/removed if you ask me :)
This bug is marked as fixed in 1.6.1. So I checked out the current trunk and compared CloudscapeDelegate and StdJDBCDelegate with their versions from the 1.6.0-tag. No difference except a new linebreak in StdJDBCDelegate.
Is this bug really fixed? It's marked as 'fix for 1.6.1'. It's still open, so not fixed until the issue is resolved or closed fixed. I believe I've got the same issue using the MSSQLDelegate... here's part of the stack trace...
java.io.EOFException at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source) at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source) at java.io.ObjectInputStream.readStreamHeader(Unknown Source) at java.io.ObjectInputStream.<init>(Unknown Source) at org.quartz.impl.jdbcjobstore.MSSQLDelegate.getObjectFromBlob(MSSQLDelegate.java:88) at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectTrigger(StdJDBCDelegate.java:2132) at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveTrigger(JobStoreSupport.java:1490) at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:891) at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverJobs(JobStoreSupport.java:780) at org.quartz.impl.jdbcjobstore.JobStoreSupport$2.execute(JobStoreSupport.java:752) at org.quartz.impl.jdbcjobstore.JobStoreSupport$40.execute(JobStoreSupport.java:3628) at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3662) at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3624) at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverJobs(JobStoreSupport.java:748) at org.quartz.impl.jdbcjobstore.JobStoreSupport.schedulerStarted(JobStoreSupport.java:573) at org.quartz.core.QuartzScheduler.start(QuartzScheduler.java:449) ... Paul - yep, that one is
I've spent a fair amount of time this weekend testing the fixes to the delegates (CloudscapeDelegate, MSSQLDelegate, PointbaseDelegate, StdJDBCDelegate). All seems to work fine now, so far as I can tell, though there's sometimes variations once people try things with different releases of those DBs. Hopefully the empty stream, byte array checks have done the trick across the board. Closing Also, marked the CloudscapeDelegate deprecated. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I also seem to be able to repro it even with the non-empty JobDataMap.
Repro attached. The runsql bit is a hacky bit of Java I have to shove SQL into databases, I presume you have your own way to push the data into Derby.