I recently migrated my web applications from JBoss 4.2 to JBoss 5.1 and I had to go through all the classloading nightmares once again. Because of the number of frameworks in our app, I ended up having to put the quartz jars at the EAR level.
So I started having problems when the job class could not be found because quartz was using a different classloader than the one used by the job itself. I fixed this issue by creating my own ClassLoadHelper, so now the Job class was in the same class loader as the class holding my scheduler (the scheduler is in the EAR classloader).
The problem is more with an object being stored in the jobDataMap. This object has a totally different classloader from either the Job or the Scheduler, and I didn't know how to change that. This object is being deserialized by Quartz (it's using JobStoreTX with the JDBCJobStore. If I use the RAMJObStore it's not an issue because the jobData object stays the same.
So here's the classloader for the different objects to see if anyone has any ideas how I can make the jobdata to use the same classloader as the Job. It would be great if it would use the ClassLoadHelper to create those objects as well.
Code:
Object creating scheduler:
BaseClassLoader@45d017d4{.../deploy/NuminsWebServicesEAR.ear/NuminsKaeWEB.war/}
Quartz Scheduler:
BaseClassLoader@2223a923{.../deploy/NuminsWebServicesEAR.ear/}
object before going into jobDataMap: (Same as the object that creates the scheduler. Since it creates both)
BaseClassLoader@45d017d4{.../deploy/NuminsWebServicesEAR.ear/NuminsKaeWEB.war/}
ClassLoadHelper: (It's being put in the application's WAR file)
BaseClassLoader@45d017d4{.../deploy/NuminsWebServicesEAR.ear/NuminsKaeWEB.war/}
Job read using ClassLoadHelper: (As expected since it uses the classLoadHelper)
BaseClassLoader@45d017d4{.../deploy/NuminsWebServicesEAR.ear/NuminsKaeWEB.war/}
jobExecutionContext: (As expected since it's using the same as the Scheduler)
BaseClassLoader@2223a923{.../deploy/NuminsWebServicesEAR.ear/}
jobDataMap: (As expected since it's using the same as the Scheduler)
BaseClassLoader@2223a923{.../deploy/NuminsWebServicesEAR.ear/}
Object from JobDataMap:
BaseClassLoader@315351de{vfsfile:/C:/dev/jboss-5.1.0.GA/server/numins/deploy/NuminsEAR.ear/}
And just to make it clear, here's my classloading structure:
Code:
Root
+--- NuminsEar.ear
+--- NuminsWebServicesEAR.ear
+---NuminsKaeWEB.war
Look how the last guy has a totally different classloader from the rest. It's even in another EAR classloader. How could this be?
For now the workaround is for the Job to instantiate a new Object making a copy of the original object taken out of the jobDataMap using reflection (since I can't cast the object either since it's in a different classloader) But this is not a clean solution at all.
Any hints, ideas, or suggestions will be greatly appreciated.