Friday, October 20, 2006

Sakai Classloaders

I am beginning todo a little bit of work with Sakai and was trying to deal with uploaded files from a web form when inside a tool. Now Sakai uses commons-filupload to handle uploaded files and parses them automatically and adds the results back to the request as attributes. I was then trying to access this attribute in my tool with a line: FileItem fileItem = (FileItem)request.getAttribute("file"); This supprisingly was giving me a ClassCastException complaining that it was unable to cast a DefaultFileItem to a FileItem despite the fact that DefaultFileItem implements the FileItem interface. After a little head scratching Alexis suggested classloader issues we found the problem. Sakai has the parsing of the uploaded files in one classloader(the portal, getting commons-fileupload from shared) which then hands control off to the tool in another classloader (the tool, done by dispatching the request across servlet contexts). The problem was that both classloaders had a copy of the commons-fileupload jar and so when the FileItem class what loaded it wasn't in the same classloader as the DefaultFileItem and so couldn't be cast. Removing the copy of commons-fileupload from the tool fixed the problem. This issue would have been a little easier to debug if when the ClassCastException occured they provided the ID of the classloader that the two classes had come from in the exception message.

No comments: