# JAXB - nor any of its super class is known to this context



## nrg (26. Sep 2011)

Hallo Zusammen,

experimentiere gerade mit JAXB und stolpere über folgende Exception:

```
Exception in thread "main" javax.xml.bind.MarshalException
 - with linked exception:
[javax.xml.bind.JAXBException: class test.lib.Lion nor any of its super class is known to this context.]
	at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(Unknown Source)
	at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(Unknown Source)
	at test.lib.TestJaxb.main(TestJaxb.java:31)
Caused by: javax.xml.bind.JAXBException: class test.lib.Lion nor any of its super class is known to this context.
	at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.property.ArrayReferenceNodeProperty.serializeListBody(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty.serializeBody(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsSoleContent(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(Unknown Source)
	... 4 more
Caused by: javax.xml.bind.JAXBException: class test.lib.Lion nor any of its super class is known to this context.
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getBeanInfo(Unknown Source)
	... 10 more
```


Code:

```
@XmlRootElement
class Zoo {
	@XmlAnyElement
	public List<Animal> animals = new ArrayList<Animal>();
}

@XmlSeeAlso( {Dog.class, Lion.class} )
interface Animal {
	void makeSomeNoise();
}

@XmlRootElement
class Dog implements Animal {
	@Override
	public void makeSomeNoise() {
		System.out.println("bark");
	}
}

@XmlRootElement
class Lion implements Animal {
	@Override
	public void makeSomeNoise() {
		System.out.println("growl");
	}
}
```

Testmain:

```
Zoo zoo = new Zoo();
		zoo.animals.add(new Lion());
		zoo.animals.add(new Dog());
		JAXBContext jc = JAXBContext.newInstance(Zoo.class);
		Marshaller m = jc.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.marshal(zoo, System.out);
```

warum? Bei google finde ich nur, dass die XmlSeeAlso-Annotation verwendet werden soll. Aber das tue ich ja bereits. Vielleicht nicht richtig??

Grüße
nrg


----------



## musiKk (26. Sep 2011)

Zwei Sachen:

Warum hast Du [c]@XmlAnyElement[/c] an [c]animals[/c]? Das scheint Probleme zu bereiten. Ohne das (bzw. stattdessen mit [c]@XmlElement[/c]) ist es auch nicht nötig, die einzelnen Tiere mit [c]@XmlRootElement[/c] zu annotieren.

Was auf jeden Fall funktioniert, ist aus dem Interface eine abstrakte Klasse zu machen. Über die Gründe kann ich nur mutmaßen. Nach diesem Post liegt es wohl daran, dass XML Schema keine Mehrfachvererbung erlaubt und das in Java über Interfaces möglich ist (eine Klasse, die zwei Interfaces implementiert).

Ungefähr so:


```
@XmlRootElement
static class Zoo {
	private final List<Animal> animals = new ArrayList<Animal>();
	@XmlElement
	public List<Animal> getAnimals() {
		return animals;
	}
}

@XmlSeeAlso({Lion.class, Dog.class})
static class Animal {}
static class Lion extends Animal {}
static class Dog extends Animal {}
```


----------



## nrg (26. Sep 2011)

ich möchte die ArrayList dynamisch annotieren. D.h. je nach eigentlichem Objekt wird entweder das eine oder das andere Element gezogen (wenn ich jetzt z.b. statt Lion Tiger und statt Dog Hund haben möchte, muss ich das für mein Verständnis ja an der Klasse Lion bzw. Dog direkt machen). Wie würde ich bei deinem Code dann sowas machen?

Das Beispiel habe ich von hier:
Unofficial JAXB Guide - Mapping interfaces &mdash; Java.net


----------



## musiKk (26. Sep 2011)

Ok, ich wollte nicht sagen, dass es zwangsläufig falsch ist. Ich habe damit noch nichts gemacht und deshalb fehlt mir wahrscheinlich auch das Verständnis dafür. Das Pattern, welches in dem Guide verwendet wird, war mir nicht bekannt und mir ist auch nicht ganz klar, warum man das so machen sollte.

Beim ursprünglichen Code gibt es jedenfalls zwei Möglichkeiten:
1. die [c]@XmlSeeAlso[/c] von [c]Animal[/c] zur Klasse [c]Zoo[/c] ziehen
2. die Klassen [c]Lion[/c] und [c]Dog[/c] bei der Erstellung des [c]JAXBContext[/c] mit aufzählen (wie es auch im Guide steht)


----------

