When you invoke
JAXBContext.newInstance("aaa.bbb.ccc")
,
it tries to load a property file called jaxb.properties
from
each package, using the same classloader used to load the JAXBContext
class itself. This classloader may be different from the classloader which
was used to load your application (see the picture). In this case, you'll
see the above error. This problem is often seen with application servers,
J2EE containers, Ant, JUnit, and other applications that use sophisticated
class loading mechanisms.
With some applications, things get even more complicated when the JAXB-generated
code can be loaded by either classloader. In this case, JAXBContext.newInstance("aaa.bbb.ccc")
will work but the JVM ends up loading two copies of the generated classes
for each class loader. As a result, unmarshalling works but an attempt to
cast the returned object into the expected type will fail, even though its
getClass().getName()
returns the expected name.
The solution for both situations is to pass your curent class loader like this:
JAXBContext.newInstance( "aaa.bbb.ccc", this.getClass().getClassLoader() );
In general, if you are writing code that uses JAXB, it is always better to explicitly pass in a class loader, so that your code will work no matter where it is deployed.