JBoss EAP 6.3 / Castor 1.0 - MappingException: Could not find the class

790 Views Asked by At

When moving a formerly WebSphere Java EE application to JBoss EAP 6.3, a runtime exception was thrown when invoking the marshall(Object) method of Castor 1.0's org.exolab.castor.xml.Marshaller object:

org.exolab.castor.mapping.MappingException: Nested error: org.exolab.castor.mapping.MappingException: Could not find the class {fully qualified Java class name}

(The Marshaller is trying to serialize an object to XML.)

I see no obvious class path issues. There is seemingly no reason why this application, which compiles fine using JBoss Developer Studio, would fail at runtime.

The problem occurs with the first Java class described in the mapping.xml file -- not with the class that I'm trying to serialize, unless by coincidence it happens to be the first class in the mapping.xml file.

What might be the problem, and what is a solution?

1

There are 1 best solutions below

0
Dynotherm Connector On

After scouring Google, I found the solution in this discussion thread from 2002:

https://developer.jboss.org/thread/21611

Per Fred Loney in that discussion thread:

The jboss lib castor.jar resides in a classloader that is a parent of your webapp classloader. Castor relies on introspection and attempts to resolve the mapped classes using its classloader context, not the webapp or thread context. Your mapped application classes are therefore not found.... Castor should use the current thread context classloader by default but it doesn't. This is a failing common to other open source middleware projects that rely on introspection, e.g. cactus.

Following the advice recommended in that thread, I changed my code to, rather than use the default constructor of org.exolab.castor.mapping.Mapping, instead use the constructor that accepts a ClassLoader argument, and I used the ClassLoader of the class of the object that I'm trying to serialize.

Object objectToSerialize = ...

// I previously used Mapping's default constructor
Mapping mapping = new Mapping(objectToSerialize.getClass().getClassLoader());
// Set other properties of mapping, such as entityResolver, mapping file, etc.

StringWriter stringWriter = new StringWriter();
Marshaller marshaller = new Marshaller(stringWriter);
marshaller.setMapping(mapping);
marshaller.marshal(objectToSerialize);

// stringWriter now contains the serialized data from objectToSerialize

I hope Fred Loney's tip helps someone. It took me a while to find the problem and solution online!