JAXB "nor any of its super class is known to this context" avoid @XmlSeeAlso
So here is what the essence of the custom resolver looks like:
@Provider
@Produces ({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public class JaxbContextResolver implements ContextResolver<JAXBContext> {
@Override
public JAXBContext getContext(Class<?> type) {
// load appropriate context data
Class[] bindTypes = ...
// create
try {
return JAXBContext.newInstance(bindTypes);
} catch (JAXBException e) {
// todo: this can be handled better but works for the example
throw new RuntimeException(e);
}
}
}
Now, the processing for "load appropriate context data" is pretty simple. By basically mimicking @XmlSeeAlso
using runtime data:
- Create a custom something (annotation, processing method, whatever) that marks a particular field/method as "contextual"
- Load the field/method data pulling the data types out
- Make sure you do not load duplicates and check for infinite recursion possibilities
Now, I used some caching to help make things more efficient for myself. I also created a slightly more complex setup for my root object where it actually kept track of the class data on its own and made it pretty speedy. I also created an alternative that marked classes as "contextual" that I used package inspection to load via annotations and just automatically add to the context but I have not checked efficiency on that yet. I have some ideas for a 3rd implementation, but I want to get more benchmarking completed.
el n00b
Falling in love with Go and coming from a Java and C/C++ background. I generally love to code and create but absolutely abhor technology in the home (ironic, right?). Family, motorcycles and caffeine are the only other thing really important to me. Up for some D20 if you're down. Just trying to make a living, you know?
Updated on June 04, 2022Comments
-
el n00b almost 2 years
Explanation & Workaround
Currently I am using JAX-RS and letting JAXB bindings automatically handle converting the data to XML and JSON for me in a JEE6 project. Everything is working absolutely fantastically until I try to create a generic response object to wrap all of my information in.
When I attempt to use my generic response class
com.eln00b.Wrapper
(which contains aprivate Object result
attribute within it) I get:javax.xml.bind.MarshalException - with linked exception: [com.sun.istack.SAXException2: class com.eln00b.CustomObject nor any of its super class is known to this context. javax.xml.bind.JAXBException: class com.eln00b.CustomObject nor any of its super class is known to this context.]
So I add to
com.eln00b.Wrapper
:@XmlSeeAlso ({com.eln00b.CustomObject}) public class Wrapper { }
Everything works fine.
The Problem
I want this to be extremely generic. I do not want t constantly add classes to the
@XmlSeeAlso
annotation on thecom.eln00b.Wrapper
class. How do I have the system automatically locate all of my classes for the JAXB context?Even if it's a hack where I use something like Reflections to load the data, that's fine. I'm just not sure how to get the context to load all of that data without the
@XmlSeeAlso
annotation. With the large amount of annotations I will be creating it will just simply not work.How It Worked Manually
It worked manually just by adding the data like so doing manual conversions. However, I do not want to use manual XML/JSON creation unless I absolutely need to (I don't want to deal with content negotiation or anything like that).
Sample:
JAXBContext.newInstance(new Class[] {Wrapper.class, CustomObject.class});