Why do I get ClassCastExceptions on Hot Deployments?
Scenario: You have A.ear and B.ear, and B.ear relies upon an EJB that is packaged in A.ear. You update some code inside A.ear and redeploy it, and when you go to test the updated code using a method contained in B.ear, you get a ClassCastException.
First off, this is not a bug with the JBoss classloader, this is normal expected behavior. What is happenning is when A.ear is redeployed any references that B.ear may have to classes contained inside A.ear are no longer valid. (For a more in depth explanation, please consult chapter 2 of the JBoss admin book).
Solution: In order to address this issue, you need to adjust your packaging structure. The following works for both scoped and unscoped ears.
Extract all common interfaces and any other classes (ie: your ejb returns a custom value object) that may be referenced by B.ear into their own jar file. The example is given in the context of two scoped ears, but the concept is the same for unscoped ears as well.
A.ear exposes its interface via a class called Foo.
B.ear needs to use interface Foo to access A.ear
Remove class Foo from both A.ear and B.ear (if B.ear has been scoped) and deploy it in a standalone jar. the "whiteboard" picture would look something like this:
Foo.jar A.ear (scoped) B.ear (scoped)
when A.ear asks for interface Foo, it sees that it is not available via it's classloader and then asks for it from the top level class loader. The same thing occurs with B.ear - it can't find the class, and asks the top level loader, leaving both ears to get the same class loader definition. this also now allows you to hot deploy A.ear and/or B.ear without having to restart jboss.
A slight concern to this approach is that if any of the classes change inside the standalone jar file and you redeploy it, you will either have to restart the server or "touch" all the other deployment archives that rely upon that jar. The reason for this is that the ear's class loader will have a stale reference to classes in the jar.