By using @XmlSeeAlso on a class, sub types of the bound class can be listed thereby allowing them to be bound also and therefore reachable by JAX-WS when marshalling and unmarshalling.
It can also be used to overcome the problem of using generics in a JAXB annotated class as the following simple example will describe. Given the below LogFile class, it will only be marshalled/unmarshalled if the T at runtime is bound.
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class LogFile<T> {
@XmlElement(name="logFileLine")
private List<T> logFileLines;
public LogFile() {
logFileLines = new ArrayList<T>();
}
public LogFile(List<T> logFileLines) {
this.logFileLines = logFileLines;
}
public List<T> getLogFileLines() {
return logFileLines;
}
public void setLogFileLines(List<T> logFileLines) {
this.logFileLines = logFileLines;
}
public void addLogFileLine(T logFileLine) {
this.logFileLines.add(logFileLine);
}
}
If LogFile contains a collection of eg Strings then this will work fine but if T is a class not bound, eg com.city81.domain.LogLine then an error similar to below will be thrown:
javax.xml.bind.MarshalException - with linked exception: [javax.xml.bind.JAXBException: class com.city81.domain.LogLine nor any of its super class is known to this context.]
To resolve this, the class LogLine needs to be included the @XmlSeeAlso annotation.
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso(LogLine.class)
public class LogFile<T> {
....
}
This does of course mean you need to know what potential classes can be T before runtime but at least it means you can use Generics on JAXB annotated classes.