问题
Just so it's clear, I've implemented and verified a solution for the error we were getting, but I'd just like to understand the innards of what's going on here. I've looked at similar instances of this same problem, and the answers usually don't go much past just providing the solution.
I work with an application that uses a jar file with JAXB-annoated classes generated from XJC. The jar file has ObjectFactory classes in each relevant package.
The application is deployed in a standard EAR format and deployed to WebLogic. The web applications have web content, but all the jars used by the web modules and the "ejb" modules (which doesn't actually have any ejbs) are in a shared lib directory in the EAR.
the JAXB classes are used by an integration layer to call a set of web services. The JSP pages reference classes which eventually call this integration layer, although there are also background tasks running which also reference the integration layer.
Most of the time, all of this works fine. However, in some circumstances, calls that initiate from the front-end fail with errors like this:
javax.xml.bind.JAXBException: "..." doesnt contain ObjectFactory.class or jaxb.index
After a bit of searching, I managed to find a random response to a blog post at Annotated JAXB Classes that led me to the solution. In our integration layer, we create a JAXBContext for the desired package. The key was overriding the default classloader in the "JAXBContext.newInstance()" call to use the classloader of the utility class in the integration layer.
WebLogic, perhaps like other application servers, creates a classloader hierarchy such that a web module is loaded by one classloader, and the ejb modules are loaded by a different classloader. Classes loaded in the web module classloader can call classes in the ejb classloader, but not the other way around (not that that matters here).
I'm assuming the error would happen when the utility class in the integration layer is called indirectly by a class first loaded by the web module classloader, as opposed to the ejb module classloader. The utility class in the integration layer is likely initially loaded by the ejb module classloader (although I wonder if that's an accident). By changing the classloader used in "JAXBContext.newInstance()" to the ejb module classloader, it allows the ObjectFactory to be found.
That's what I understand of this. I'd still like to understand this better. For instance, it's not crystal clear to me why exactly the ObjectFactory class is not visible to the web module classloader.
来源:https://stackoverflow.com/questions/9333091/could-use-more-clarification-of-classloader-issues-with-doesnt-contain-objectfa